changeset 430:7ab81ff32111 2.3

merged flys-artifacts/2.3
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:10 +0200
parents a6f56ed9238b (diff) b8377caf4515 (current diff)
children 29a15392e229
files
diffstat 159 files changed, 15779 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/.classpath	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<classpath>
+   <classpathentry kind="src" path="src/main/java"/>
+   <classpathentry kind="src" path="src/test/java"/>
+   <classpathentry kind="lib" path="/vol1/download/ingo/gwt-2.1.1/gwt-user.jar"/>
+   <classpathentry kind="lib" path="/vol1/download/ingo/gwt-2.1.1/gwt-dev.jar"/>
+   <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+   <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+   <classpathentry kind="output" path="src/main/webapp/WEB-INF/classes"/>
+
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/.project	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<projectDescription>
+   <name>FLYS</name>
+   <comment>FLYS project</comment>
+   <projects/>
+   <buildSpec>
+       <buildCommand>
+           <name>org.eclipse.jdt.core.javabuilder</name>
+           <arguments/>
+       </buildCommand>
+   </buildSpec>
+   <natures>
+       <nature>org.eclipse.jdt.core.javanature</nature>
+   </natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/ChangeLog	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,2132 @@
+2011-05-17  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged RELEASE 2.3
+
+2011-05-16  Hans Plum <hans@intevation.de>
+
+	* NEWS:
+	Added version number and release date for V 2.3
+
+2011-05-16  Hans Plum <hans@intevation.de>
+
+	* NEWS:
+	New. Describing new functionality and some backgrounds in
+	MoinMoin-Wiki Syntax (in german	only) from the user perspective. It
+	does not differentiate between client and server-specific code!
+
+2011-05-13  Ingo Weinzierl <ingo@intevation.de>
+
+	* Changes: Prepared Changes for the upcoming release 2.3 - see Changes
+	  file to get to know about the change of version number.
+
+2011-05-12	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+    * src/main/java/de/intevation/flys/client/server/meta/Converter.java:
+      New. Converts the incoming XML to a more informative way.
+
+    * src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java:
+      Use the new converter.
+
+2011-05-12  Raimund Renkert <rrenkert@intevation.de>
+
+	  ISSUE-61
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Changed datacage button style.
+
+2011-05-12  Raimund Renkert <rrenkert@intevation.de>
+
+	  ISSUE-46
+
+	* src/main/java/de/intevation/flys/client/client/ui/TableDataPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Removed the table header context menu.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LinkSelection.java:
+	  Removed log message.
+
+2011-05-12  Raimund Renkert <rrenkert@intevation.de>
+
+	  ISSUE-43
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Changed i18n strings.
+
+2011-05-12  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LinkSelection.java:
+	  New. Shows a list of rivers displayed as links.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Use the new Panel to show rivers as links.
+
+2011-05-12  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-15
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  After resizing the chart panel, the chart/image is replaced by a new
+	  chart with adjusted width and height (requested from server).
+
+2011-05-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Defined the chart size (600x500).
+
+	* src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java:
+	  Query the chart in the requested size defined in the GET-parameters of
+	  the request.
+
+2011-05-12  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-34
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java:
+	  The number of windows which are moved the right lower browser window
+	  corner is limited to 10 windows now. The 11th window is placed at the
+	  left upper corner again. Window 12-20 are moved with an offset into to
+	  the right lower corner again.
+
+2011-05-11	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DataCageNode.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DataCageTree.java:
+	  New. Server -> Client transport model. Ugly because it re-invents XML
+	  documents. XML is received by the RPC service from the artifact server,
+	  transformed into this transport representation and this is transformed
+	  in ui elements on the client side.
+
+	* src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java:
+	  Transform the incoming XML to transport representation. TODO:
+	  Do not simply copy the XML.
+
+	* src/main/java/de/intevation/flys/client/client/services/MetaDataServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/MetaDataService.java:
+	  Changed signature tio transport the tree.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DatacageWindow.java:
+	  Transform the transport tree into ui elements.
+
+2011-05-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ExportPanel.java:
+	  Changed the height of this panel to be visible in all browsers.
+
+2011-05-11	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java:
+	  Call the service. TODO: transport artifact server result to client.
+
+	* src/main/java/de/intevation/flys/client/client/services/MetaDataServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/MetaDataService.java:
+	  Extended interfaces to cope with i18n.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Error messages if the artifact meta data service is not reachable.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Forward collection view to chart output tab.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Forward artifact to fetch river name later.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DatacageWindow.java:
+	  New. UI code for the data cage panel. TODO: build tree from
+	  service data.
+
+	* src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Added simple break in a loop if river was found.
+
+2011-05-11  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-56
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java,
+	  src/main/java/de/intevation/flys/client/shared/model/OutputMode.java:
+	  Added a further method that returns all available facets.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ExportPanel.java: New.
+	  This panel is used to serve download links for each export mode / type
+	  of a collection.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Implements the CollectionChangeHandler interface now. If a Collection
+	  changes, the available output modes are analyzed. If there are export
+	  modes available, those modes are displayed in a so called 'ExportPanel'.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Registered the ParameterList as CollectionChange handler.
+
+	* src/main/webapp/FLYS.css: Added a stylesheet for the export panels
+	  title.
+
+	* src/main/webapp/images/save.gif: New. This image is displayed in the
+	  export panel.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java: New
+	  i18n strings for the export panel.
+
+2011-05-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ExportServiceImpl.java:
+	  New. This service is a "proxy servlet" that enables the GUI to add
+	  download buttons for exporting the computed data of the artifact server.
+
+	* src/main/java/de/intevation/flys/client/client/services/CSVExportService.java:
+	  Changed the URL part to query the CSV export ('export' -> 'csv').
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the new ExportService.
+
+2011-05-11  Raimund Renkert <rrenkert@intevation.de>
+
+	  ISSUE 34
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java:
+	  Move every new project window 20 px multiplicated with the window count
+	  down and right.
+
+2011-05-11  Raimund Renkert <rrenkert@intevation.de>
+
+	  ISSUE 44
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Moved the location/range and WQ input tables to the helper panel on the
+	  right. The tables have a dynamic size now.
+
+2011-05-11  Raimund Renkert <rrenkert@intevation.de>
+
+	  ISSUE 41 (part2)
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Set the computation result panel width and height to 100%. The panel
+	  resizes with its parent component now.
+
+2011-05-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/ExportMode.java:
+	  New. A derived OutputMode that is used to mark an OutputMode as an
+	  export.
+
+	* src/main/java/de/intevation/flys/client/shared/model/OutputMode.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java:
+	  Added methods to provide facets in output modes.
+
+	* src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java:
+	  Extract facets from DESCRIBE and distinguish between an ordinary
+	  OutputMode or an ExportMode.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Replaced the determination of an export mode for creating new
+	  OutputTabs. Now, we just create new OutputTabs for OutputModes that are
+	  no instance of ExportMode. Furthermore, the computation output panel
+	  is now displayed if there is an output mode which:
+	   - is an ExportMode
+	   - has a facet which name is "csv"
+
+2011-05-11  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-41 (part1)
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Moved the computation result panel right beside the parameterization.
+
+	  TODO: This panel has now hard coded width/height. The result of this is,
+	  that it does not change its size when the parent component is resized.
+	  So, the width and height should be set to 100%.
+
+2011-05-11  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-57
+
+	* src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Replaced wrong i18n function name.
+
+2011-05-10  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-48
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Added labels placeholder for the theme control panel and the toolbar.
+	  Both panels now have a black border.
+
+2011-05-10  Ingo Weinzierl <ingo@intevation.de>
+
+	  ISSUE-38
+
+	* src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Set the first value of a select box as default value.
+
+2011-05-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java: Added
+	  i18n error messages required if the data input failed in the adapted WQ
+	  panel.
+
+2011-05-10  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Changed the empty table message for the WQ input table.
+
+2011-05-10  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/TableDataPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Changed the empty table text from default to "Loading data".
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added i18n strings for empty table text.
+
+	* src/main/java/de/intevation/flys/client/server/CSVExportServiceImpl.java:
+	  Changed author.
+
+2011-05-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/MetaDataServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/MetaDataService.java:
+	  New. Stub for new meta data service.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered meta data service.
+
+2011-05-10  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Fixed the location input. A range selection sets the correct location values
+	  now.
+
+2011-05-10  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Remove the data table on step back.
+
+2011-05-10  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Use the name instead of the description to determine the output mode.
+
+	* src/main/java/de/intevation/flys/client/server/CSVExportServiceImpl.java:
+	  Removed obsolete code.
+
+	* src/main/java/de/intevation/flys/client/client/ui/TableDataPanel.java:
+	  Build up a dynamic table for different header count. The first line of CSV
+	  data is used to set the header title.
+
+2011-05-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/CSVExportServiceImpl.java:
+	  Bugfix: Use the ElementCreator from XMLUtils to add attribute to nodes
+	  in the xml document. Then, those nodes will have the ArtifactNamespace
+	  automatically. If we do something like
+	    node.setAttribute("art:attr", "value")
+	  Restlet will throw an exception, because it does not know the "art:"
+	  namespace.
+
+2011-05-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* pom.xml: Bugfix: replaced the goupId of the OpenCSV dependency with the
+	  correct id.
+
+2011-05-09  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/CSVExportServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/CSVExportServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/CSVExportService.java:
+	  New service. Requests CSV data and returns a list of lines in a string
+	  array.
+
+	* src/main/java/de/intevation/flys/client/client/ui/TableDataPanel.java:
+	  New. Displays the data requested by the new service.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Added the table to UI.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered new service.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added strings for the new table.
+
+	* pom.xml: Added dependency: au.com.bytecode.opencsv, version 2.0;
+
+2011-05-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQAdaptedInputPanel.java:
+	  Added radio buttons to choose between W/Q mode.
+
+2011-05-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Bugfix: the current locale string is used to fetch the chart image now
+	  which enables the client to present localized charts.
+
+2011-05-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Added a doubleclick listener to the rows of this list. A doubleclick
+	  will now open the selected project.
+
+2011-05-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DistanceInfoRecord.java,
+	  src/main/java/de/intevation/flys/client/client/Config.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Removed superfluous imports.
+
+2011-05-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties:
+	  Changed wording: 'distance' -> 'range'.
+
+2011-05-05  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Enable or disable table rows depending on the WQ selection.
+
+2011-05-05  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Implemented handler for the value selection.
+
+2011-05-05  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Added table for WQ inputs. TODO: Implement the selection and set the
+	  values.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  New i18n strings for the WQ input table.
+
+2011-05-05  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Moved functions getData() and getDataItem() from WQInputPanel to
+	  AbstractUIProvider to make it accessible in all UIProvider that inherit
+	  from AbstractUIProvider.
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQAdaptedInputPanel.java:
+	  Implemented the methods to create the old widget of thi panel.
+
+2011-05-05  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java: Added
+	  new i18n displayed in the WQAdaptedInputPanel.
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQAdaptedInputPanel.java:
+	  The list of input fields for each intersected gauge is created now. The
+	  correct w/q values will be returned after the submit button has been
+	  clicked.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java:
+	  The orientation of the field label might be adjusted using a new
+	  constructor parameter. Furthermore, there is a new method (which has no
+	  parameters) that returns the double values inserted in this panel.
+
+2011-05-04  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/WQInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/WQInfoServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/WQInfoService.java:
+	  New. This service fetches WQ information from the server.
+
+	* src/main/java/de/intevation/flys/client/shared/model/WQInfoRecord.java,
+	  src/main/java/de/intevation/flys/client/shared/model/WQInfoObjectImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/WQInfoObject.java:
+	  New. Data structures for the WQ information.
+
+	* src/main/webapp/WEB-INF/web.xml: Added new service.
+
+2011-05-04  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Do not update the locations table if no data is cached.
+
+2011-05-04  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQAdaptedInputPanel.java:
+	  New. This UIProvider is used to enter W/Q values associated with a set
+	  of gauges.
+
+	  NOTE: This is currently just a stub implementation used for further
+	  development.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Initialize the WQAdaptedInputPanel if the uiprovider flag is set to
+	  "wq_panel_adapted".
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java: New
+	  i18n strings for the "discharge longitudinal section.
+
+2011-05-04  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Fixed the input panel. It takes manual input now and the table data is
+	  filtered correctly.
+
+2011-05-04  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Renamed the non-computed discharge curves into 'Discharge Curves at
+	  Gauges' (german 'Abflusskurven an Pegeln') to distinuish the two output
+	  types for discharge curves.
+
+2011-05-04  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  New i18n strings for the computed discharge curve.
+
+2011-05-03  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  New i18n strings for new output modes.
+
+2011-05-03  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Added new UI provider for single location selection.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java:
+	  Check if the values are not null.
+
+	* src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  New. Takes a single location from the location input table.
+
+2011-05-02  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  The table data is cached in a new variable. The location table for
+	  distance input is rebuild on distance selection.
+
+2011-05-02  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Introduced two further parameters to determine the selection mode of
+	  this panel.
+
+2011-05-02  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Added location and distance tables. A selection fills the textfield with
+	  the selected values.
+
+	* src/main/java/de/intevation/flys/client/shared/model/DistanceInfoRecord.java:
+	  New.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added i18n strings for the new tables.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSImages.java: Added new
+	  images.
+
+	* src/main/java/de/intevation/flys/client/client/images/marker_green.png,
+	  src/main/java/de/intevation/flys/client/client/images/marker_red.png: New.
+
+2011-05-02  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Bugfix: The WQ panel now returns the correct step width value if the
+	  range mode is selected.
+
+2011-04-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java:
+	  Added setter for the location and distance values.
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/UIProvider.java:
+	  Added setter for an artifact.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Set the current artifact to the provider to make the old data available
+	  for the other widgets.
+
+2011-04-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java: New
+	  i18n strings for a 'longitudinal section curve' output tab.
+
+2011-04-28  Raimund Renkert <rrenkert@intevation.de>
+
+	Added class diagrams.
+
+	* doc/Flys-UI-Classes.png, doc/Flys-UI-Services-Classes.png: New.
+
+2011-04-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java:
+	  The error key that is provided by the FLYS artifact server is read from
+	  feed() result document and used to bring up an error popup with an
+	  translated error message.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added error messages for the feed operation.
+
+2011-04-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/Config.java:
+	  A new method returns the name of the current locale now.
+
+	* src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/GetArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/UserServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/DistanceInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserService.java,
+	  src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/services/RiverServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/RiverService.java,
+	  src/main/java/de/intevation/flys/client/client/services/DescribeCollectionServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/GetArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactService.java,
+	  src/main/java/de/intevation/flys/client/client/services/GetArtifactService.java,
+	  src/main/java/de/intevation/flys/client/client/services/StepForwardServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/AdvanceServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/StepForwardService.java,
+	  src/main/java/de/intevation/flys/client/client/services/AdvanceService.java,
+	  src/main/java/de/intevation/flys/client/client/services/AddArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/DistanceInfoServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java,
+	  src/main/java/de/intevation/flys/client/client/services/DistanceInfoService.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserCollectionsServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserCollectionsService.java:
+	  Introduced a "locale" parameter that stores the name of the current
+	  locale. This is used to set the locale of the request object manually.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ProjectList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Modified the RPC service calls (introduction of a locale).
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  The title of the ParameterList depends on the Artifact's name if we
+	  gonna create a new CollectionView with an existing Artifact.
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/Artifact.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultArtifact.java:
+	  An artifact knows its name now. It is retrievable via getName().
+
+	* src/main/java/de/intevation/flys/client/shared/model/WINFOArtifact.java:
+	  New. A concrete class that represents an Artifact using the WINFO
+	  parameterization.
+
+	* src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java:
+	  The ArtifactCreator builds up new Artifacts based on the name in the
+	  DESCRIBE document. If no name is included, a DefaultArtifact is created.
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java:
+	  This record class uses the default mechanism to store/load values -
+	  it uses the setAttribute() and getAttribute() methods now.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java: The
+	  list is sorted based on the project's creation time now.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java:
+	  Removed. The collection grid is no longer used, because the fields are
+	  created by using default mechanisms (setting the field type, using cell
+	  formatter).
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java:
+	  Implemented a method to open an existing project. The method takes the
+	  UUID of a Collection and creates a new CollectionView with
+	  ParameterList based on the first Artifact that is stored in that
+	  Collection.
+
+	  NOTE: Maybe we need to introduce a mechanism to mark the artifact that
+	  defines the parameterization. I am not sure, if the first artifact is
+	  always the artifact that the Collection's parameterization is based on!
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Triggers the method of FLYS to open an existing project.
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Added new constructors that enables us to create instances with an
+	  existing parameterization (with a given artifact).
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added further error messages.
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java:
+	  There is a new method that returns the Collection object which is
+	  represented by this record.
+
+2011-04-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/GetArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/GetArtifactService.java,
+	  src/main/java/de/intevation/flys/client/server/GetArtifactServiceImpl.java:
+	  New. A service that queries the artifact description based on the
+	  identifier of an artifact.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the new GetArtifactService.
+
+2011-04-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added strings that are used in the context menu of the project list.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  A right mouse click on a project opens a context menu with the options
+	  to open / delete a project.
+
+2011-04-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/DistanceInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/DistanceInfoServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/DistanceInfoService.java:
+	  New. This service fetches river specific distance information from
+	  server.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the DistanceInfoService.
+
+2011-04-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DistanceInfoObjectImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DistanceInfoObject.java:
+	  New. This model will be used by the LocationDistancePanel to bring up a
+	  table with distances which supports the user while entering the start
+	  and end point of the WINFO paramterization. A DistanceInfoObject
+	  contains information about a specific distance (description, from, to
+	  and riverside).
+
+2011-04-08  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserService.java:
+	  This service now throws an AuthenticationException if an error occured
+	  while user authentication.
+
+	* src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/RiverService.java:
+	  This service now throws a ServerException if an error occured while
+	  reading the supported rivers from artifact server.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: Show warnings
+	  if errors occur while fetching supported rivers or 
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added further strings for error messages.
+
+2011-04-08  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/exceptions/AuthenticationException.java:
+	  New. An exception that should be used if the user authentication fails.
+
+2011-04-08  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactService.java,
+	  src/main/java/de/intevation/flys/client/client/services/StepForwardService.java,
+	  src/main/java/de/intevation/flys/client/client/services/AdvanceService.java,
+	  src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java:
+	  Improved the exception handling. If an exception occurs specific to an
+	  artifact / collection specific operation, a ServerException is thrown.
+	  The message of this exception is a key that needs to be translated using
+	  the lookup mechanism of FLYSConstants.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  The dialog helper class SC of the SmartGWT framework is used to bring up
+	  warning dialogs that inform the user about errors that occured after the
+	  artifact / collection specific operations.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added strings for the exceptions thrown in the services.
+
+2011-04-08  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/exceptions/ServerException.java:
+	  New. This exception is used to be thrown after an error occured while
+	  one of the artifact / collection operations.
+
+2011-04-07  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Adjusted the code to trigger the out() operation of the Collection
+	  instead of the out() operation of the first Artifact in that Collection.
+
+2011-04-07  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Added new strings for a warning dialog that is opened when the user
+	  start changing the current language.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Fixed
+	  the function to toggle the language and added a warning dialog that
+	  informs the user about the creation of a new session when the language
+	  is changed.
+
+2011-04-05  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  New. A constants interface with the ability to lookup an i18n string
+	  with a given key.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ProjectList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MainMenu.java,
+	  src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java:
+	  Replaced the FLYSMessages interface with the FLYSConstants interface.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Removed.
+
+2011-04-05  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java:
+	  Implemented the toggle button to switch the current locale.
+
+2011-04-05  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties:
+	  Added missing strings used in the footer.
+
+2011-03-30  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged RELEASE 0.1
+
+2011-03-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Removed some comments that have been commited by mistaken.
+
+2011-03-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Derives the ConstantsWithLookup interface now. This makes it possible to
+	  fetch i18n string using a getString(String key) lookup method.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Removed '@DefaultMessage' annotations - they are not available for
+	  ConstantsWithLookup, added a further i18n string and fixed another one.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Some modifications related to the changes above.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Removed the hard coded title determination based on the selected module.
+	  Now, the getString() of FLYSMessages is used to determine the human
+	  readable string.
+
+2011-03-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/FLYS.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java:
+	  Removed useless imports.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: The
+	  CollectionView no longer gets an empty collection when it is created.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java:
+	  The CollectionViews are no longer stored in a Map but in a List.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Bugfix: We just create a new collection a single time - if no one is
+	  existing. If the output modes of the artifact that is used for the
+	  parameterization changes, we fetch the new DESCRIBE document of the
+	  collection using the new DescribeCollectionService.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/DescribeCollectionServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java:
+	  New. This service is used to fetch the DESCRIBE document of a specific
+	  collection and returns a Collection object that contains the information of
+	  that document. The code to parse the DESCRIBE has been moved here from
+	  the AddArtifactServiceImpl which now derives the
+	  DescribeCollectionServiceImpl.
+
+	* src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java:
+	  This service is derived from DescribeCollectionServiceImpl now, because
+	  the methods to parse the DESCRIBE document are moved to that service.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the
+	  DescribeCollectionService.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Replaced the german title of the project list 'Berechnungen' with
+	  'Projekte'.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: Registered the
+	  ProjectList as CollectionChangeHandler of each created CollectionView.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Implements the CollectionChangeHandler to update the list of user
+	  collections after a collection changed (or has been created).
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java,
+	  src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java:
+	  Modified the output of the 'name' and 'date' fields.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Added a format for datetime strings.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserCollectionsServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserCollectionsService.java:
+	  New. This service returns a list of Collections owned by a specified
+	  user.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the UserCollectionsService.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Collection.java:
+	  Added methods to retrieve the creation time.
+
+2011-03-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Fixed code
+	  in ProjectList toggle method.
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java: Fixed
+	  the WQInputPanel label to have the correct size.
+
+2011-03-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/webapp/FLYS.html: Added style information to avoid the smartgwt
+	  theme margin.
+
+2011-03-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Changed some german strings.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Changed tab title.
+
+2011-03-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: Set
+	  label width to have a tabled style for WINFO selections.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Resized window to fit the content size.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  The ParameterList is a Tab now and can set its title itself. So, the
+	  title will change after the module is chosen.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Removed code to insert the ParameterList into a new Tab. This is no longer
+	  needed, because the ParameterList is a Tab itself.
+
+2011-03-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Modified the string that points to the 'back button' image.
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  Modified the URL that points to the 'back button' image. Now, the
+	  base URL is taken into account as well. The button will be shown
+	  everywhere now (in every installation)!
+
+2011-03-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: Set
+	  label width to have a tabled style for WINFO selections.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	 Resized window to fit the content size.
+
+2011-03-29  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Fixed
+	 toggle method.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java:
+	  A CollectionItem has a hash() method now. The value comes from the
+	  Collection's DESCRIBE document.
+
+	* src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java:
+	  The hash value of a collection item is parsed from DESCRIBE document.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Appended the hash value of the artifact to the URL of the chart image.
+	  This bypasses the browser cache of a previous chart image.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  A parameterization change will always remove all output tabs before
+	  updating the output tab panel.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Modified existing string and added a new one.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Added a further radio button for a plugin and changed the alignment of
+	  the radio button to vertical.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  Removed the "TODO: ThemeEditor" label.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Removed the date string from title bar.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  A UIProvider might now have a panel that can be used to render helper
+	  widgets. E.g. the river selection will render its river map into this
+	  panel. It is injected and can be placed somewhere around the
+	  application.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Injected the right panel of the parameter panel into the UIProvider.
+	  Helper widgets are rendered into this panel now!
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Some layout improvements (heights, position of elements and so far).
+
+2011-03-28  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: The project
+	list button toggles the project list now.
+
+2011-03-28  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  Replaced next button image with smartgwt button.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Removed
+	 button path, added text for new button.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties:
+	  Removed image path, added english text for button.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Removed image path, added german text for button.
+
+2011-03-28  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added text
+	  for FLYSFooter.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Added german text for footer label.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java: New. A
+	  new ui element at the bottom of the page.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: Added footer
+	  element to FLYS webpage.
+
+2011-03-28  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Customized ProjectList style.
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSView.java: Set
+	  background color and size constraints.
+
+	* src/main/webapp/FLYS.css: Added background style.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  The right side of this panel displays an image now. This image
+	  represents a chart that is generated by an artifact. The request is made
+	  up in the ChartOutputServiceImpl.
+
+	* src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java:
+	  New. This service creates the request to retrieve chart images and
+	  writes the response to the output stream.
+
+	  NOTE: This service is not asynchron! It is derived directly from
+	  HttpServlet.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the ChartOutputService.
+
+2011-03-25  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Limited the area for CollectionView to the size of FLYSWorkspace.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/OutputTab.java: Fixed
+	  a typo.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java:
+	  An OutputTab with two panels. The left one is not implemented yet
+	  (ThemeEditor). The right one will display an image.
+
+	* src/main/java/de/intevation/flys/client/client/ui/OutputTab.java: The
+	  content pane is set in the constructor.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  New output tabs will use the ChartOutputTab.
+
+	  NOTE: We should move the code that constructs the concrete output tabs
+	  into a factory class that decides which OutputTab has to be used.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  The tab bar is extended with output tabs if the artifact used for the
+	  parameterization reaches a state with output modes.
+
+	* src/main/java/de/intevation/flys/client/client/ui/OutputTab.java: A
+	  base class that might be used to derive concrete output tabs for charts,
+	  maps and so on.
+
+2011-03-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Moved parameterization specific code from CollectionView to
+	  ParameterList.
+
+2011-03-26  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Moved ParameterList specific code into the ParameterList.
+
+2011-03-25  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java:
+	  Changed the return type to 'Collection' - returned a UUID (String)
+	  before.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  The artifact is put into the collection (or new collection) if we reach
+	  a step in the parameterization in that an artifact has reachable
+	  outputs. Furthermore, some adjustments related to the changes of the
+	  return type in the CreateCollectionService.
+
+2011-03-25  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/webapp/WEB-INF/web.xml: Made the AddArtifactService accessible.
+
+2011-03-25  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/AddArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java,
+	  src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java:
+	  New. This service adds an existing artifact to an existing collection.
+	  The return value of this service is a Collection that is filled with
+	  CollectionItems and OutputModes.
+
+2011-03-25  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/FLYS.gwt.xml: Changed theme to
+	  smartgwt Enterprise Blue.
+
+2011-03-25  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/Facet.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultFacet.java:
+	  New. An interface and its default implementation that provide methods
+	  to get information about facets. Currently, the only information that is
+	  supported is the name of the facet.
+
+	* src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java:
+	  New. An interface and its default implementation that provide methods to
+	  get information about the available output modes and its facets of
+	  artifacts -> a CollectionItem is related to an artifact - both have the
+	  same identifier.
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Collection.java:
+	  The Collection no longer stores references to artifacts, but to
+	  CollectionItems. I have changed this, because the artifact contains a
+	  lot more information we need for the Collections. So, I decided to
+	  create CollectionItems that are related to artiacts but just know about
+	  the possible outputmodes and facets.
+
+2011-03-24  Raimund Renkert <rrenkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Set styles
+	  for label.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java: Fixed the
+	  method to calculate the image width and resized the BfG logo.
+
+	* src/main/webapp/FLYS.css: Introduced styles for fonts and BfG colorscheme.
+
+2011-03-23  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  Extract the output modes from DESCRIBE document and fill the
+	  ArtifactDescription with those objects.
+
+2011-03-23  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java:
+	  Added a method to retrieve the available output modes of the artifact.
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java:
+	  Implemented the method to retrieve the available output modes and
+	  enhanced the default constructor with a parameter for output modes.
+
+2011-03-23  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/OutputMode.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java:
+	  New. An interface and its default implementation that describes
+	  available output modes of artifacts.
+
+2011-03-21  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/webapp/images/next.xcf: Moved to images/next.xcf to avoid that
+	  this file is included in the WAR archive of the web application.
+
+	* images/next.xcf: Moved from src/main/webapp/images/next.xcf.
+
+2011-03-21  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  Parse the selected values as human readable strings from the static UI
+	  part.
+
+	* src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Display human readable values in the static UI part.
+
+2011-03-21  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/event/HasStepBackHandlers.java,
+	  src/main/java/de/intevation/flys/client/client/event/StepBackHandler.java,
+	  src/main/java/de/intevation/flys/client/client/event/StepBackEvent.java:
+	  New. These classes are used to realize a notification mechanism to
+	  listen to the step-back part of the advance() operation. UI elements
+	  should fire a StepBackEvent if the user tries to step back to a previous
+	  state.
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  The UIProvider implements the HasStepBackHandlers interface and fires
+	  StepBackEvents if the 'back' button has been clicked.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Listens to StepBackEvents. If such an event is received, we gonna remove
+	  all old state items from the list and revert the view. Afterwards, the
+	  artifact description is used to redraw the whole view.
+
+	  NOTE: I think we should just remove those items that belong to states
+	  between the current state and the target state. This would avoid a
+	  complete refresh of the ParameterPanel.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Listens to StepBackEvents. If such an event is received, the advance()
+	  operation is triggerd with the current artifact and the new target
+	  state identifier to step back to that state.
+
+2011-03-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java:
+	  The methods that validates a FormItem will skip StaticTextItem
+	  validation.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Added a mechanism to validate and save user input before returning the
+	  data entered in the fields.
+	  Reason: the BlurEvent - after that we gonne validate and save the input
+	  stuff - is not fired when the focus is still in one of the text fields
+	  and we click the 'next' button immediately. A nullpointer exception
+	  would be the result (which is avoided with the mechanism).
+
+2011-03-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Added localized strings that point to the source of the 'back' button.
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  Added a new method that creates the 'back' button and returns it.
+
+	  TODO: Fire an event that triggers the ADVANCE action.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Append the 'back' button in the panel with the 'old' parameters.
+
+	* src/main/webapp/images/back.png,
+	  src/main/webapp/images/back_en.png,
+	  src/main/webapp/images/back_de.png: New. Images für the 'back' button in
+	  the parameterization.
+
+2011-03-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  localized strings that point to the images of the 'next' button.
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  There is a method that creates the 'next' button, adds the UIProvider as
+	  ClickHandler and returns the button.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  The 'next' button is created in the AbstractUIProvider. So, we have a
+	  central place to adjust the look of this button.
+
+	* src/main/webapp/images/next.xcf,
+	  src/main/webapp/images/next.png,
+	  src/main/webapp/images/next_en.png,
+	  src/main/webapp/images/next_de.png: Images for the 'next' button in the
+	  parameterization.
+
+2011-03-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Read min/max values and define those values as default values for the
+	  distance modes.
+
+2011-03-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Read min/max values and define those values as default values for the
+	  distance mode.
+
+2011-03-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  When a state is reached with no further user input, the 'current'
+	  property of the ParameterList is set to 'null' and no dynamic panel is
+	  shown.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Fixed a typo.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  The widgets displayed in the static panel are created using the
+	  UIProvider defined in the DataList.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProvider.java: There
+	  is a new method createOld() that is used to create the static
+	  representation of a DataList.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Implemented the createOld() method.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DataList.java:
+	  Added a constructor to create a DataList with a label.
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  Read the label of the static state data objects and create the DataList
+	  objects with this attribute.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DataList.java: This
+	  data structure manages a list of Data objects. A DataList is the list of
+	  Data objects that a single State can have. So, this class has methods to
+	  retrieve the name of the state it belongs to, the list of Data objects,
+	  the recommended UIProvider and a label.
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java,
+	  src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Data.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultData.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/UIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Necessary refactoring to introduce the DataList data structure to manage
+	  the list of Data objects a single State provides.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Added a bit more space between the values that have been entered in
+	  former states and the current input panel.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Data.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultData.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Removed needless imported.
+
+	* src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  The SelectProvider extends the AbstractUIProvider now. Now, each
+	  concrete UIProvider is an instance of the AbstractUIProvider that
+	  handles some basic events.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  The Single-W panel is displayed initially when the WQInputPanel is
+	  rendered.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Implemented some methods to retrieve the data that have been entered by
+	  the user. The getData() method retrieves data now!
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Implemented some methods to retrieve the data that have been entered by
+	  the user. The getData() method retrieves data now!
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Defined the 'WINFO' plugin as default plugin. The initial view will
+	  display a preselcted winfo radio button.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Added the missing 'next' button.
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Added the ClickHandler to the 'next' button.
+
+2011-03-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  The 'uiprovider' attribute 'wq_panel' will return a WQInputPanel
+	  provider.
+
+2011-03-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Some refactoring. This class now uses the DoubleRangePanel and
+	  DoubleArrayPanel for the two different input modes as well.
+
+2011-03-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  i18n strings used in the WQInputPanel.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java:
+	  New. This panel contains three input fields that enables the user to
+	  enter a start and end value and a step width. Furthermore, there are
+	  methods to validate the fields and to retrieve its values.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java:
+	  New. This panel contains a single input field that enables the user to
+	  enter a list of double values. There is a method to validate the input
+	  and a method to retrieve the list of entered double values.
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  New. This panel allows the user to enter W or Q values for single or
+	  range input in one single state.
+
+2011-03-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  i18n strings used in the LocationDistancePanel.
+
+	* src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java:
+	  New. This abstract class implements the UIProvider and the
+	  HasStepForwardHandlers interface and its necessary methods. These two
+	  things are required by each concrete UIProvider, so this class should be
+	  the base class for further concrete UIProviders.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  New. A UIProvider that enables the user to enter locations or a
+	  distance.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  States with a uiprovider attribute set to 'location_distance_panel' use
+	  the LocationDistancePanel for user input.
+
+2011-03-15  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Clear the panel that displays the current input widget before adding a
+	  new one to this panel.
+
+2011-03-15  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  a i18n string for a new calculation.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSImages.java,
+	  src/main/java/de/intevation/flys/client/client/images/gewkarte.png: New
+	  image: the map that shows the relevant rivers.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MapSelection.java:
+	  Added the river map to the right panel of that widget.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Implemented the step forward mechanism.
+
+2011-03-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Save the name of the data item. We need the name for feed().
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Before adding further old data items, we gonna check if the item is
+	  already existing in the list. If it exists, the item is not added.
+
+2011-03-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Read i18n strings from DESCRIBE document and display them in the UI.
+
+2011-03-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Integrated the mechnism to listen on paramer changes. The CollectionView
+	  is both: a HasParameterChangeHandler and a ParameterChangeHandler.
+
+2011-03-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Bugfix: Removed static string from gui.
+
+2011-03-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  Parse the static data from DESCRIBE document and put it into the
+	  ArtifactDescription.
+
+2011-03-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/event/HasParameterChangeHandler.java,
+	  src/main/java/de/intevation/flys/client/client/event/ParameterChangeHandler.java,
+	  src/main/java/de/intevation/flys/client/client/event/ParameterChangeEvent.java:
+	  New. Interfaces and classes used for a listener mechanism to notify
+	  listeners when the parameterization of a Collection/Artifact has
+	  changed.
+
+2011-03-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/StepForwardServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/StepForwardService.java,
+	  src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java:
+	  New. This service bundles the artifact operations feed() and advance()
+	  into a single service.
+
+	* src/main/java/de/intevation/flys/client/client/services/AdvanceServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/AdvanceService.java,
+	  src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java:
+	  New. This service provides a method that triggers the advance() operation
+	  of the artifact server.
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  Added code to parse the reachable states from DESCRIBE.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Make use of the 'forward' service after choosing the module and the river.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the new services 'forward' and
+	  'advance'.
+
+2011-03-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/test/java/de/intevation/flys/client/FLYSJUnit.gwt.xml,
+	  src/main/java/de/intevation/flys/client/client/GreetingServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/GreetingService.java:
+	  Removed the GreetingService from out application - this service has been
+	  added initially by creating this repository.
+
+2011-03-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  i18n strings for the module and river selection.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  New. A wrapper for the module and river selection. Both information can
+	  be chosen in just one step.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java:
+	  Some layout improvements.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Makes use of the ModuleSelection if no artifact is existing in a new
+	  CollectionView. Users may now choose the desired plugin and the river in
+	  one single step.
+
+2011-03-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/RiverServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/RiverService.java,
+	  src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java:
+	  New. A service that retrieves a list of supported rivers by the artifact
+	  server.
+
+	* src/main/java/de/intevation/flys/client/shared/model/River.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultRiver.java:
+	  New. A model class and its default implementation to store rivers.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: At application
+	  start, the provided rivers by the artifact server are fetched using the
+	  RiverService. The rivers are queriable via a getRivers() method.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the RiverService.
+
+2011-03-08  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  i18n strings used in the menu panel.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: Added a method
+	  to retrieve the project list.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Added
+	  further buttons (labels with ClickHandler) to switch the language,
+	  logout the current user or open an info panel.
+
+2011-03-08  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/images/flys_logo.gif,
+	  src/main/java/de/intevation/flys/client/client/images/bfg_logo.gif: New.
+	  A logo of the BfG and a logo of the application FLYS. Both copied from
+	  desktop FLYS.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSImages.java: New.
+	  This interface grants access to the images used in this application.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java:
+	  Added the fullname of FLYS.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java: New.
+	  This class displays the header containing a FLYS and a BfG logo.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: Integrated the
+	  FLYSHeader into the layout at the bottom of the application.
+
+	* src/main/webapp/FLYS.html: Set the title of the application to
+	  "FLYS-3.0".
+
+2011-03-07  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java,
+	  src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java:
+	  New. A service that might be used to create new collections in the
+	  artifact server.
+
+	* src/main/webapp/WEB-INF/web.xml: Registered the service to create new
+	  collections.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Added the service to create new collections. Currently, this service is
+	  not used.
+
+2011-03-07  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultUser.java,
+	  src/main/java/de/intevation/flys/client/shared/model/User.java: A user
+	  interface and its default implementation.
+
+	* src/main/java/de/intevation/flys/client/client/services/UserService.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java,
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java: This
+	  service will currently return the first user that is returned by the
+	  artifact server.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: The FLYS
+	  instance stores the user that is logged in, because we need to make use of
+	  this user in many services.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Make use
+	  of the User of this package - the User of the common package is not used
+	  any longer.
+
+2011-03-02	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* pom.xml: Added missing SmartGWT repository.
+
+2011-02-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java: A UI
+	  widget that stores and displays the data of former states and the current
+	  data. The widget displaying of the current data is created by the
+	  UIProvider that is stored in the Data object.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java: We
+	  are able to create new WINFO artifacts. After the artifact has been
+	  created, the first 'state' is rendered in a 'WINFO tab' using the
+	  ParameterList.
+
+2011-02-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  The 'uiprovider' attribute is parsed from DESCRIBE document and stored at
+	  the Data object.
+
+	* src/main/java/de/intevation/flys/client/shared/model/Data.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultData.java:
+	  Implemented code to store the UIProvider (as string!) for the Data object.
+
+2011-02-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/event/StepForwardEvent.java:
+	  An event that is thrown after the user has selected or entered data in the
+	  UI and triggers the feed & advance operations via UI button.
+
+	* src/main/java/de/intevation/flys/client/client/event/HasStepForwardHandlers.java:
+	  This interface is used by classes that provide that step forward
+	  mechanism.
+
+	* src/main/java/de/intevation/flys/client/client/event/StepForwardHandler.java:
+	  This interface is used by classes that want to listen to
+	  StepForwardEvents.
+
+2011-02-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProvider.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MapSelection.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java: The
+	  interface description and two implementations of a UIProvider. A
+	  UIProvider is used to create widgets for the user input. The UIProvider
+	  that is used in the current state depends on the data type in the describe
+	  document and a 'uiprovider' flag that might be configured there.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  The factory that is used to create new instances of UIProvider.
+
+2011-02-21  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  This view implements the HasCollectionChangeHandlers interface -
+	  CollectionChangeHandler can register to this class and retrieve
+	  notifications when the collection of this view changes.
+
+2011-02-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/event/CollectionChangeHandler.java,
+	  src/main/java/de/intevation/flys/client/client/event/CollectionChangeEvent.java,
+	  src/main/java/de/intevation/flys/client/client/event/HasCollectionChangeHandlers.java:
+	  New. These interfaces and classes should be used to listen to changes in
+	  Collections.
+
+2011-02-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Collection.java:
+	  Enhanced the Collection and its default implementation with new methods
+	  to add new Artifacts, retrieve Artifacts and get the number of artifacts
+	  managed by the Collection.
+
+2011-02-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
+	  New. This factory is used to create an ArtifactDescription based on an
+	  DESCRIBE document returned by the artifact server.
+
+	* src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java: A
+	  new DefaultArtifact with an ArtifactDescription that contains the dynamic
+	  UI part is returned by the create() method now.
+
+2011-02-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* pom.xml: This client uses the artifacts http-client for the communication
+	  between client and server now.
+
+	* src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java:
+	  New. An instance of the ArtitactCreator interface of the http-client. It
+	  uses the document returned by the artifact server to create an artifact
+	  instance.
+
+	  NOTE: The artifact creation needs to be implemented! This is currently
+	  just a stub to make the other things work.
+
+	* src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactService.java:
+	  The method signature of create() changed: the server url is required now.
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java:
+	  Make use of the HttpClient and the FLYSArtifactCreator to create
+	  artifacts.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Added the server url to the create() call of the ArtifactService.
+
+2011-02-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  This view will now display radio buttons to choose between the module
+	  'WINFO', 'MINFO', 'Map' and 'Fix-Analyse'. A button is shown to create an
+	  artifact of the selected module.
+
+	  NOTE: The next step here is to use the returning artifact with its
+	  description and display widgets based on these information.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  i18n strings for the CollectionView's 'next' button.
+
+2011-02-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DataItem.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Data.java: The
+	  interfaces implement the Serializable interface now.
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultDataItem.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultData.java:
+	  New. Default implementions of the interfaces above. These classes
+	  implements constructors and the necessary methods of the interface
+	  descriptions only!
+
+2011-02-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactService.java:
+	  New. Interface descriptions and the server implementation of an artifact
+	  service that provides basic methods for working with artifacts.
+
+	  NOTE: The implementation is currently just a stub. The artifact creation
+	  needs to be implemented.
+
+	* src/main/webapp/WEB-INF/web.xml: Added a servlet for the artifact
+	  interface.
+
+2011-02-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/Artifact.java:
+	  Implements the serializable interface which is necessary to be able to
+	  use this object in the GWT client code.
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultArtifact.java:
+	  New. A simple default implementation of an artifact.
+
+2011-02-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/FLYS.gwt.xml: Added the
+	  Resources and XML modules of GWT.
+
+	* src/main/java/de/intevation/flys/client/client/config.xml: An xml file
+	  that will contain the client configuration.
+
+	* src/main/java/de/intevation/flys/client/client/Config.java: New. This
+	  class should be used to handle the client configuration and provides
+	  methods for retrieving information about the configuration.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSResources.java: The
+	  configuration (Config) is initialized at the startup.
+
+2011-02-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/Artifact.java: New.
+	  The interface description of an artifact used in this client. There are
+	  several methods that provide information about the artifact itself and its
+	  representation.
+
+	* src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java:
+	  New. The ArtifactDescription provides information about the current
+	  representation of an artifact.
+
+	* src/main/java/de/intevation/flys/client/shared/model/DataItem.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Data.java: New. The
+	  interfaces are used to handle user input.
+
+2011-02-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  strings for the plugins.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Display radio buttons if the collection is new and no plugin (winfo,
+	  minfo, map, fix analyse) has been chosen.
+
+2011-02-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: New
+	  strings for the CollectionViews.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java: New.
+	  This is the workspace for FLYS. It contains the windows for each
+	  collection of the user.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  New. This window will display a collection. Currently, it has just a
+	  title, but no content.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSView.java: Displays
+	  the FLYSWorkspace.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: Added a
+	  button to open new collections.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: The
+	  FLYSWorkspace is created here. FLYS stores a reference to it and puts the
+	  workspace into the FLYSView. Furthermore, there is a new method that
+	  creates new Collections.
+
+	  NOTE: Currently, there is no communication with the artifact server,
+	  because Collections aren't implemented yet!
+
+2011-02-11  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Collection.java:
+	  Added a new method that returns the UUID of the collection.
+
+2011-02-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java: The
+	  ProjectList stores a reference to the current user and provides a list
+	  with his existing projects.
+
+	  NOTE: There are created two Collections and two CollectionRecords for the
+	  mockup. This code needs to be removed after a service to fetch the user
+	  collections has been implemented.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionGrid.java:
+	  This grid will show a list of collections with its last modification date,
+	  their uuid and two buttons to publish and delete the collection.
+
+	  NOTE: The buttons have no effect yet.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: The FLYS class
+	  has a reference to the ProjectList. If a logged in user was found, the
+	  ProjectList is initialized and added to the FLYSView.
+
+	* src/main/java/de/intevation/flys/client/client/ui/FLYSView.java: There is
+	  a new method to set the ProjectList. Furthermore, all UI components are
+	  put into a HLayout now. On this way, we are able to open/close the
+	  ProjectList.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties:
+	  Added strings for the project list.
+
+2011-02-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Collection.java: The
+	  interface and its default implementation of a Collection.
+	  NOTE: I think both classes will change pretty much, but they have been
+	  necessary for the ProjectList mockup.
+
+2011-02-10  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/FLYS.gwt.xml: The artifact-common
+	  package is available in the GWT code now.
+
+	* pom.xml: Made the artifact-common package available.
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserService.java,
+	  src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java:
+	  A service definition that retrieves user information. Currently, this
+	  service defines a single method that returns the user that is currently
+	  logged in.
+
+	* src/main/webapp/WEB-INF/web.xml: Added a servlet definition that provides
+	  the UserService.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSMessages_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSMessages.java: Added
+	  I18N string for a guest user.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MainMenu.java: There are
+	  new methods to set the current user and to update the menu with its name.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java: After creating
+	  the necessary components, the current user is queried by the UserService
+	  and displayed in the menu bar.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/Changes	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,45 @@
+2011-05-13  RELEASE 2.3
+
+    NEW:
+
+        * Initial GWT/Ajax based Web-Client for the REST based artifact system:
+          - Renderer for states specific for WINFO artifact
+          - Panels for W/Q selection
+          - Panels for Range selection
+          - Chart panels for chart output creation
+          - Export panels that provides download links for exporting computation
+            data
+          - Project list displays former projects that might be opened by
+            double click
+          - Datacage (dt. 'Datenkorb') UI that displays loadable data for charts
+
+        * RPC-services enable data exchange between client and server
+
+        * Connection settings are configured in config.xml
+
+        * I18N is splitted into two parts and support English and German:
+          - GUI elements are translated using the GWT i18n mechanism
+          - Information/data served by the artifact system is translated by the
+            artifact server
+
+
+    LIMITATIONS:
+
+        * Language switch drops the current session
+
+        * Charts served by the artifact system are rendered as PNG only
+
+        * Theme control for charts is not implemented yet.
+
+        * Data served by the datacage can't be added to projects/charts
+
+
+    !!!
+
+    The version number of this release depends on an existing desktop variant of
+    this software that is in version 2.1.
+
+    !!!
+
+
+2011-03-30  RELEASE 0.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/FLYS.launch	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
+<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;FLYS&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/FLYS/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento project=&quot;FLYS&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war src/main/webapp -startupUrl FLYS.html de.intevation.flys.client.FLYS"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="FLYS"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+</launchConfiguration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/FLYSTest-dev.launch	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="de.intevation.flys.client.client.FLYSTest"/>
+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;FLYS&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/FLYS/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/FLYS/src/test/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento project=&quot;FLYS&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;/vol1/download/ingo/gwt-2.1.1/gwt-dev.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="FLYS"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgwt.args=&quot;-standardsMode -logLevel WARN&quot; -Xmx256M"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+</launchConfiguration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/FLYSTest-prod.launch	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="de.intevation.flys.client.client.FLYSTest"/>
+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;FLYS&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/FLYS/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/FLYS/src/test/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento project=&quot;FLYS&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;/vol1/download/ingo/gwt-2.1.1/gwt-dev.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="FLYS"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgwt.args=&quot;-prod -standardsMode -logLevel WARN -out www-test&quot; -Xmx256M"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+</launchConfiguration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/NEWS	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,109 @@
+NEWS
+
+2011-05-16  Release V 2.3
+
+=== Framework ===
+
+ * Projektverwaltung (Pflichtenheft Kap. 3.3, Lokale Daten > Arbeitssitzungen)
+  * Mit dem Anlegen eines neuen Projektes wird die Projektliste automatisch gefüllt.
+   * Zu beachten: Zur Zeit operiert das System noch mit '''einem''' Benutzer, so dass jeder alle auf dem Server liegenden Projekte sieht. Mit der Einführung einer Nutzeranmeldung sieht dann jeder Nutzer nur noch seine eigenen Projekte.
+  * Mit einem Doppelklick oder das Kontextmenü können die jeweiligen Projekte wieder geöffnet werden. Sie stellen den Arbeitszustand des letzten "Übernehmen" wieder her. Die Einstellung ist sprachunabhängig, d.h. auch wenn zuvor Diagramme in deutsch erstellt worden sind, können diese in englischer Sprache geöffnet und dargestellt werden.
+   * Projekte können Projekte noch in mehreren Fenster geöffnet werden. Um Konsistenz herzustellen, kann man ein Projekt nur einmal öffnen. (vgl. https://roundup-intern.intevation.de/flys/issue21)
+  * Neue Fenster überlappen sich nicht mit der Position des vorherigen Fensters, um beim Anlegen eines neuen Projektes eine vollständige Überdeckung zu vermeiden
+   * Projektfenster maximieren (vgl. https://roundup-intern.intevation.de/flys/issue35)
+
+ * Projekteinstieg
+  * Klick-Optimierung der Gewässerauswahl über eine Liste: von 3 Klicks zu 1 Klick.
+
+ * Internationalisierung (Pflichtenheft, Kap.4.3.4)
+  * Beim Start wird die Spracheinstellung des Browser automatisch ausgewertet und die dazugehörige Oberfläche in deutsch oder englisch geladen. Wenn eine andere Sprache als deutsch oder englisch angefragt wird, fällt die Anwendung auf englisch (TOCHECK) zurück.
+  * Die Sprache kann jeweils manuell gewechselt werden. Dies hat Auswirkungen auf die Bedienoberfläche, Diagramme und Nutzung von Dezimaltrenner und Punkt
+
+=== Fachdatenbestand ===
+ * Import der hydrologischen Daten der Elbe
+##  * Was wird nicht berücksichtigt?
+##   * Spalten in wst-Dateien mit einer - Notation; andere, nicht einheitliche werde jeweils mit einer Ziffer erweitert
+ * Einige Zahlen zum Bestand:
+  * 3 Gewässern mit Saar, Mosel und Elbe
+  * 15 Pegel
+  * 108 wst/zus-Dateien
+   * 711 Spalten aus diesen
+   * rund 500.000 Einzelwerte
+  * rund 2.500 Stationierungen aus km-Dateien
+ 
+
+=== WINFO ===
+
+ * Wahl des Gewässers (Pflichtenheft, Teile aus 3.4.1, 3.4.1.1)
+  * Automatische Vorbelegung des ersten Eintrags
+
+ * Wahl der Berechnungsart (Pflichtenheft 3.4.1.1 - bestehende Funktionen)
+  * Automatische Vorbelegung des ersten Eintrags
+  * Umsetzung der folgenden Berechnungsarten
+   * Wasserstand/Wasserspiegellage
+   * Abflusskurve/Abflusstafel
+   * Dauerlinie
+   * W bei ungleichmäßigem Abflusslängsschnitt
+
+ * Wahl von Strecke oder Ort (Pflichtenheft: Bestehende Funktionen aus Desktop-FLYS; keine Entsprechung in Leistungsbeschreibung)
+
+   * Automatisches Umschalten der Reiter bei Wahl von Orten oder Strecken
+
+  * Eingabe eines Ortes (Dauerlinie, Abflusstafel/-kurve)
+   * Freie Texteingabe
+   * Unterstützung der Eingabe durch Liste an Ortsfavoriten. Per Klick wird jeweils der Wert in das Textfeld eingetragen.
+
+  * Eingabe mehrere Orte (Wasserstand/Wasserspiegellage)
+   * Freie Texteingabe
+   * Unterstützung der Eingabe durch Auswahltabellen an Ortsfavoriten. Per Klick wird jeweils der Wert in das Textfeld eingetragen.
+   * Übernehmen von Beginn einer Strecke und Ende einer Strecke (abweichend von Desktop-FLYS, um die Bedienführung gradliniger zu gestalten)
+   
+  * Eingabe von Strecken (Wasserstand/Wasserspiegellage)
+   * Freie Texteingabe
+   * Unterstützung der Eingabe durch Auswahltabellen an Streckenfavoriten. Per Klick wird jeweils der Wert in das Textfeld eingetragen.
+   * Übernehmen von Beginn einer Strecke und Ende einer Strecke aus den Ortsfavoriten mit explizitem Setzen von Beginn (grüne Fahne) und Ende (Rote Fahne) (Erweiterung zu Desktop-FLYS)
+   * Bemerkungen:
+    * Es gibt Streckendaten, die außerhalb der Berechnungsstrecke des Modells liegen. Können die Ortsfavoritenbestände hierauf reduziert werden, da hier keine Ermittlung von Wasserständen erfolgen kann bzw. Favoriten außerhalb der Bezugspegelstrecken erlauben keine Ermittlung eines Bezugspegels.
+
+ * Automatische Ermittlung des Bezugspegels (Keine Entsprechung in Leistungsbeschreibung. Neue Anforderung als Ergebnis des Bedienkonzeptes.)
+  * Gewässer und Streckenwahl ermitteln den Bezugspegel automatisch
+  * Anzeige der Abflusskurven aller Pegel auf der vorgegebenen Strecke
+
+  * Wahl von Abflüssen, Wasserständen und Dauerzahlen (Pflichtenheft: Bestehende Funktionen aus Desktop-FLYS; keine Entsprechung in Leistungsbeschreibung)
+   * Berechnungsart: Wasserspiegellagen/Wasserstand
+    * Eingabefelder wie in Desktop-FLYS für W oder Q; Einzelwerte oder Wertebereich
+    * Eingaben werden über eine tabellarische Auswahl unterstützt
+     * Bei der Eingabe von W: Wasserstände sind auswählbar
+     * Bei der Eingabe von Q: Hauptwerte und Dauerzahlen sind auswählbar
+   * Berechnungsart: W bei ungleichmäßigem Abflusslängsschnitt
+    * Eingabefelder für W und Q analog zu bisherigen genutzten Mechanismen
+
+ * Berechnungsausgabe (Pflichtenheft: Teile in Kap. 3.4.1.1; bestehende Funktionen aus Desktop-FLYS + Verbesserungen)
+  * Ausgabe jeweils in einer strukturierten Tabelle.
+  * Die Werte können in Abhängigkeit von der Spalte auf- und absteigend sortiert werden.
+  * Ergebnisse werden jeweils im CSV-Format ausgegeben
+  * Es werden weitere Ausgaben in zusätzlichen Reitern angezeigt, die auch abgefragt werden können.
+
+=== Diagramme ===
+  * Allgemein:
+   * Integrierte Ausgabe der Diagramme in WINFO (Pflichtenheft Kap. 3.1)
+   * Zugriff auf die Projektdefinition/Parameterisierung (WINFO-Reiter)
+   * Freie Größenskalierung der Diagramme in Abhängigkeit vom Projektfenster
+   * Internationalisierung der Diagramme in deutsch und englisch (Beschriftung, Dezimaltrennzeichen und Tausendertrennzeichen)
+   * Beschriftung der Diagrammtitel gemäß Anhang (Leistungsbeschreibung, Anhang 1)
+    
+  * Anpassungen in Abhängigkeit von Berechnungsart/Diagrammtyp (Bestehendes Verhalten aus Desktop-FLYS):
+   * Abflusskurve am Pegel
+   * Längsschnitt
+    * Wasser fließt immer von links nach rechts (unabhängig von der Orientierung der Stationierung; die Orientierung kann pro Gewässer explizit gesetzt werden.)
+   * Abflusskurve/-tafel
+   * Dauerlinie
+    * Kombiniertes Diagramm von W- und Q-Dauerlinie (Pflichtenheft 3.4.1.8.6)
+   * W bei ungleichmäßigem Abflusslängsschnitt
+    * Kombiniertes Diagramm von W-Diagramm und Q-Vorschau (Pflichtenheft 3.4.1.8.6)
+
+
+=== Datenkorb (Pflichtenheft 3.4.1, ausgehend von Desktop-FLYS) ===
+ * Anzeige aller in der Datenbank vorhandenen Datensätze für das gewählte Gewässer (FLYS-Daten aus der Datenbank)
+ * Mehrfachauswahl durch Bereiche mit der Taste "Shift"; kombinierte Einzelauswahl mit der Taste "Strg"
+ * XML-basierte Konfiguration des Datenkorbs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/README.txt	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,84 @@
+--- Generated by GWT WebAppCreator ---
+
+Congratulations, you've successfully generated a starter project!  What next?
+
+-- Option A: Import your project into Eclipse (recommended) --
+
+If you use Eclipse, you can simply import the generated project into Eclipse.
+We've tested against Eclipse 3.4 and 3.5.  Later versions will likely also
+work, earlier versions may not.
+
+If the directory containing this file does not have a .classpath or .project
+file, generate them by running 'ant eclipse.generate'
+
+In Eclipse, go to the File menu and choose:
+
+  File -> Import... -> Existing Projects into Workspace
+
+  Browse to the directory containing this file,
+  select "FLYS".
+  
+  Be sure to uncheck "Copy projects into workspace" if it is checked.
+  
+  Click Finish.
+  
+You can now browse the project in Eclipse.
+
+To launch your web app in GWT development mode, go to the Run menu and choose:
+
+  Run -> Open Debug Dialog...
+
+  Under Java Application, you should find a launch configuration
+  named "FLYS".  Select and click "Debug".
+
+  You can now use the built-in debugger to debug your web app in development mode.
+
+If you supplied the junit path when invoking webAppCreator, you should see
+launch configurations for running your tests in development and production
+mode.
+
+-- Option B: Build from the command line with Ant --
+
+If you prefer to work from the command line, you can use Ant to build your
+project. (http://ant.apache.org/)  Ant uses the generated 'build.xml' file
+which describes exactly how to build your project.  This file has been tested
+to work against Ant 1.7.1.  The following assumes 'ant' is on your command
+line path.
+
+To run development mode, just type 'ant devmode'.
+
+To compile your project for deployment, just type 'ant'.
+
+To compile and also bundle into a .war file, type 'ant war'.
+
+If you supplied the junit path when invoking webAppCreator, you can type 'ant
+test' to run tests in development and production mode.
+ 
+For a full listing of other targets, type 'ant -p'.
+
+-- Option C: Using another IDE --
+
+GWT projects can be run in other IDEs as well, but will require some manual
+setup.  If you go this route, be sure to:
+
+* Have your IDE build .class files into 'war/WEB-INF/classes'.
+* Add gwt-user.jar and gwt-dev.jar to your project build path.
+* When creating a launch configuration, add a classpath entry for your 'src'
+  folder (this is somewhat unusual but GWT needs access to your source files).
+
+If you get stuck, try to mimic what the Ant 'build.xml' would do.
+
+-- Option D: Using Maven --
+
+If you have generated your project with the option '-maven', you have a 'pom.xml'
+file ready to use. Assuming you have 'maven2' installed in your system, 'mvn' is 
+in your path, and you have access to maven repositories, you should be able to run:
+
+mvn clean         # delete temporary stuff
+mvn test          # run all the tests (gwt and junit)
+mvn gwt:run       # run development mode
+mvn gwt:compile   # compile to javascript
+mvn package       # generate a .war package ready to deploy
+
+For more information about other available goals, read maven and gwt-maven-plugin 
+documentation (http://maven.apache.org, http://mojo.codehaus.org/gwt-maven-plugin)  
Binary file flys-client/doc/Flys-UI-Classes.png has changed
Binary file flys-client/doc/Flys-UI-Services-Classes.png has changed
Binary file flys-client/images/next.xcf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/pom.xml	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <!-- POM file generated with GWT webAppCreator -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.intevation.flys.client</groupId>
+  <artifactId>FLYS</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>de.intevation.flys.client.FLYS</name>
+  
+  <properties>
+      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+      <!-- Convenience property to set the GWT version -->
+      <gwtVersion>2.1.1</gwtVersion>
+      <!-- GWT needs at least java 1.5 -->
+      <maven.compiler.source>1.5</maven.compiler.source>
+      <maven.compiler.target>1.5</maven.compiler.target>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-servlet</artifactId>
+      <version>${gwtVersion}</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-user</artifactId>
+      <version>${gwtVersion}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-dev</artifactId>
+      <version>${gwtVersion}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.smartgwt</groupId>
+      <artifactId>smartgwt</artifactId>
+      <version>2.4</version>
+    </dependency>
+    <dependency>
+      <groupId>de.intevation.artifacts.common</groupId>
+      <artifactId>artifacts-common</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+        <groupId>de.intevation.artifacts.httpclient</groupId>
+        <artifactId>http-client</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+        <groupId>net.sf.opencsv</groupId>
+        <artifactId>opencsv</artifactId>
+        <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.4</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <!-- Generate compiled stuff in the folder used for developing mode --> 
+    <outputDirectory>target/www/WEB-INF/classes</outputDirectory>
+    
+    <plugins>
+      
+      <!-- GWT Maven Plugin-->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>gwt-maven-plugin</artifactId>
+        <!-- JS is only needed in the package phase, this speeds up testing --> 
+        <executions>
+          <execution>
+            <phase>prepare-package</phase>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+          </execution>
+        </executions>
+        <!-- Plugin configuration. There are many available options, 
+             see gwt-maven-plugin documentation at codehaus.org --> 
+        <configuration>
+          <!-- URL that should be automatically opened in the GWT shell (gwt:run). -->
+          <runTarget>FLYS.html</runTarget>
+          <!-- Location of the develop-mode web application structure (gwt:run). -->
+          <hostedWebapp>target/www</hostedWebapp>
+          <!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
+          <soyc>true</soyc>
+        </configuration>
+      </plugin>
+
+      <!-- Add source folders to test classpath in order to run gwt-tests as normal junit-tests -->
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <additionalClasspathElements>
+            <additionalClasspathElement>${project.build.sourceDirectory}</additionalClasspathElement>
+            <additionalClasspathElement>${project.build.testSourceDirectory}</additionalClasspathElement>
+          </additionalClasspathElements>
+          <useManifestOnlyJar>false</useManifestOnlyJar>
+          <forkMode>always</forkMode>
+
+          <!-- Folder for generated testing stuff --> 
+          <systemProperties>
+            <property>
+              <name>gwt.args</name>
+              <value>-out target/www</value>
+            </property>
+          </systemProperties>
+        </configuration>
+      </plugin>
+      
+      <!-- Copy static web files before executing gwt:run -->
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>target/www</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/main/webapp</directory>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Delete gwt generated stuff -->
+      <plugin>
+        <artifactId>maven-clean-plugin</artifactId>
+        <configuration>
+          <filesets>
+            <fileset><directory>src/main/webapp/flys</directory></fileset>
+            <fileset><directory>src/main/webapp/WEB-INF/classes</directory></fileset>
+            <fileset><directory>tomcat</directory></fileset>
+            <fileset><directory>www-test</directory></fileset>
+            <fileset><directory>.gwt-tmp</directory></fileset>
+          </filesets>
+        </configuration>
+      </plugin>
+      
+    </plugins>
+    </build>
+      <repositories>
+        <repository>
+           <id>com.smartgwt</id>
+           <name>SmartGWT</name>
+           <url>http://www.smartclient.com/maven2</url>
+      </repository>
+    </repositories>
+</project>
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/FLYS.gwt.xml	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module rename-to='flys'>
+  <!-- Inherit the core Web Toolkit stuff.                        -->
+  <inherits name='com.google.gwt.user.User'/>
+
+  <!-- Inherit the i18n google stuff.                             -->
+  <inherits name="com.google.gwt.i18n.I18N"/>
+
+  <!-- Inherit the XML stuff of GWT                               -->
+  <inherits name="com.google.gwt.xml.XML"/>
+
+  <!-- Inherit the Resource module of GWT                         -->
+  <inherits name="com.google.gwt.resources.Resources"/>
+
+  <inherits name="de.intevation.artifacts.common.Common"/>
+
+  <!-- Inherit the smartgwt Enterprise Blue Theme.                -->
+  <inherits name="com.smartgwt.SmartGwtNoTheme" />
+  <inherits name="com.smartclient.theme.enterpriseblue.EnterpriseBlue"/>
+  <inherits name="com.smartclient.theme.enterpriseblue.EnterpriseBlueResources"/>
+
+  <!-- Other module inherits                                      -->
+
+  <!-- Specify the app entry point class.                         -->
+  <entry-point class='de.intevation.flys.client.client.FLYS'/>
+
+  <!-- Specify the paths for translatable code                    -->
+  <source path='client'/>
+  <source path='shared'/>
+
+  <extend-property name="locale" values="de,en"/>
+</module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/Config.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,84 @@
+package de.intevation.flys.client.client;
+
+import com.google.gwt.i18n.client.LocaleInfo;
+
+import com.google.gwt.xml.client.Document;
+import com.google.gwt.xml.client.Node;
+
+
+/**
+ * A class that is used to handle the global configuration of this client. You
+ * can retrieve an instance of this class using the <code>getInstance</code>
+ * methods. <b>NOTE:</b> the configuration is initialized using {@link
+ * getInstance(Document)} the first time.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class Config {
+
+    /** The instance of the configuration. */
+    protected static Config INSTANCE;
+
+    /** The xml document that contains the configuration options.*/
+    protected Document config;
+
+
+    /**
+     * Get an instance by using {@link getInstance(Document)} or {@link
+     * getInstance()}.
+     */
+    private Config(Document config) {
+        this.config = config;
+    }
+
+
+    /**
+     * Returns an instance of this class and initializes the configuration of
+     * this has not been done so far.
+     *
+     * @param config The client configuration.
+     *
+     * @return an instance of this Config class.
+     */
+    public static Config getInstance(Document config) {
+        if (INSTANCE == null) {
+            INSTANCE = new Config(config);
+        }
+
+        return INSTANCE;
+    }
+
+
+    /**
+     * Returns an instance of this class. If it has not been initialized with a
+     * valid configuration, null is returned.
+     *
+     * @return an instance of this class or null, if the Config has not been
+     * initialized using {@link getInstance(Document)} so far.
+     */
+    public static Config getInstance() {
+        return INSTANCE;
+    }
+
+
+    /**
+     * Returns the URL of the artifact server.
+     *
+     * @return the artifact server url.
+     */
+    public String getServerUrl() {
+        Node server = config.getElementsByTagName("server").item(0);
+        return server.getFirstChild().getNodeValue();
+    }
+
+
+    /**
+     * Returns the name of the current locale.
+     *
+     * @return the name of the current locale.
+     */
+    public String getLocale() {
+        return LocaleInfo.getCurrentLocale().getLocaleName();
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYS.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,313 @@
+package de.intevation.flys.client.client;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.xml.client.XMLParser;
+
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.CollectionItem;
+import de.intevation.flys.client.shared.model.River;
+import de.intevation.flys.client.shared.model.User;
+
+import de.intevation.flys.client.client.services.ArtifactService;
+import de.intevation.flys.client.client.services.ArtifactServiceAsync;
+import de.intevation.flys.client.client.services.DescribeCollectionService;
+import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync;
+import de.intevation.flys.client.client.services.GetArtifactService;
+import de.intevation.flys.client.client.services.GetArtifactServiceAsync;
+import de.intevation.flys.client.client.services.RiverService;
+import de.intevation.flys.client.client.services.RiverServiceAsync;
+import de.intevation.flys.client.client.services.UserService;
+import de.intevation.flys.client.client.services.UserServiceAsync;
+import de.intevation.flys.client.client.ui.CollectionView;
+import de.intevation.flys.client.client.ui.FLYSHeader;
+import de.intevation.flys.client.client.ui.FLYSView;
+import de.intevation.flys.client.client.ui.FLYSWorkspace;
+import de.intevation.flys.client.client.ui.MainMenu;
+import de.intevation.flys.client.client.ui.ProjectList;
+import de.intevation.flys.client.client.ui.FLYSFooter;
+
+
+/**
+ * Entry point classes define <code>onModuleLoad()</code>.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYS implements EntryPoint {
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    /** The UserService used to retrieve information about the current user. */
+    protected UserServiceAsync userService = GWT.create(UserService.class);
+
+    /** The RiverService used to retrieve the supported rivers of the server.*/
+    protected RiverServiceAsync riverService = GWT.create(RiverService.class);
+
+    /** The ArtifactService used to communicate with the Artifact server. */
+    protected ArtifactServiceAsync artifactService =
+        GWT.create(ArtifactService.class);
+
+    /** The ArtifactService used to communicate with the Artifact server. */
+    protected DescribeCollectionServiceAsync describeCollectionService =
+        GWT.create(DescribeCollectionService.class);
+
+    /** The GetArtifactService used to open an existing collection. */
+    protected GetArtifactServiceAsync getArtifactService =
+        GWT.create(GetArtifactService.class);
+
+
+    /** The menu bar at the top of the application.*/
+    protected MainMenu menu;
+
+    /** The content window. It takes the whole space beneath the menu bar.*/
+    protected FLYSView view;
+
+    /** The project list that displays the projects of the user.*/
+    protected ProjectList projectList;
+
+    /** The FLYSWorkspace.*/
+    protected FLYSWorkspace workspace;
+
+    /** The footer. */
+    protected FLYSFooter footer;
+
+    /** The user who is currently logged in.*/
+    protected User currentUser;
+
+    /** The list of rivers supported by the server.*/
+    protected River[] rivers;
+
+
+    /**
+     * This is the entry point method.
+     */
+    public void onModuleLoad() {
+
+        VLayout vertical = new VLayout();
+        vertical.setLayoutMargin(1);
+        vertical.setWidth100();
+        vertical.setHeight100();
+
+        HLayout spacerBar = new HLayout();
+        spacerBar.setWidth("100%");
+        spacerBar.setHeight("20px");
+        spacerBar.setStyleName("bgBlueLight");
+
+        menu = new MainMenu(this);
+        view = new FLYSView();
+        footer = new FLYSFooter(this);
+
+        vertical.addMember(new FLYSHeader());
+        vertical.addMember(menu);
+        vertical.addMember(spacerBar);
+        vertical.addMember(view);
+        vertical.addMember(footer);
+
+        RootPanel.get("app").add(vertical);
+
+        initConfiguration();
+
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale();
+
+        getRivers();
+
+        userService.getCurrentUser(url, locale, new AsyncCallback<User>() {
+            public void onFailure(Throwable caught) {
+                GWT.log("Could not find a logged in user.");
+                SC.warn(MSG.getString(caught.getMessage()));
+            }
+
+            public void onSuccess(User user) {
+                GWT.log("Found a user. Set '"+ user.getName() + "'");
+                setCurrentUser(user);
+
+                menu.setCurrentUser(user);
+
+                projectList = new ProjectList(FLYS.this, user);
+                workspace   = new FLYSWorkspace();
+                view.setProjectList(projectList);
+                view.setFLYSWorkspace(workspace);
+
+                readRivers();
+            }
+        });
+    }
+
+
+    /**
+     * This method should be called at system start. It initialzes the client
+     * configuration.
+     */
+    protected void initConfiguration() {
+        String xml = FLYSResources.INSTANCE.initialConfiguration().getText();
+        Config.getInstance(XMLParser.parse(xml));
+    }
+
+
+    /**
+     * Returns the user that is currently logged in.
+     *
+     * @return the current user.
+     */
+    public User getCurrentUser() {
+        return currentUser;
+    }
+
+
+    /**
+     * Sets the current user.
+     */
+    public void setCurrentUser(User user) {
+        currentUser = user;
+    }
+
+
+    /**
+     * Returns the project list.
+     */
+    public ProjectList getProjectList() {
+        return projectList;
+    }
+
+
+    /**
+     * Returns a list of rivers supported by the artifact server.
+     *
+     * @return a list of rivers supported by the artifact server.
+     */
+    public River[] getRivers() {
+        return rivers;
+    }
+
+
+    protected void readRivers() {
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale();
+
+        GWT.log("Fetch rivers from server '" + url + "'");
+
+        riverService.list(url, locale, new AsyncCallback<River[]>() {
+            public void onFailure(Throwable caught) {
+                GWT.log("Could not recieve a list of rivers.");
+                SC.warn(MSG.getString(caught.getMessage()));
+            }
+
+            public void onSuccess(River[] newRivers) {
+                GWT.log("Retrieved " + newRivers.length + " new rivers.");
+                rivers = newRivers;
+            }
+        });
+    }
+
+
+    /**
+     * This method creates a new CollectionView and adds it to the workspace.
+     * <b>NOTE</b>The user needs to be logged in and there need to at least one
+     * river - otherwise a warning is displayed and no CollectionView is
+     * created.
+     */
+    public void newProject() {
+        if (getCurrentUser() == null) {
+            SC.warn(MSG.error_not_logged_in());
+            return;
+        }
+
+        if (getRivers() == null) {
+            SC.warn(MSG.error_no_rivers_found());
+            readRivers();
+
+            return;
+        }
+
+        CollectionView view = new CollectionView(this);
+        workspace.addView(view);
+
+        view.addCollectionChangeHandler(getProjectList());
+    }
+
+
+    public void openProject(String collectionID) {
+        if (collectionID == null) {
+            return;
+        }
+
+        GWT.log("Open existing project: " + collectionID);
+
+        Config config       = Config.getInstance();
+        final String url    = config.getServerUrl();
+        final String locale = config.getLocale();
+
+        describeCollectionService.describe(collectionID, url, locale,
+            new AsyncCallback<Collection>() {
+                public void onFailure(Throwable caught) {
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(Collection c) {
+                    final Collection collection = c;
+                    final CollectionItem   item = c.getItem(0);
+
+                    if (item == null) {
+                        SC.warn(MSG.error_load_parameterization());
+                        return;
+                    }
+
+                    getArtifactService.getArtifact(
+                        url,
+                        locale,
+                        item.identifier(),
+                        item.hash(),
+                        new AsyncCallback<Artifact>() {
+                            public void onFailure(Throwable caught) {
+                                SC.warn(MSG.getString(caught.getMessage()));
+                            }
+
+                            public void onSuccess(Artifact artifact) {
+                                CollectionView view = new CollectionView(
+                                    FLYS.this, collection, artifact);
+
+                                view.addCollectionChangeHandler(
+                                    getProjectList());
+
+                                workspace.addView(view);
+                            }
+                    });
+
+                }
+        });
+    }
+
+
+    /**
+     * Create a new Artifact.
+     */
+    public void newArtifact(String factory) {
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale();
+
+        artifactService.create(url, locale, factory,
+            new AsyncCallback<Artifact>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not create the new artifact.");
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(Artifact artifact) {
+                    GWT.log("Successfully created a new artifact.");
+                }
+        });
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,215 @@
+package de.intevation.flys.client.client;
+
+import com.google.gwt.i18n.client.ConstantsWithLookup;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface FLYSConstants extends ConstantsWithLookup {
+
+    String title();
+
+    String fullname();
+
+    String user();
+
+    String guest();
+
+    String projects();
+
+    String open_project();
+
+    String delete_project();
+
+    String manage_projects();
+
+    String logout();
+
+    String switch_language();
+
+    String info();
+
+    String warning();
+
+    String warning_language();
+
+    String no_projects();
+
+    String load_projects();
+
+    String empty_table();
+
+    String date_format();
+
+    String datetime_format();
+
+    String new_project();
+
+    String new_calculation();
+
+    String module_selection();
+
+    String river_selection();
+
+    String winfo();
+
+    String minfo();
+
+    String map();
+
+    String chart();
+
+    String fix();
+
+    String next();
+
+    String river_km();
+
+    String location_distance_state();
+
+    String location();
+
+    String distance();
+
+    String unitFrom();
+
+    String unitTo();
+
+    String unitWidth();
+
+    String unitLocation();
+
+    String wrongFormat();
+
+    String description();
+
+    String from();
+
+    String to();
+
+    String riverside();
+
+    String calcTableTitle();
+
+    String wqTitle();
+
+    String wqadaptedTitle();
+
+    String unitWNN();
+
+    String wqW();
+
+    String wqQ();
+
+    String wqSingle();
+
+    String wqRange();
+
+    String unitWSingle();
+
+    String unitWFrom();
+
+    String unitWTo();
+
+    String unitWStep();
+
+    String unitQSingle();
+
+    String unitQFrom();
+
+    String unitQTo();
+
+    String unitQStep();
+
+    String footerHome();
+
+    String footerContact();
+
+    String footerImpressum();
+
+    String buttonNext();
+
+    String imageBack();
+
+    String imageSave();
+
+    // OUTPUT TYPES
+
+    String discharge_curve();
+
+    String computed_discharge_curve();
+
+    String longitudinal_section();
+
+    String duration_curve();
+
+    String waterlevel_export();
+
+    String name();
+
+    String type();
+
+    String wq_value();
+
+    String discharge_longitudinal_section();
+
+    // EXPORTS
+
+    String dataexport();
+
+    String csv();
+
+    // ERRORS
+
+    String error_create_artifact();
+
+    String error_describe_artifact();
+
+    String error_feed_data();
+
+    String error_advance_artifact();
+
+    String error_add_artifact();
+
+    String error_create_collection();
+
+    String error_describe_collection();
+
+    String error_no_rivers_found();
+
+    String error_no_such_user();
+
+    String error_not_logged_in();
+
+    String error_load_parameterization();
+
+    String error_feed_no_data();
+
+    String error_feed_from_out_of_range();
+
+    String error_feed_to_out_of_range();
+
+    String error_feed_from_bigger_to();
+
+    String error_feed_invalid_wq_mode();
+
+    String error_feed_number_format_float();
+
+    String error_feed_invalid_calculation_mode();
+
+    String error_feed_no_calculation_mode();
+
+    String error_feed_no_such_river();
+
+    String error_feed_no_river_selected();
+
+    String error_feed_no_wq_mode_selected();
+
+    String error_feed_q_values_invalid();
+
+    String error_feed_w_values_invalid();
+
+    String error_no_meta_data_found();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,106 @@
+title = FLYS-3.0
+fullname = Flusshydrologische Software
+user = User:
+guest = guest
+logout = Logout
+projects = Projects
+open_project = Open Project
+delete_project = Delete Project
+manage_projects = Manage Projects
+switch_language = German
+info = Info
+warning = Attention
+warning_language = You go to start a new session when you choose the language.
+no_projects = No existing calculations found.
+load_projects = Load calculations...
+empty_table = Loading data...
+date_format = yyyy-MM-dd
+datetime_format = yyyy-MM-dd HH:mm
+new_project = New Project
+new_calculation = New Calculation
+module_selection = Module
+river_selection = Rivers
+winfo = WINFO
+minfo = MINFO
+map = New Map
+chart = New Chart
+fix = TODO FIX ANALYSE TODO
+next = Next
+location_distance_state = Choose calculation location/range
+location = Location
+distance = Range
+unitFrom = km
+unitTo = km a
+unitWidth = m
+unitLocation = km
+wrongFormat = Wrong format
+description = Description
+from = From
+to = To
+riverside = Riverside
+name = Name
+type = Type
+wq_value = W/Q/D
+river_km = River-Km
+
+wqTitle = Input for W/Q Data
+wqadaptedTitle = Input for W/Q Data
+calcTableTitle = Calculated Output
+wqW = W at Gauge [cm]
+wqQ = Q [m³/s]
+wqSingle = Single values
+wqRange = Range
+unitWNN = W [NN+m]
+unitWSingle = cm
+unitWFrom = cm&nbsp;-
+unitWTo = cm&nbsp;a
+unitWStep = cm
+unitQSingle = m³/s
+unitQFrom = m³/s&nbsp;-
+unitQTo = m³/s&nbsp;a
+unitQStep = m³/s
+footerHome = Home
+footerContact = Kontakt
+footerImpressum = Impressum
+
+buttonNext = Next
+imageBack = images/back_en.png
+imageSave = images/save.gif
+
+discharge_curve = Discharge Curves at Gauges
+computed_discharge_curve = Discharge Curve
+longitudinal_section = Longitudinal Section Curve
+duration_curve = Duration Curve
+waterlevel_export = Waterlevel Export
+discharge_longitudinal_section = Discharge Longitudinal Section
+
+dataexport = Datenexport
+csv = CSV
+
+error_create_artifact = Error while creating new project.
+error_describe_artifact = Error while loading the parameterization.
+error_feed_data = Error while inserting new data.
+error_advance_artifact = Error while changing the project's state.
+error_add_artifact = Error while inserting new data.
+error_create_collection = Error while creating a new collection.
+error_describe_collection = Error while fetching the projects state.
+error_no_rivers_found = Error while reading supported rivers.
+error_no_such_user = Error - no such user found.
+error_not_logged_in = You need to log in before you are allowed to start your work.
+error_load_parameterization = Could not load the parameterization.
+
+error_feed_no_data = No input data found.
+error_feed_from_out_of_range = The lower value is bigger than the upper value.
+error_feed_to_out_of_range = The upper value is out or the valid range.
+error_feed_from_bigger_to = The lower value is bigger than the upper value.
+error_feed_invalid_wq_mode = Invalid WQ-Mode selected.
+error_feed_number_format_float = The inserted value is no floating point number.
+error_feed_invalid_calculation_mode = The chosen calculation method is invalid.
+error_feed_no_calculation_mode = No calculation method chosen.
+error_feed_no_such_river = The selected river is not provided.
+error_feed_no_river_selected = No river selected.
+error_feed_no_wq_mode_selected = No W/Q mode selected.
+error_feed_q_values_invalid = Selected Q values are outside the valid range.
+error_feed_w_values_invalid = Selected W values are outside the valid range.
+
+error_no_meta_data_found = No meta data found.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,106 @@
+title = FLYS-3.0
+fullname = Flusshydrologische Software
+user = Benutzer:
+guest = Gast
+logout = Abmelden
+projects = Projekte
+open_project = Projekt \u00d6ffnen
+delete_project = Projekt l\u00f6schen
+manage_projects = Projekte verwalten
+switch_language = Englisch
+info = Info
+warning = Achtung
+warning_language = Das \u00c4ndern der Sprache startet eine neue Sitzung des Programms. Alle offenen Fenster werden geschlossen.
+no_projects = Keine alten Berechnungen gefunden.
+load_projects = Lade Berechnungen...
+empty_table = Lade Daten...
+date_format = dd.MM.yyyy
+datetime_format = dd.MM.yyyy HH:mm
+new_project = Neues Projekt
+new_calculation = Neue Berechnung
+module_selection = Modul
+river_selection = Gewässer
+winfo = WINFO
+minfo = MINFO
+map = Neue Karte
+chart = Neues Diagramm
+fix = Fixierungsanalyse
+next = Weiter
+location_distance_state = Berechnungsort/strecke wählen
+location = Ort
+distance = Strecke
+unitFrom = km&nbsp;-
+unitTo = km a
+unitWidth = m
+unitLocation = km
+wrongFormat = Falsches Format
+description = Beschreibung
+from = von
+to = bis
+riverside = Flussseite
+name = Name
+type = Typ
+wq_value = W/Q/D
+river_km = Fluss-Km
+
+wqTitle = Eingabe für W/Q Daten
+wqadaptedTitle = Eingabe für W/Q Daten
+calcTableTitle = Berechnungsausgabe
+wqW = W am Pegel [cm]
+wqQ = Q [m³/s]
+wqSingle = Einzelwerte
+wqRange = Wertebereich
+unitWNN = W [NN+m]
+unitWSingle = cm
+unitWFrom = cm&nbsp;-
+unitWTo = cm&nbsp;a
+unitWStep = cm
+unitQSingle = m³/s
+unitQFrom = m³/s&nbsp;-
+unitQTo = m³/s&nbsp;a
+unitQStep = m³/s
+footerHome = Home
+footerContact = Kontakt
+footerImpressum = Impressum
+
+buttonNext = Ãœbernehmen
+imageBack = images/back_de.png
+imageSave = images/save.gif
+
+discharge_curve = Abflusskurven an Pegeln
+computed_discharge_curve = Abflusskurve
+longitudinal_section = L\u00e4ngsschnitt
+duration_curve = Dauerlinie
+waterlevel_export = Wasserstand/Wasserspiegellagen Export
+discharge_longitudinal_section = W bei ungleichwertigem Abflussl\u00e4ngsschnitt
+
+dataexport = Datenexport
+csv = CSV
+
+error_create_artifact = Fehler beim Erstellen eines neuen Projekts.
+error_describe_artifact = Fehler beim Laden der Parametrisierung.
+error_feed_data = Fehler beim Hinzuf\u00fcgen neuer Daten.
+error_advance_artifact = Fehler beim Wechseln des Zustands des Projektes.
+error_add_artifact = Fehler beim Hinzuf\u00fcgen neuer Daten.
+error_create_collection = Fehler beim Erstellen einer neuen Collection.
+error_describe_collection = Fehler beim Laden des Projektzustandes.
+error_no_rivers_found = Fehler beim Lesen der unterst\u00fctzten Fl\u00fcsse.
+error_no_such_user = Fehler - Kein Benutzer vorhanden.
+error_not_logged_in = Sie m\u00fcssen sich erst einloggen um mit der Arbeit beginnen zu k\u00f6nnen.
+error_load_parameterization = Fehler beim Laden der Parametrisierung.
+
+error_feed_no_data = Keine Eingabedaten gefunden.
+error_feed_from_out_of_range = Der untere Wert liegt au\u00dferhalb des g\u00fcltigen Wertebereiches.
+error_feed_to_out_of_range = Der obere Wert liegt au\u00dferhalb des g\u00fcltigen Wertebereiches.
+error_feed_from_bigger_to = Der untere Wert ist gr\u00f6\u00dfer als der obere Wert.
+error_feed_invalid_wq_mode = Ung\u00fcltiger Modus f\u00fcr die WQ-Eingabe gew\u00e4hlt.
+error_feed_number_format_float = Der eingegebene Wert ist keine Flie\u00dfkommazahl.
+error_feed_invalid_calculation_mode = Die gew\u00e4hlte Berechnungsart ist ung\u00fcltig.
+error_feed_no_calculation_mode = Es ist keine Berechnungsart gew\u00e4hlt.
+error_feed_no_such_river = Der gew\u00e4hlte Fluss wird nicht unterst\u00fctzt.
+error_feed_no_river_selected = Es wurde kein Fluss gew\u00e4hlt.
+error_feed_no_wq_mode_selected = Es ist kein W/Q Modus gew\u00e4hlt.
+error_feed_q_values_invalid = Die gew\u00e4hlten Q Werte liegen au\u00dferhalb des g\u00fcltigen Bereiches.
+error_feed_w_values_invalid = Die gew\u00e4hlten W Werte liegen au\u00dferhalb des g\u00fcltigen Bereiches.
+
+error_no_meta_data_found = Keine Meta-Daten gefunden.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,97 @@
+title = FLYS-3.0
+fullname = Flusshydrologische Software
+user = User:
+guest = guest
+logout = Logout
+projects = Projects
+open_project = Open Project
+delete_project = Delete Project
+manage_projects = Manage Projects
+switch_language = German
+info = Info
+warning = Attention
+warning_language = You go to start a new session when you choose the language.
+no_projects = No existing calculations found.
+load_projects = Load calculations...
+empty_table = Loading data...
+date_format = yyyy-MM-dd
+datetime_format = yyyy-MM-dd HH:mm
+new_project = New Project
+new_calculation = New Calculation
+module_selection = Module
+river_selection = Rivers
+winfo = WINFO
+minfo = MINFO
+map = New Map
+chart = New Chart
+fix = TODO FIX ANALYSE TODO
+next = Next
+location_distance_state = Choose calculation location/range
+location = Location
+distance = Range
+unitFrom = km
+unitTo = km a
+unitWidth = m
+unitLocation = km
+wrongFormat = Wrong format
+description = Description
+from = From
+to = To
+riverside = Riverside
+name = Name
+type = Type
+wq_value = W/Q/D
+river_km = River-Km
+
+wqTitle = Input for W/Q Data
+wqadaptedTitle = Input for W/Q Data
+calcTableTitle = Calculated Output
+wqW = W at Gauge [cm]
+wqQ = Q [m³/s]
+wqSingle = Single values
+wqRange = Range
+untiWNN = W [NN+m]
+unitWSingle = cm
+unitWFrom = cm&nbsp;-
+unitWTo = cm&nbsp;a
+unitWStep = cm
+unitQSingle = m³/s
+unitQFrom = m³/s&nbsp;-
+unitQTo = m³/s&nbsp;a
+unitQStep = m³/s
+footerHome = Home
+footerContact = Kontakt
+footerImpressum = Impressum
+
+buttonNext = Next
+imageBack = images/back_en.png
+
+discharge_curve = Discharge Curves at Gauges
+computed_discharge_curve = Discharge Curve
+longitudinal_section = Longitudinal Section Curve
+duration_curve = Duration Curve
+waterlevel_export = Waterlevel Export
+discharge_longitudinal_section = Discharge Longitudinal Section
+
+error_create_artifact = Error while creating new project.
+error_describe_artifact = Error while loading the parameterization.
+error_feed_data = Error while inserting new data.
+error_advance_artifact = Error while changing the project's state.
+error_add_artifact = Error while inserting new data.
+error_create_collection = Error while creating a new collection.
+error_describe_collection = Error while fetching the projects state.
+error_no_rivers_found = Error while reading supported rivers.
+error_no_such_user = Error - no such user.
+error_not_logged_in = You need to log in before you are allowed to start your work.
+error_load_parameterization = Could not load the parameterization.
+
+error_feed_no_data = No input data found.
+error_feed_from_out_of_range = The lower value is bigger than the upper value.
+error_feed_to_out_of_range = The upper value is out or the valid range.
+error_feed_from_bigger_to = The lower value is bigger than the upper value.
+error_feed_invalid_wq_mode = Invalid WQ-Mode selected.
+error_feed_number_format_float = The inserted value is no floating point number.
+error_feed_invalid_calculation_mode = The chosen calculation method is invalid.
+error_feed_no_calculation_mode = No calculation method chosen.
+error_feed_no_such_river = The selected river is not provided.
+error_feed_no_river_selected = No river selected.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSImages.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,28 @@
+package de.intevation.flys.client.client;
+
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+
+
+/**
+ * This interface grants access to the images used in this application.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface FLYSImages extends ClientBundle {
+
+    @Source("images/bfg_logo.gif")
+    ImageResource logoBfg();
+
+    @Source("images/flys_logo.gif")
+    ImageResource logoFlys();
+
+    @Source("images/gewkarte.png")
+    ImageResource riverMap();
+
+    @Source("images/marker_red.png")
+    ImageResource markerRed ();
+
+    @Source("images/marker_green.png")
+    ImageResource markerGreen ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSResources.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.client.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.TextResource;
+
+
+/**
+ * A {@link ClientBundle} that is used to handle resources in this client.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface FLYSResources extends ClientBundle {
+
+    public static final FLYSResources INSTANCE =
+        GWT.create(FLYSResources.class);
+
+        @Source("config.xml")
+        public TextResource initialConfiguration();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/config.xml	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,3 @@
+<config>
+    <server>http://localhost:8181</server>
+</config>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/CollectionChangeEvent.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,29 @@
+package de.intevation.flys.client.client.event;
+
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This events stores references to the old collection and the new one.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class CollectionChangeEvent {
+
+    protected Collection oldCollection;
+    protected Collection newCollection;
+
+    public CollectionChangeEvent(Collection old, Collection newArt) {
+        oldCollection = old;
+        newCollection = newArt;
+    }
+
+    public Collection getOldValue() {
+        return oldCollection;
+    }
+
+    public Collection getNewValue() {
+        return newCollection;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/CollectionChangeHandler.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,18 @@
+package de.intevation.flys.client.client.event;
+
+
+/**
+ * Handler interface for CollectionChangeEvent events.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface CollectionChangeHandler {
+
+    /**
+     * Called when a CollectionChangeEvent is fired.
+     *
+     * @param event The CollectionChangeEvent.
+     */
+    public void onCollectionChange(CollectionChangeEvent event);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasCollectionChangeHandlers.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,16 @@
+package de.intevation.flys.client.client.event;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface HasCollectionChangeHandlers {
+
+    /**
+     * Adds a new CollectionChangeHandler.
+     *
+     * @param handler The new CollectionChangeHandler.
+     */
+    public void addCollectionChangeHandler(CollectionChangeHandler handler);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasParameterChangeHandler.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,16 @@
+package de.intevation.flys.client.client.event;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface HasParameterChangeHandler {
+
+    /**
+     * Adds a new ParameterChangeHandler.
+     *
+     * @param handler The new ParameterChangeHandler.
+     */
+    public void addParameterChangeHandler(ParameterChangeHandler handler);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasStepBackHandlers.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,13 @@
+package de.intevation.flys.client.client.event;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface HasStepBackHandlers extends Serializable {
+
+    public void addStepBackHandler(StepBackHandler handler);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/HasStepForwardHandlers.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,13 @@
+package de.intevation.flys.client.client.event;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface HasStepForwardHandlers extends Serializable {
+
+    public void addStepForwardHandler(StepForwardHandler handler);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/ParameterChangeEvent.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,29 @@
+package de.intevation.flys.client.client.event;
+
+import de.intevation.flys.client.shared.model.Artifact;
+
+
+/**
+ * This events stores references to the old artifact and the new one.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ParameterChangeEvent {
+
+    protected Artifact oldArtifact;
+    protected Artifact newArtifact;
+
+    public ParameterChangeEvent(Artifact old, Artifact newArt) {
+        oldArtifact = old;
+        newArtifact = newArt;
+    }
+
+    public Artifact getOldValue() {
+        return oldArtifact;
+    }
+
+    public Artifact getNewValue() {
+        return newArtifact;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/ParameterChangeHandler.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,18 @@
+package de.intevation.flys.client.client.event;
+
+
+/**
+ * Handler interface for ParameterChangeEvent events.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface ParameterChangeHandler {
+
+    /**
+     * Called when a ParameterChangeEvent is fired.
+     *
+     * @param event The ParameterChangeEvent.
+     */
+    public void onParameterChange(ParameterChangeEvent event);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepBackEvent.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,34 @@
+package de.intevation.flys.client.client.event;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class StepBackEvent implements Serializable {
+
+    /** The identifier of the target state.*/
+    protected String target;
+
+
+    /**
+     * Creates a new StepBackEvent with the identifier of the target state.
+     *
+     * @param target The identifier of the target state.
+     */
+    public StepBackEvent(String target) {
+        this.target = target;
+    }
+
+
+    /**
+     * A method to retrieve the target identifier.
+     *
+     * @return the target identifier.
+     */
+    public String getTarget() {
+        return target;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepBackHandler.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,13 @@
+package de.intevation.flys.client.client.event;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface StepBackHandler extends Serializable {
+
+    public void onStepBack(StepBackEvent event);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepForwardEvent.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,36 @@
+package de.intevation.flys.client.client.event;
+
+import java.io.Serializable;
+
+import de.intevation.flys.client.shared.model.Data;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class StepForwardEvent implements Serializable {
+
+    /** The selected data.*/
+    protected Data[] data;
+
+    /**
+     * Creates a new StepForwardEvent with the Data that has been selected in
+     * the UI.
+     *
+     * @param data The selected data.
+     */
+    public StepForwardEvent(Data[] data) {
+        this.data = data;
+    }
+
+
+    /**
+     * A method to retrieve the data stored in the event.
+     *
+     * @return the data.
+     */
+    public Data[] getData() {
+        return data;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/event/StepForwardHandler.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,13 @@
+package de.intevation.flys.client.client.event;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface StepForwardHandler extends Serializable {
+
+    public void onStepForward(StepForwardEvent event);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/bfg_logo.gif has changed
Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/flys_logo.gif has changed
Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/gewkarte.png has changed
Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/marker_green.png has changed
Binary file flys-client/src/main/java/de/intevation/flys/client/client/images/marker_red.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AddArtifactService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,36 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This interface describes the service to add an existing artifact to an
+ * existing collection.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("add-artifact")
+public interface AddArtifactService extends RemoteService {
+
+    /**
+     * Adds an artifact to a collection.
+     *
+     * @param collection The Collection that should be extended.
+     * @param artifact   The artifact that should be added.
+     * @param url        The url of the artifact server.
+     *
+     * @return the Collection after the operation.
+     */
+    Collection add(
+        Collection collection,
+        Artifact   artifact,
+        String     url,
+        String     locale)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AddArtifactServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface AddArtifactServiceAsync {
+
+    public void add(
+        Collection collection,
+        Artifact   artifact,
+        String     url,
+        String     locale,
+        AsyncCallback<Collection> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AdvanceService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,34 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+
+/**
+ * This interface provides artifact specific operation ADVANCE.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("advance")
+public interface AdvanceService extends RemoteService {
+
+    /**
+     * This method inserts new data into the an existing artifact.
+     *
+     * @param serverUrl The url of the artifact server.
+     * @param locale The locale used for the request.
+     * @param artifact The artifact.
+     * @param target The identifier of the target state.
+     *
+     * @return the artifact which description might have been changed.
+     */
+    public Artifact advance(
+        String   serverUrl,
+        String   locale,
+        Artifact artifact,
+        String   target)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/AdvanceServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,22 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Artifact;
+
+
+/**
+ * This interface provides artifact specific operation ADVANCE.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface AdvanceServiceAsync {
+
+    public void advance(
+        String                  serverUrl,
+        String                  locale,
+        Artifact                artifact,
+        String                  target,
+        AsyncCallback<Artifact> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,30 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+
+/**
+ * This interface provides artifact specific services as CREATE, DESCRIBE, FEED,
+ * ADVANCE and OUT.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("artifact")
+public interface ArtifactService extends RemoteService {
+
+    /**
+     * This method creates a new artifact based on the given <i>factory</i>.
+     *
+     * @param serverUrl The url of the artifact server.
+     * @param locale The locale used for the request.
+     * @param factory The factory that should be used for the artifact creation.
+     *
+     * @return the new artifact.
+     */
+    public Artifact create(String serverUrl, String locale, String factory)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,22 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Artifact;
+
+
+/**
+ * This interface provides artifact specific services as CREATE, DESCRIBE, FEED,
+ * ADVANCE and OUT.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface ArtifactServiceAsync {
+
+    public void create(
+        String serverUrl,
+        String locale,
+        String factory,
+        AsyncCallback<Artifact> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/CSVExportService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,29 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import java.util.List;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+
+/**
+ * This service is used to fetch a list of DistanceInfoObjects from artifact
+ * server for a specific river.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+@RemoteServiceRelativePath("csv")
+public interface CSVExportService extends RemoteService {
+
+    /**
+     * This method returns a list of DistanceInfoObjects for a specific river.
+     */
+    List getCSV(
+        String serverUrl,
+        String locale,
+        String uuid,
+        String name)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/CSVExportServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,19 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public interface CSVExportServiceAsync {
+
+    void getCSV(
+        String url,
+        String locale,
+        String uuid,
+        String name,
+        AsyncCallback<List> cb);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/CreateCollectionService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,27 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This interface describes the service for creating new collections.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("create-collection")
+public interface CreateCollectionService extends RemoteService {
+
+    /**
+     * This method creates a new collection in the artifact server and returns
+     * the uuid of this collection.
+     *
+     * @return the uuid of the created collection.
+     */
+    Collection create(String serverUrl, String locale, String ownerId)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/CreateCollectionServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This interface describes the service for creating new collections.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface CreateCollectionServiceAsync {
+
+    void create(
+        String serverUrl,
+        String locale,
+        String owner,
+        AsyncCallback<Collection> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/DescribeCollectionService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,31 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This service describes an operation the fetches the DESCRIBE document of a
+ * specific collection and returns a Collection.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("describe-collection")
+public interface DescribeCollectionService extends RemoteService {
+
+    /**
+     * Adds an artifact to a collection.
+     *
+     * @param uuid The uuid of the desired collection.
+     * @param url  The url of the artifact server.
+     * @param locale The name of the locale used for the request.
+     *
+     * @return the Collection after the operation.
+     */
+    Collection describe(String uuid, String url, String locale)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/DescribeCollectionServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,19 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface DescribeCollectionServiceAsync {
+
+    public void describe(
+        String uuid,
+        String url,
+        String locale,
+        AsyncCallback<Collection> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/DistanceInfoService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,27 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.DistanceInfoObject;
+
+/**
+ * This service is used to fetch a list of DistanceInfoObjects from artifact
+ * server for a specific river.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("distanceinfo")
+public interface DistanceInfoService extends RemoteService {
+
+    /**
+     * This method returns a list of DistanceInfoObjects for a specific river.
+     */
+    DistanceInfoObject[] getDistanceInfo(
+        String serverUrl,
+        String locale,
+        String river)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/DistanceInfoServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,19 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.DistanceInfoObject;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface DistanceInfoServiceAsync {
+
+    void getDistanceInfo(
+        String url,
+        String locale,
+        String river,
+        AsyncCallback<DistanceInfoObject[]> cb);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/GetArtifactService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,31 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+
+/**
+ * This interface provides a method to retrieve an artifact based on its uuid.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("getartifact")
+public interface GetArtifactService extends RemoteService {
+
+    /**
+     * This method inserts new data into the an existing artifact.
+     *
+     * @param url The url of the artifact server.
+     * @param locale The string representation of a locale that is used for the
+     * request.
+     * @param uuid The artifact's identifier.
+     * @param hash The artifact's hash.
+     *
+     * @return the artifact.
+     */
+    Artifact getArtifact(String url, String locale, String uuid, String hash)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/GetArtifactServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,20 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Artifact;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface GetArtifactServiceAsync {
+
+    public void getArtifact(
+        String                  serverUrl,
+        String                  locale,
+        String                  uuid,
+        String                  hash,
+        AsyncCallback<Artifact> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/MetaDataService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,18 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+
+import de.intevation.flys.client.shared.model.DataCageTree;
+
+@RemoteServiceRelativePath("meta-data")
+public interface MetaDataService extends RemoteService
+{
+    DataCageTree getMetaData(String serverUrl, String locale, String name)
+        throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/MetaDataServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,16 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.DataCageTree;
+
+public interface MetaDataServiceAsync {
+    void getMetaData(
+        String              serverUrl,
+        String              locale,
+        String              name, 
+        AsyncCallback<DataCageTree> cb);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/RiverService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,29 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.River;
+
+/**
+ * This interface provides a method to list the supported rivers of the artifact
+ * server.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("rivers")
+public interface RiverService extends RemoteService {
+
+    /**
+     * This method returns a list of rivers provided by the artifact server.
+     *
+     * @param serverUrl The url of the artifact server.
+     * @param locale The locale used for the request.
+     *
+     * @return a list of rivers provided by the artifact server.
+     */
+    public River[] list(String serverUrl, String locale)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/RiverServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.River;
+
+
+/**
+ * This interface provides a method to list the supported rivers of the artifact
+ * server.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface RiverServiceAsync {
+
+    public void list(
+        String serverUrl,
+        String locale,
+        AsyncCallback<River[]> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/StepForwardService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,35 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Data;
+
+/**
+ * This interface provides artifact specific operation FEED.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("forward")
+public interface StepForwardService extends RemoteService {
+
+    /**
+     * This method inserts new data into the an existing artifact.
+     *
+     * @param serverUrl The url of the artifact server.
+     * @param locale The locale used for the request.
+     * @param artifact The artifact.
+     * @param data The data that should be inserted.
+     *
+     * @return the artifact which description might have been changed.
+     */
+    public Artifact go(
+        String   serverUrl,
+        String   locale,
+        Artifact artifact,
+        Data[]   data)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/StepForwardServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,23 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Data;
+
+
+/**
+ * This interface provides artifact specific operation FEED.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface StepForwardServiceAsync {
+
+    public void go(
+        String                  serverUrl,
+        String                  locale,
+        Artifact                artifact,
+        Data[]                  data,
+        AsyncCallback<Artifact> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserCollectionsService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,32 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This interface describes a method that retrieves a list of Collections owned
+ * by a specified user.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("user-collections")
+public interface UserCollectionsService extends RemoteService {
+
+    /**
+     * This method retrieves the user that is currently logged in.
+     *
+     * @param serverUrl The url of the artifact server.
+     * @param locale The locale used for the request object.
+     * @param userid The identifier of the owner.
+     *
+     * @return the current {@link User}.
+     */
+    Collection[] getUserCollections(
+        String serverUrl,
+        String locale,
+        String userid);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserCollectionsServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,22 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Collection;
+
+
+/**
+ * This interface describes a method that retrieves a list of Collections owned
+ * by a specified user.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface UserCollectionsServiceAsync {
+
+    void getUserCollections(
+        String serverUrl,
+        String locale,
+        String userid,
+        AsyncCallback<Collection[]> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,28 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.AuthenticationException;
+import de.intevation.flys.client.shared.model.User;
+
+
+/**
+ * This interface describes services for the user.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+@RemoteServiceRelativePath("user")
+public interface UserService extends RemoteService {
+
+    /**
+     * This method retrieves the user that is currently logged in.
+     *
+     * @param serverUrl The url of the artifact server.
+     *
+     * @return the current {@link User}.
+     */
+    User getCurrentUser(String serverUrl, String locale)
+    throws AuthenticationException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/UserServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,20 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.User;
+
+
+/**
+ * This interface describes services for the user.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface UserServiceAsync {
+
+    void getCurrentUser(
+        String serverUrl,
+        String locale,
+        AsyncCallback<User> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/WQInfoService.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,29 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.WQInfoObject;
+
+/**
+ * This service is used to fetch a list of DistanceInfoObjects from artifact
+ * server for a specific river.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+@RemoteServiceRelativePath("mainvalues")
+public interface WQInfoService extends RemoteService {
+
+    /**
+     * This method returns a list of DistanceInfoObjects for a specific river.
+     */
+    WQInfoObject[] getWQInfo(
+        String serverUrl,
+        String locale,
+        String river,
+        double start,
+        double end)
+    throws ServerException;
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/WQInfoServiceAsync.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.WQInfoObject;
+
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public interface WQInfoServiceAsync {
+
+    void getWQInfo(
+        String url,
+        String locale,
+        String river,
+        double start,
+        double end,
+        AsyncCallback<WQInfoObject[]> cb);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,238 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.Button;
+
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.event.HasStepBackHandlers;
+import de.intevation.flys.client.client.event.HasStepForwardHandlers;
+import de.intevation.flys.client.client.event.StepBackEvent;
+import de.intevation.flys.client.client.event.StepBackHandler;
+import de.intevation.flys.client.client.event.StepForwardEvent;
+import de.intevation.flys.client.client.event.StepForwardHandler;
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.Artifact;
+
+/**
+ * An abstract UIProvider that provides some basic methods.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public abstract class AbstractUIProvider
+implements   UIProvider, HasStepForwardHandlers, ClickHandler,
+             HasStepBackHandlers
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+
+    /** The StepForwardHandlers.*/
+    protected List<StepForwardHandler> forwardHandlers;
+
+    /** The StepForwardHandlers.*/
+    protected List<StepBackHandler> backHandlers;
+
+    /** The container that is used to position helper widgets.*/
+    protected Canvas helperContainer;
+
+    /** The artifact that contains status information.*/
+    protected Artifact artifact;
+
+    /**
+     * Creates a new UIProvider instance of this class.
+     */
+    public AbstractUIProvider() {
+        forwardHandlers = new ArrayList<StepForwardHandler>();
+        backHandlers    = new ArrayList<StepBackHandler>();
+    }
+
+
+    /**
+     * Appends a StepBackHandler that wants to listen to StepBackEvents.
+     *
+     * @param handler A new StepBackHandler.
+     */
+    public void addStepBackHandler(StepBackHandler handler) {
+        if (handler != null) {
+            backHandlers.add(handler);
+        }
+    }
+
+
+    /**
+     * Appends a StepForwardHandler that wants to listen to StepForwardEvents.
+     *
+     * @param handler A new StepForwardHandler.
+     */
+    public void addStepForwardHandler(StepForwardHandler handler) {
+        if (handler != null) {
+            forwardHandlers.add(handler);
+        }
+    }
+
+
+    /**
+     * This method is called after the user has clicked one of the buttons to
+     * step back to a previous state.
+     *
+     * @param e The StepBackEvent.
+     */
+    protected void fireStepBackEvent(StepBackEvent e) {
+        GWT.log("AbstractUIProvider - fireStepBackEvent() handlers: " + backHandlers.size());
+        for (StepBackHandler handler: backHandlers) {
+            handler.onStepBack(e);
+        }
+    }
+
+
+    /**
+     * This method is called after the user has clicked on the 'next' button to
+     * step to the next state.
+     *
+     * @param e The StepForwardEvent.
+     */
+    protected void fireStepForwardEvent(StepForwardEvent e) {
+        GWT.log("AbstractUIProvider - fireStepForwardEvent() handlers: " + forwardHandlers.size());
+        for (StepForwardHandler handler: forwardHandlers) {
+            handler.onStepForward(e);
+        }
+    }
+
+
+    /**
+     * This method is used to listen to click events on the 'next' button. The
+     * fireStepForwardEvent() method is called here.
+     *
+     * @param e The click event.
+     */
+    public void onClick(ClickEvent e) {
+        Data[] data = getData();
+
+        fireStepForwardEvent(new StepForwardEvent(data));
+    }
+
+
+    /**
+     * Creates the 'next' button to step forward to the next state.
+     *
+     * @return the 'next' button.
+     */
+    protected Canvas getNextButton() {
+        Button next = new Button(MSG.buttonNext());
+        next.addClickHandler(this);
+
+        return next;
+    }
+
+
+    /**
+     * Creates the 'back' button to step back to a previous state.
+     *
+     * @param targetState The identifier of the target state.
+     *
+     * @return the 'back' button.
+     */
+    protected Canvas getBackButton(final String targetState) {
+        String url = GWT.getHostPageBaseURL() + MSG.imageBack();
+        Img back   = new Img(url, 16, 16);
+
+        back.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                fireStepBackEvent(new StepBackEvent(targetState));
+            }
+        });
+
+        return back;
+    }
+
+
+    /**
+     * This method injects a container that is used to position helper widgets.
+     *
+     * @param helperContainer A container that is used to position helper
+     * widgets.
+     */
+    public void setContainer(Canvas helperContainer) {
+        this.helperContainer = helperContainer;
+    }
+
+
+    /**
+     * This method injects an artifact that contains the status information.
+     *
+     * @param art An artifact containing status information.
+     */
+    public void setArtifact(Artifact art) {
+        this.artifact = art;
+    }
+
+
+    /**
+     * This method greps the Data with name <i>name</i> from the list and
+     * returns it.
+     *
+     * @param items A list of Data.
+     * @param name The name of the Data that we are searching for.
+     *
+     * @return the Data with the name <i>name</i>.
+     */
+    protected Data getData(List<Data> data, String name) {
+        for (Data d: data) {
+            if (name.equals(d.getLabel())) {
+                return d;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * This method greps the DataItem with name <i>name</i> from the list and
+     * returns it.
+     *
+     * @param items A list of DataItems.
+     * @param name The name of the DataItem that we are searching for.
+     *
+     * @return the DataItem with the name <i>name</i>.
+     */
+    protected DataItem getDataItem(DataItem[] items, String name) {
+        for (DataItem item: items) {
+            if (name.equals(item.getLabel())) {
+                return item;
+            }
+        }
+
+        return null;
+    }
+
+
+    /**
+     * This method needs to be implemented by concrete subclasses. It should
+     * create a new Canvas object with a representation of <i>data</i>.
+     *
+     * @param data The data that should be displayed.
+     *
+     * @return a Canvas object that displays <i>data</i>.
+     */
+    public abstract Canvas create(DataList data);
+
+
+    /**
+     * This method needs to be implemented by concrete subclasses. It should
+     * return the selected data.
+     *
+     * @return the selected data.
+     */
+    protected abstract Data[] getData();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ChartOutputTab.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,213 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.Alignment;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.IButton;
+
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.events.CloseClickHandler;
+import com.smartgwt.client.widgets.events.CloseClientEvent;
+import com.smartgwt.client.widgets.events.ResizedEvent;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.OutputMode;
+import de.intevation.flys.client.client.Config;
+
+import de.intevation.flys.client.shared.model.Artifact;
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ChartOutputTab extends OutputTab implements ResizedHandler {
+
+    public static final int DEFAULT_CHART_WIDTH  = 600;
+    public static final int DEFAULT_CHART_HEIGHT = 500;
+
+    /** The canvas that wraps the chart toolbar.*/
+    protected Canvas tbarPanel;
+
+    /** The canvas that wraps the theme editor.*/
+    protected Canvas left;
+
+    /** The canvas that wraps the chart.*/
+    protected Canvas right;
+
+
+    /**
+     * The default constructor to create a new ChartOutputTab.
+     *
+     * @param title The title of this tab.
+     * @param collection The Collection which this chart belongs to.
+     * @param mode The OutputMode.
+     */
+    public ChartOutputTab(
+        String         title, 
+        Collection     collection,
+        OutputMode     mode,
+        CollectionView collectionView
+    ){
+        super(title, collection, mode);
+
+        tbarPanel = new Canvas();
+        left      = new Canvas();
+        right     = new Canvas();
+
+        tbarPanel.setBorder("1px solid black");
+        tbarPanel.setHeight(30);
+        left.setBorder("1px solid black");
+        left.setWidth("25%");
+        right.setWidth("*");
+
+        VLayout vLayout = new VLayout();
+        vLayout.setMembersMargin(2);
+
+        HLayout hLayout = new HLayout();
+        hLayout.setWidth100();
+        hLayout.setHeight100();
+        hLayout.setMembersMargin(10);
+
+        hLayout.addMember(left);
+        hLayout.addMember(right);
+
+        right.addChild(createChartPanel());
+        left.addChild(createThemeControlPanel());
+        tbarPanel.addChild(
+            createTBarPanel(collectionView));
+
+        vLayout.addMember(tbarPanel);
+        vLayout.addMember(hLayout);
+
+        setPane(vLayout);
+
+        right.addResizedHandler(this);
+    }
+
+
+    /**
+     * This method is called after the chart panel has resized. It removes the
+     * chart - if existing - and requests a new one with adjusted size.
+     *
+     * @param event The resize event.
+     */
+    public void onResized(ResizedEvent event) {
+        Canvas[] children = right.getChildren();
+        for (Canvas child: children) {
+            right.removeChild(child);
+        }
+
+        right.addChild(createChartPanel(right.getWidth(), right.getHeight()));
+    }
+
+
+    protected Canvas createTBarPanel(
+        final CollectionView collectionView
+    ) {
+        HLayout hLayout = new HLayout();
+        hLayout.setWidth100();
+        hLayout.setHeight100();
+        hLayout.setMembersMargin(10);
+
+        Label datacage = new Label("Datenkorb");
+        datacage.setHeight(20);
+        datacage.setBackgroundColor("#BED730");
+        datacage.setBorder("1px solid black");
+        datacage.setAlign(Alignment.CENTER);
+
+        hLayout.setMargin(5);
+        hLayout.addMember(datacage);
+        datacage.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                GWT.log("Clicked 'datacage' button.");
+                openDatacageWindow(
+                    collectionView.getArtifact());
+            }
+        });
+
+        return hLayout;
+    }
+
+    protected void openDatacageWindow(Artifact artifact) {
+        final DatacageWindow dc = new DatacageWindow(artifact);
+        dc.addCloseClickHandler(new CloseClickHandler() {
+            public void onCloseClick(CloseClientEvent event) {
+                dc.destroy();
+            }
+        });
+        dc.show();
+    }
+
+
+    protected Canvas createChartPanel() {
+        return createChartPanel(DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT);
+    }
+
+
+    protected Canvas createChartPanel(int width, int height) {
+        Img chart  = getChartImg(width, height);
+        chart.setWidth100();
+        chart.setHeight100();
+
+        return chart;
+
+    }
+
+
+    protected Canvas createThemeControlPanel() {
+        Label label = new Label("Themensteuerung");
+        label.setHeight(25);
+        label.setMargin(5);
+
+        return label;
+    }
+
+
+    /**
+     * Builds the chart image and returns it.
+     *
+     * @param width The chart width.
+     * @param height The chart height.
+     *
+     * @return the chart image.
+     */
+    protected Img getChartImg(int width, int height) {
+        return new Img(getImgUrl(width, height));
+    }
+
+
+    /**
+     * Builds the URL that points to the chart image.
+     *
+     * @param width The width of the requested chart.
+     * @param height The height of the requested chart.
+     *
+     * @return the URL to the chart image.
+     */
+    protected String getImgUrl(int width, int height) {
+        Config config = Config.getInstance();
+
+        String imgUrl = GWT.getModuleBaseURL();
+        imgUrl += "chart";
+        imgUrl += "?uuid=" + collection.identifier();
+        imgUrl += "&type=" + mode.getName();
+        imgUrl += "&server=" + config.getServerUrl();
+        imgUrl += "&locale=" + config.getLocale();
+        imgUrl += "&timestamp=" + new Date().getTime();
+        imgUrl += "&width=" + Integer.toString(width);
+        imgUrl += "&height=" + Integer.toString(height);
+
+        return imgUrl;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,422 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.layout.Layout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.tab.TabSet;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.ExportMode;
+import de.intevation.flys.client.shared.model.OutputMode;
+import de.intevation.flys.client.shared.model.User;
+
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.event.HasCollectionChangeHandlers;
+import de.intevation.flys.client.client.event.CollectionChangeEvent;
+import de.intevation.flys.client.client.event.CollectionChangeHandler;
+import de.intevation.flys.client.client.event.ParameterChangeEvent;
+import de.intevation.flys.client.client.event.ParameterChangeHandler;
+import de.intevation.flys.client.client.services.AddArtifactService;
+import de.intevation.flys.client.client.services.AddArtifactServiceAsync;
+import de.intevation.flys.client.client.services.CreateCollectionService;
+import de.intevation.flys.client.client.services.CreateCollectionServiceAsync;
+import de.intevation.flys.client.client.services.DescribeCollectionService;
+import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class CollectionView
+extends      Window
+implements   CollectionChangeHandler, HasCollectionChangeHandlers,
+             ParameterChangeHandler
+{
+    /** The ArtifactService used to communicate with the Artifact server. */
+    protected CreateCollectionServiceAsync createCollectionService =
+        GWT.create(CreateCollectionService.class);
+
+    /** The AddArtifactService used to add an artifact to a collection. */
+    protected AddArtifactServiceAsync addArtifactService =
+        GWT.create(AddArtifactService.class);
+
+    /** The DescribeCollectionService used to update the existing collection. */
+    protected DescribeCollectionServiceAsync describeCollectionService =
+        GWT.create(DescribeCollectionService.class);
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants messages = GWT.create(FLYSConstants.class);
+
+    /** The FLYS instance used to call services.*/
+    protected FLYS flys;
+
+    /** The ParameterList.*/
+    protected ParameterList parameterList;
+
+    /** The list of ValueChangeHandlers.*/
+    protected List<CollectionChangeHandler> handlers;
+
+    /** The collection to be displayed.*/
+    protected Collection collection;
+
+    /** The artifact that handles the parameterization.*/
+    protected Artifact artifact;
+
+    protected TabSet tabs;
+
+    /** The output tab.*/
+    protected Map<String, OutputTab> outputTabs;
+
+    /** The layout.*/
+    protected Layout layout;
+
+
+    /**
+     * This constructor creates a new CollectionView that is used to display the
+     * <i>collection</i>.
+     *
+     * @param collection The collection to be displayed.
+     */
+    public CollectionView(FLYS flys) {
+        this.flys          = flys;
+        this.tabs          = new TabSet();
+        this.outputTabs    = new HashMap<String, OutputTab>();
+        this.handlers      = new ArrayList<CollectionChangeHandler>();
+        this.layout        = new VLayout();
+        this.parameterList = new ParameterList(
+            flys, this, messages.new_project());
+
+        addCollectionChangeHandler(this);
+        addCollectionChangeHandler(parameterList);
+
+        parameterList.addParameterChangeHandler(this);
+
+        init();
+    }
+
+
+    public CollectionView(FLYS flys, Collection collection, Artifact artifact) {
+        this.flys          = flys;
+        this.tabs          = new TabSet();
+        this.outputTabs    = new HashMap<String, OutputTab>();
+        this.handlers      = new ArrayList<CollectionChangeHandler>();
+        this.layout        = new VLayout();
+        this.parameterList = new ParameterList(
+            flys,
+            this,
+            messages.getString(artifact.getName()),
+            artifact);
+
+        addCollectionChangeHandler(this);
+        addCollectionChangeHandler(parameterList);
+
+        parameterList.addParameterChangeHandler(this);
+
+        init();
+
+        setCollection(collection);
+        setArtifact(artifact);
+    }
+
+
+    /**
+     * This method handles the initial layout stuff.
+     */
+    protected void init() {
+        setWidth(750);
+        setHeight(600);
+
+        layout.setWidth100();
+
+        setCanDragReposition(true);
+        setCanDragResize(true);
+        setKeepInParentRect(true);
+
+        setTitle("");
+
+        addItem(layout);
+
+        layout.addMember(tabs);
+        tabs.addTab(parameterList);
+    }
+
+
+    /**
+     * This method triggers the CreateCollectionService to create a new
+     * collection in the artifact server.
+     *
+     * @param ownerId The uuid of the user that should own the new collection.
+     */
+    protected void createNewCollection(String ownerId) {
+        GWT.log("CollectionView.createNewCollection");
+
+        Config config       = Config.getInstance();
+        final String url    = config.getServerUrl();
+        final String locale = config.getLocale();
+
+        createCollectionService.create(
+            url, locale, ownerId,
+            new AsyncCallback<Collection>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not create the new collection.");
+                    SC.warn(messages.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(Collection collection) {
+                    GWT.log("Successfully created a new collection.");
+
+                    Artifact artifact = getArtifact();
+                    addArtifactService.add(collection, artifact, url, locale,
+                        new AsyncCallback<Collection>() {
+
+                            public void onFailure(Throwable caught) {
+                                GWT.log("An error occured while adding artifact.");
+                                SC.warn(messages.getString(caught.getMessage()));
+                            }
+
+                            public void onSuccess(Collection newCollection) {
+                                GWT.log("Successfully added artifact.");
+                                setCollection(newCollection);
+                            }
+                        }
+                    );
+                }
+            });
+    }
+
+
+    protected FLYS getFlys() {
+        return flys;
+    }
+
+
+
+    /**
+     * This method registers a new ValueChangeHandler.
+     *
+     * @param handler The new ValueChangeHandler.
+     */
+    public void addCollectionChangeHandler(CollectionChangeHandler handler) {
+        if (handler != null) {
+            handlers.add(handler);
+        }
+    }
+
+
+
+    /**
+     * This method calls the <code>onValueChange()</code> method of all
+     * registered ValueChangeHanders.
+     */
+    protected void fireCollectionChangeEvent(
+        Collection old, Collection newCol)
+    {
+        for (CollectionChangeHandler handler: handlers) {
+            handler.onCollectionChange(new CollectionChangeEvent(old, newCol));
+        }
+    }
+
+
+    /**
+     * This method returns true, if the Collection is new and no plugins has
+     * been chosen.
+     *
+     * @return true, if the Collection is new.
+     */
+    public boolean isNew() {
+        return collection.getItemLength() == 0 ? true : false;
+    }
+
+
+    /**
+     * Returns the artifact that is used for the parameterization.
+     *
+     * @return the artifact that is used for the parameterization.
+     */
+    protected Artifact getArtifact() {
+        return artifact;
+    }
+
+
+    /**
+     * Set the current artifact that is the master of the parameterization.
+     *
+     * @param artifact The new artifact.
+     */
+    protected void setArtifact(Artifact artifact) {
+        this.artifact = artifact;
+    }
+
+
+    /**
+     * Implements the onCollectionChange() method to do update the GUI after the
+     * parameterization has changed.
+     *
+     * @param event The ParameterChangeEvent.
+     */
+    public void onParameterChange(ParameterChangeEvent event) {
+        GWT.log("CollectionView.onParameterChange");
+
+        Artifact art             = event.getNewValue();
+        ArtifactDescription desc = art.getArtifactDescription();
+        OutputMode[] outs        = desc.getOutputModes();
+
+        setArtifact(art);
+        clearOutputTabs();
+
+        if (parameterList.hasPanel()) {
+            parameterList.removePanel();
+        }
+        Collection c = getCollection();
+
+        if (outs != null && c == null) {
+            User user = getFlys().getCurrentUser();
+            createNewCollection(user.identifier());
+        }
+        else if (outs != null && c != null) {
+            Config config = Config.getInstance();
+            String url    = config.getServerUrl();
+            String locale = config.getLocale();
+
+            describeCollectionService.describe(c.identifier(), url, locale,
+                new AsyncCallback<Collection>() {
+                    public void onFailure(Throwable caught) {
+                        GWT.log("Could not DESCRIBE collection.");
+                        SC.warn(messages.getString(caught.getMessage()));
+                    }
+
+
+                    public void onSuccess(Collection newCollection) {
+                        GWT.log("Successfully DESCRIBED collection.");
+                        setCollection(newCollection);
+                    }
+                }
+            );
+        }
+        else {
+            updateView();
+        }
+    }
+
+
+    /**
+     * Returns the collection of displayed by this view.
+     *
+     * @return the collection of this view.
+     */
+    protected Collection getCollection() {
+        return collection;
+    }
+
+
+    /**
+     * Set the current collection.
+     *
+     * @param collection The new collection.
+     */
+    protected void setCollection(Collection collection) {
+        Collection tmp  = this.collection;
+        this.collection = collection;
+
+        fireCollectionChangeEvent(tmp, this.collection);
+    }
+
+
+    public void onCollectionChange(CollectionChangeEvent event) {
+        Collection newCol = event.getNewValue();
+
+        Map<String, OutputMode> outs = newCol.getOutputModes();
+
+        Set<String> keys = outs.keySet();
+        for (String outname: keys) {
+            addOutputTab(outname, outs.get(outname));
+        }
+
+        updateView();
+    }
+
+
+    /**
+     * Adds a new tab for the OutputMode <i>out</i>.
+     *
+     * @param name The name and title of the output.
+     */
+    protected void addOutputTab(String name, OutputMode out) {
+        if (out instanceof ExportMode) {
+            ExportMode export = (ExportMode) out;
+
+            if (export.getFacet("csv") != null) {
+                TableDataPanel p = new TableDataPanel();
+                p.setUuid(collection.identifier());
+                p.setName(out.getName());
+                parameterList.setPanel (p);
+            }
+
+            return;
+        }
+
+        GWT.log("Add new output tab for '" + name + "'");
+
+        // TODO Source this out to a factory that creates the different
+        // OutputTabs.
+        String title = messages.getString(name);
+        OutputTab tab = new ChartOutputTab(
+            title, getCollection(), out, this);
+        outputTabs.put(name, tab);
+    }
+
+
+    /**
+     * Removes all output mode tabs from tab bar.
+     */
+    protected void clearOutputTabs() {
+        GWT.log("Clear OutputTabs.");
+
+        int num = tabs.getNumTabs();
+
+        for (int i = num-1; i >= 1; i--) {
+            tabs.removeTab(i);
+        }
+
+        outputTabs.clear();
+    }
+
+
+    /**
+     * Update the view (refresh the list of old and current data).
+     */
+    protected void updateView() {
+        GWT.log("CollectionView.updateView()");
+        updateOutputTabs();
+    }
+
+
+    /**
+     * This method is used to update the tabs to show specific output modes.
+     */
+    protected void updateOutputTabs() {
+        GWT.log("Update output tabs.");
+        if (outputTabs != null) {
+            Set<String> keys = outputTabs.keySet();
+
+            for (String key: keys) {
+                tabs.addTab(outputTabs.get(key));
+            }
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWindow.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,180 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import com.google.gwt.core.client.GWT;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.util.SC;
+
+import com.smartgwt.client.widgets.Window;
+
+import com.smartgwt.client.widgets.tree.Tree;
+import com.smartgwt.client.widgets.tree.TreeNode;
+import com.smartgwt.client.widgets.tree.TreeGrid;
+
+import com.smartgwt.client.widgets.layout.Layout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DataItem;
+
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.Config;
+
+import de.intevation.flys.client.client.services.MetaDataService;
+import de.intevation.flys.client.client.services.MetaDataServiceAsync;
+
+import de.intevation.flys.client.shared.model.DataCageTree;
+import de.intevation.flys.client.shared.model.DataCageNode;
+
+public class DatacageWindow
+extends      Window
+{
+    protected MetaDataServiceAsync metaDataService =
+        GWT.create(MetaDataService.class);
+
+    protected FLYSConstants messages =
+        GWT.create(FLYSConstants.class);
+
+
+    protected Artifact artifact;
+
+    protected TreeGrid treeGrid;
+
+    protected Layout layout;
+
+
+    public DatacageWindow(Artifact artifact) {
+        this.artifact = artifact;
+
+        setWidth(200);
+        setHeight(300);
+
+        layout = new VLayout();
+        layout.setWidth100();
+
+        addItem(layout);
+
+        treeGrid = new TreeGrid();  
+        treeGrid.setLoadDataOnDemand(false);          
+        treeGrid.setWidth100();  
+        treeGrid.setHeight100();
+
+        layout.addMember(treeGrid);
+
+        String river =  findRiver();
+        setTitle("Datenkorb: " + river);  
+        setShowMinimizeButton(false);  
+        setIsModal(true);  
+        setShowModalMask(true);  
+        setCanDragResize(true);
+
+        centerInPage();
+
+        triggerTreeBuilding(river);
+    }
+
+    protected void triggerTreeBuilding(String river) {
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale();
+
+        metaDataService.getMetaData(
+            url, locale, river,
+            new AsyncCallback<DataCageTree>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not load meta data.");
+                    SC.warn(messages.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(DataCageTree tree) {
+                    GWT.log("Successfully loaded meta data.");
+                    buildTree(tree);
+                }
+            });
+    }
+
+    protected void buildTree(DataCageTree tree) {
+        treeGrid.setData(convert(tree));
+    }
+
+    protected static TreeNode convert(DataCageNode node) {
+        List<DataCageNode> children = node.getChildren();
+
+        TreeNode [] cs;
+
+        if (children != null) {
+            ArrayList<TreeNode> nc = new ArrayList<TreeNode>(children.size());
+
+            for (DataCageNode dcn: children) {
+                nc.add(convert(dcn));
+            }
+
+            cs = nc.toArray(new TreeNode[nc.size()]);
+        }
+        else {
+            cs = new TreeNode[0];
+        }
+
+        return new TreeNode(node.getName(), cs);
+    }
+
+    protected static Tree convert(DataCageTree tree) {
+        DataCageNode root = tree.getRoot();
+
+        List<DataCageNode> children = root.getChildren();
+
+        TreeNode [] cs;
+
+        if (children != null) {
+            ArrayList<TreeNode> nc = new ArrayList<TreeNode>(children.size());
+
+            if (nc != null) {
+                for (DataCageNode dcn: children) {
+                    nc.add(convert(dcn));
+                }
+            }
+            cs = nc.toArray(new TreeNode[nc.size()]);
+        }
+        else {
+            cs = new TreeNode[0];
+        }
+
+        TreeNode rn = new TreeNode(root.getName(), cs);
+
+        Tree r = new Tree();
+        r.setRoot(rn);
+
+        return r;
+    }
+
+    protected String findRiver() {
+
+        ArtifactDescription adescr = artifact.getArtifactDescription();
+        DataList [] data = adescr.getOldData();
+
+        if (data != null && data.length > 0) {
+            for (int i = 0; i < data.length; i++) {
+                DataList dl = data[i];
+                if (dl.getState().equals("state.winfo.river")) {
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        DataItem [] di = d.getItems();
+                        if (di != null && di.length == 1) {
+                           return d.getItems()[0].getStringValue();
+                        }
+                    }
+                }
+            }
+        }
+
+        return "";
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,217 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
+
+import com.smartgwt.client.types.TitleOrientation;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+
+import de.intevation.flys.client.client.FLYSConstants;
+
+public class DoubleArrayPanel
+extends      DynamicForm
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    protected TextItem ti;
+
+    /** The constant input field name.*/
+    public static final String FIELD_NAME = "doublearray";
+
+
+    public DoubleArrayPanel(
+        String title,
+        double[] values,
+        BlurHandler handler)
+    {
+        this(title, values, handler, TitleOrientation.RIGHT);
+    }
+
+
+    /**
+     * Creates a new form with a single input field that displays an array of
+     * double values.
+     *
+     * @param name The name of the TextItem.
+     * @param title The title of the TextItem.
+     * @param values The double values that should be displayed initially.
+     * @param handler The BlurHandler that is used to valide the input.
+     */
+    public DoubleArrayPanel(
+        String title,
+        double[] values,
+        BlurHandler handler,
+        TitleOrientation titleOrientation)
+    {
+        ti                 = new TextItem(FIELD_NAME);
+        StaticTextItem sti = new StaticTextItem("staticarray");
+
+        ti.setShowTitle(false);
+        sti.setShowTitle(false);
+        sti.setValue(title);
+
+        ti.addBlurHandler(handler);
+
+        if (titleOrientation == TitleOrientation.RIGHT) {
+            setFields(ti, sti);
+        }
+        else {
+            setFields(sti, ti);
+        }
+
+        setTitleOrientation(titleOrientation);
+        setNumCols(2);
+
+        if (values == null) {
+            return;
+        }
+
+        NumberFormat f = NumberFormat.getDecimalFormat();
+
+        StringBuilder text = new StringBuilder();
+        boolean firstItem  = true;
+
+        for (double val: values) {
+            if (!firstItem) {
+                text.append(" ");
+            }
+
+            text.append(f.format(val));
+
+            firstItem = false;
+        }
+
+        ti.setValue(text.toString());
+    }
+
+
+    /**
+     * This method takes the double array to set the values to the textbox.
+     *
+     * @param values The double values.
+     */
+    public void setValues(double[] values) {
+        NumberFormat f = NumberFormat.getDecimalFormat();
+
+        StringBuilder text = new StringBuilder();
+        boolean firstItem  = true;
+        if (values != null) {
+            for (double val: values) {
+                if (!firstItem) {
+                    text.append(" ");
+                }
+
+                text.append(f.format(val));
+
+                firstItem = false;
+            }
+        }
+
+        ti.clearValue();
+        ti.setValue(text.toString());
+    }
+
+
+    /**
+     * This method validates the entered text in the location input field. If
+     * there are values that doesn't represent a valid location, an error is
+     * displayed.
+     *
+     * @param item The FormItem.
+     */
+    protected boolean validateForm(FormItem item) {
+        if (item instanceof StaticTextItem) {
+            return true;
+        }
+
+        boolean  valid = true;
+        String   value = (String) item.getValue();
+
+        if (value == null) {
+            return valid;
+        }
+
+        String[] parts = value.split(" ");
+
+        if (parts == null) {
+            return valid;
+        }
+
+        NumberFormat f = NumberFormat.getDecimalFormat();
+        Map errors     = getErrors();
+
+        try {
+            for (String part: parts) {
+                double location = f.parse(part);
+            }
+
+            errors.remove(item.getFieldName());
+        }
+        catch (NumberFormatException nfe) {
+            errors.put(item.getFieldName(), MESSAGES.wrongFormat());
+
+            valid = false;
+        }
+
+        setErrors(errors, true);
+
+        return valid;
+    }
+
+
+    /**
+     * This method returns the double array that has been entered in
+     * <i>item</i>.
+     *
+     * @param item The item that contains the desired values.
+     *
+     * @return the values as double array.
+     */
+    public double[] getInputValues(FormItem item) {
+        String value = (String) item.getValue();
+
+        if (value == null) {
+            return null;
+        }
+
+        String[] parts  = value.split(" ");
+
+        if (parts == null) {
+            return null;
+        }
+
+        double[] values = new double[parts.length];
+
+        NumberFormat f = NumberFormat.getDecimalFormat();
+
+        int i = 0;
+        for (String part: parts) {
+            try {
+                values[i++] = f.parse(part);
+            }
+            catch (NumberFormatException nfe) {
+                // do nothing
+            }
+        }
+
+        return values;
+    }
+
+
+    /**
+     * Returns the double values of this panel.
+     *
+     * @return the double values of this panel.
+     */
+    public double[] getInputValues() {
+        return getInputValues(ti);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleRangePanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,208 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.FloatItem;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+
+/**
+ * This class creates a DynamicForm with three input fields.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DoubleRangePanel
+extends      DynamicForm
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+
+    /** The constant name of the input field to enter the start of a distance.*/
+    public static final String FIELD_FROM = "from";
+
+    /** The constant name of the input field to enter the end of a distance.*/
+    public static final String FIELD_TO = "to";
+
+    /** The constant name of the input field to enter the step width of a
+     * distance.*/
+    public static final String FIELD_WIDTH = "step";
+
+    /** The textboxes */
+    protected FloatItem fromItem;
+    protected FloatItem toItem;
+    protected FloatItem stepItem;
+
+
+    /**
+     * Creates a new form with a single input field that displays an array of
+     * double values.
+     *
+     * @param name The name of the TextItem.
+     * @param title The title of the TextItem.
+     * @param values The double values that should be displayed initially.
+     * @param handler The BlurHandler that is used to valide the input.
+     */
+    public DoubleRangePanel(
+        String titleFrom, String titleTo, String titleStep,
+        double from, double to, double step,
+        int width,
+        BlurHandler handler)
+    {
+        fromItem = new FloatItem(FIELD_FROM);
+        toItem   = new FloatItem(FIELD_TO);
+        stepItem = new FloatItem(FIELD_WIDTH);
+
+        fromItem.addBlurHandler(handler);
+        toItem.addBlurHandler(handler);
+        stepItem.addBlurHandler(handler);
+
+        NumberFormat f = NumberFormat.getDecimalFormat();
+
+        fromItem.setValue(f.format(from));
+        toItem.setValue(f.format(to));
+        stepItem.setValue(f.format(step));
+
+        StaticTextItem fromText = new StaticTextItem("staticFrom");
+        fromText.setValue(titleFrom);
+        fromText.setShowTitle(false);
+        fromItem.setShowTitle(false);
+
+        StaticTextItem toText = new StaticTextItem("staticTo");
+        toText.setValue(titleTo);
+        toText.setShowTitle(false);
+        toItem.setShowTitle(false);
+
+        StaticTextItem stepText = new StaticTextItem("staticStep");
+        stepText.setValue(titleStep);
+        stepText.setShowTitle(false);
+        stepItem.setShowTitle(false);
+
+        int itemWidth = width / 6;
+        fromItem.setWidth(itemWidth);
+        fromText.setWidth(itemWidth);
+        toItem.setWidth(itemWidth);
+        toText.setWidth(itemWidth);
+        stepItem.setWidth(itemWidth);
+        stepText.setWidth(itemWidth);
+
+        setFields(fromItem, fromText, toItem, toText, stepItem, stepText);
+        setFixedColWidths(false);
+        setNumCols(6);
+        setWidth(width);
+        setAlign(Alignment.CENTER);
+    }
+
+
+    /**
+     * This method takes distances values and sets them to the textboxes
+     * visualizied by this widget.
+     *
+     * @param from  The from value.
+     * @param to    The to value.
+     * @param steps The max steps.
+     */
+    public void setValues(double from, double to, double steps) {
+        NumberFormat f = NumberFormat.getDecimalFormat();
+
+        fromItem.setValue(f.format(from));
+        toItem.setValue(f.format(to));
+        stepItem.setValue(f.format(steps));
+    }
+
+    /**
+     * This method validates the entered text in the input fields. If
+     * there are values that doesn't represent a valid float, an error is
+     * displayed.
+     *
+     * @param item The FormItem.
+     */
+    protected boolean validateForm(FormItem item) {
+        if (item instanceof StaticTextItem) {
+            return true;
+        }
+
+        boolean valid = true;
+
+        String v = (String) item.getValue();
+
+        NumberFormat f = NumberFormat.getDecimalFormat();
+        Map errors     = getErrors();
+
+        try {
+            double value = f.parse(v);
+
+            errors.remove(item.getFieldName());
+        }
+        catch (NumberFormatException nfe) {
+            errors.put(item.getFieldName(), MESSAGES.wrongFormat());
+
+            item.focusInItem();
+
+            valid = false;
+        }
+
+        setErrors(errors, true);
+
+        return valid;
+    }
+
+
+    /**
+     * Returns the double value of <i>value</i>.
+     *
+     * @return the double value of <i>value</i>.
+     */
+    protected double getDouble(String value) {
+        NumberFormat f = NumberFormat.getDecimalFormat();
+
+        return f.parse(value);
+    }
+
+
+    /**
+     * Returns the start value.
+     *
+     * @return the start value.
+     */
+    public double getFrom() {
+        String v = getValueAsString(FIELD_FROM);
+
+        return getDouble(v);
+    }
+
+
+    /**
+     * Returns the end value.
+     *
+     * @return the end value.
+     */
+    public double getTo() {
+        String v = getValueAsString(FIELD_TO);
+
+        return getDouble(v);
+    }
+
+
+    /**
+     * Returns the step width.
+     *
+     * @return the step width.
+     */
+    public double getStep() {
+        String v = getValueAsString(FIELD_WIDTH);
+
+        return getDouble(v);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ExportPanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,121 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.ExportMode;
+import de.intevation.flys.client.shared.model.Facet;
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+/**
+ * A panel that displays an download icon for all available export modes of a
+ * Collection.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ExportPanel extends VLayout {
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    protected Collection       c;
+    protected List<ExportMode> exports;
+
+    /** This layout will store a list of available export types.*/
+    protected HLayout container;
+
+
+    public ExportPanel(Collection c, List<ExportMode> exports) {
+        super();
+
+        this.c         = c;
+        this.exports   = exports;
+        this.container = new HLayout();
+
+        Label title = new Label(MSG.dataexport());
+        title.setHeight(15);
+        title.setStyleName("fontNormalSmallUnderlined");
+
+        addMember(title);
+        addMember(createExportItems());
+
+        setHeight(45);
+        setMembersMargin(5);
+    }
+
+
+    /**
+     * This method is used to create an item (created by createExportButton) for
+     * each facet for each export mode.
+     *
+     * @return a horizontal list of buttons.
+     */
+    protected HLayout createExportItems() {
+        HLayout layout = new HLayout();
+
+        for (ExportMode mode: exports) {
+            String      name   = mode.getName();
+            List<Facet> facets = mode.getFacets();
+
+            for (Facet facet: facets) {
+                layout.addMember(createExportButton(name, facet.getName()));
+            }
+        }
+
+        return layout;
+    }
+
+
+    /**
+     * This method is used to create a button (with click handler) for a
+     * concrete export mode / type.
+     *
+     * @param name The name of the export.
+     * @param facet The name of the export type (e.g. CSV, WST).
+     *
+     * @return an image with click handler.
+     */
+    protected Canvas createExportButton(String name, String facet) {
+        String url  = getExportUrl(name, facet);
+        String iUrl = GWT.getHostPageBaseURL() + MSG.imageSave();
+
+        HTMLPane pane = new HTMLPane();
+        pane.setContents("<a href='" + url + "'><img src='" + iUrl + "'></a>");
+
+        return pane;
+    }
+
+
+    /**
+     * Creates the URL used to trigger an export.
+     *
+     * @param name The name of the export.
+     * @param facet The name of the export type (e.g. CSV, WST).
+     *
+     * @return the export URL.
+     */
+    protected String getExportUrl(String name, String facet) {
+        Config config = Config.getInstance();
+
+        String url = GWT.getModuleBaseURL();
+        url += "export";
+        url += "?uuid=" + c.identifier();
+        url += "&mode=" + name;
+        url += "&type=" + facet;
+        url += "&server=" + config.getServerUrl();
+        url += "&locale=" + config.getLocale();
+
+        return url;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSFooter.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,89 @@
+package de.intevation.flys.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class FLYSFooter extends HLayout {
+
+    /** The interface that provides i18n messages. */
+    private FLYSConstants messages = GWT.create(FLYSConstants.class);
+
+    /** An instance to FLYS.*/
+    protected FLYS flys;
+
+    /** The button to open the project list.*/
+    protected Label home;
+
+    /** The button to switch between the english and german version.*/
+    protected Label contact;
+
+    /** The button to open an info panel.*/
+    protected Label impressum;
+
+    /**
+     * The default constructor for creating a new MainMenu.
+     */
+    public FLYSFooter(FLYS flys) {
+        this.flys     = flys;
+
+        home    = new Label(messages.footerHome());
+        contact  = new Label(messages.footerContact());
+        impressum = new Label(messages.footerImpressum());
+
+        init();
+    }
+
+
+    /**
+     * This method is called by the constructor after creating the necessary
+     * components. It initializes layout specific stuff like width, height,
+     * colors and so on and appends the components.
+     */
+    protected void init() {
+        setStyleName("bgBlueDark");
+        setHeight("25px");
+        setLayoutMargin(5);
+
+        home.setStyleName("fontLightSmall");
+        contact.setStyleName("fontLightSmall");
+        impressum.setStyleName("fontLightSmall");
+
+        HLayout panel = new HLayout();
+        panel.setWidth("100%");
+        panel.setMembersMargin(5);
+        panel.setAlign(Alignment.RIGHT);
+        panel.addMember(home);
+        panel.addMember(contact);
+        panel.addMember(impressum);
+        home.setAlign(Alignment.RIGHT);
+        contact.setAlign(Alignment.RIGHT);
+        impressum.setAlign(Alignment.RIGHT);
+
+        home.setWidth(70);
+        contact.setWidth(70);
+        impressum.setWidth(80);
+
+        addMember(panel);
+    }
+
+
+    /**
+     * Returns the FLYS instance stored in this class.
+     *
+     * @return the flys instance.
+     */
+    protected FLYS getFlys() {
+        return flys;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSHeader.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,93 @@
+package de.intevation.flys.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ImageResource;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.FLYSImages;
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYSHeader extends HLayout {
+
+    /** The interface that provides the image resources. */
+    private FLYSImages IMAGES = GWT.create(FLYSImages.class);
+
+    /** The interface that provides the message resources. */
+    private FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    /** The height used for this header.*/
+    public static final int HEIGHT = 75;
+
+    /** The height used for the images.*/
+    public static final int IMG_HEIGHT = 50;
+
+
+    public FLYSHeader() {
+        init();
+    }
+
+    public void init() {
+        setWidth100();
+        setHeight(HEIGHT);
+        setLayoutLeftMargin(5);
+        setLayoutRightMargin(5);
+
+        ImageResource flysRes = IMAGES.logoFlys();
+        ImageResource bfgRes  = IMAGES.logoBfg();
+
+        Img flys = new Img(
+            flysRes.getURL(),
+            calcWidth(flysRes,IMG_HEIGHT),
+            IMG_HEIGHT);
+
+        Img bfg  = new Img(
+            bfgRes.getURL(),
+            calcWidth(bfgRes, HEIGHT),
+            HEIGHT);
+
+        Label fullname = new Label(MESSAGES.fullname());
+        fullname.setHeight(HEIGHT - IMG_HEIGHT);
+        fullname.setStyleName ("fontNormalMid");
+
+        VLayout left = new VLayout();
+        left.addMember(flys);
+        left.addMember(fullname);
+
+        HLayout right = new HLayout();
+        right.setAlign(Alignment.RIGHT);
+        right.addMember(bfg);
+
+        addMember(left);
+        addMember(right);
+    }
+
+
+    /**
+     * This method calculates the wight of an image relative to the given
+     * height.
+     *
+     * @param res The ImageResource that points to the image.
+     * @param height The pre-defined height.
+     *
+     * @return the calculated width that should be used for the image.
+     */
+    protected int calcWidth(ImageResource res, int height) {
+        int widthOrig  = res.getWidth();
+        int heightOrig = res.getHeight();
+
+        double factor = (double)heightOrig / height;
+        double width  = (double)widthOrig / factor;
+
+        return (int) width * 10 / 10;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSView.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,79 @@
+package de.intevation.flys.client.client.ui;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYSView extends Canvas {
+
+    /** The project list displaying the projects of a user.*/
+    protected ProjectList projectList;
+
+    /** The workspace that handles the artifact collection views.*/
+    protected FLYSWorkspace workspace;
+
+    /** The layout provided by this widget.*/
+    protected HLayout layout;
+
+
+    /**
+     * The default constructor for creating a new empty FLYSView. After creating
+     * the components, {@link init()} is called to do the layout work.
+     */
+    public FLYSView() {
+        layout = new HLayout();
+
+        init();
+    }
+
+
+    /**
+     * This method is called to do the layout work.
+     */
+    protected void init() {
+        setWidth("100%");
+        setHeight("*");
+
+        setStyleName("bgWhite");
+        setBorder("1px solid #808080");
+
+        layout.setHeight("100%");
+        layout.setWidth("100%");
+
+        addChild(layout);
+    }
+
+
+    /**
+     * Set the current project list. Previous ProjectLists are replaced by the
+     * new one.
+     */
+    public void setProjectList(ProjectList projectList) {
+        if (this.projectList != null) {
+            removeChild(this.projectList);
+        }
+
+        this.projectList = projectList;
+        layout.addMember(this.projectList);
+    }
+
+
+    /**
+     * Set the current FLYSWorkspace. Previous workspaces are replaced by the
+     * new one.
+     *
+     * @param workspaces The new FLYSWorkspace.
+     */
+    public void setFLYSWorkspace(FLYSWorkspace workspace) {
+        if (this.workspace != null) {
+            removeChild(this.workspace);
+        }
+
+        this.workspace = workspace;
+        layout.addMember(this.workspace);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,51 @@
+package de.intevation.flys.client.client.ui;
+
+import com.smartgwt.client.widgets.Canvas;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYSWorkspace extends Canvas {
+
+    /** The maximal number of windows that fit into the browser view when an
+     * offset is used to move windows initially.*/
+    public static int MAX_WINDOWS = 10;
+
+    /** The number of pixels used to move windows.*/
+    public static int WINDOW_OFFSET = 20;
+
+
+    /** A map that contains the open CollectionViews. */
+    protected List<CollectionView> views;
+
+
+    /**
+     * The default constructor creates an empty FLYSWorkspace with no
+     * CollectionViews opened.
+     */
+    public FLYSWorkspace() {
+        views = new ArrayList<CollectionView>();
+    }
+
+
+    /**
+     * This method adds a new CollectionView to this workspace and stores a
+     * reference in {@link views}.
+     *
+     * @param collectionView A new CollectionView.
+     */
+    public void addView(CollectionView collectionView) {
+        int num    = views != null ? views.size() : 0;
+        int factor = num % MAX_WINDOWS;
+
+        collectionView.moveTo(factor * WINDOW_OFFSET, factor * WINDOW_OFFSET);
+
+        views.add(collectionView);
+        addChild(collectionView);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/LinkSelection.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,174 @@
+package de.intevation.flys.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.LinkItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
+import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.client.event.StepForwardEvent;
+
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+/**
+ * This UIProvider displays the DataItems of the Data object in a list of links.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class LinkSelection
+extends      MapSelection
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants messages = GWT.create(FLYSConstants.class);
+
+    /** The combobox.*/
+    protected DynamicForm form;
+
+    /** The selected river*/
+    protected Data river;
+
+    /**
+     * This method currently returns a
+     * {@link com.smartgwt.client.widgets.form.DynamicForm} that contains all
+     * data items in a list of links stored in <i>data</i>.
+     *
+     * @param data The {@link Data} object.
+     *
+     * @return a combobox.
+     */
+    public Canvas create(DataList data) {
+        VLayout v = new VLayout();
+        v.setMembersMargin(10);
+        v.setAlign(VerticalAlignment.TOP);
+        if (data.getState() == null) {
+            Canvas module = super.createWidget(data);
+            v.addMember(module);
+        }
+        Canvas content = createWidget(data);
+        v.addMember(content);
+
+        return v;
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        HLayout layout  = new HLayout();
+        VLayout vLayout = new VLayout();
+        layout.setWidth("400px");
+
+        Label label = new Label(dataList.getLabel());
+        label.setWidth("200px");
+
+        int size = dataList.size();
+        for (int i = 0; i < size; i++) {
+            Data data        = dataList.get(i);
+            DataItem[] items = data.getItems();
+
+            for (DataItem item: items) {
+                HLayout hLayout = new HLayout();
+
+                hLayout.addMember(label);
+                hLayout.addMember(new Label(item.getLabel()));
+
+                vLayout.addMember(hLayout);
+                vLayout.setWidth("130px");
+            }
+        }
+
+        Canvas back = getBackButton(dataList.getState());
+
+        layout.addMember(label);
+        layout.addMember(vLayout);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+
+    /**
+     * This method creates the content of the widget.
+     *
+     * @param data The {@link Data} object.
+     *
+     * @return a list of links
+     */
+    protected Canvas createWidget(DataList data) {
+        GWT.log("LinkSelection - create()");
+
+        VLayout layout   = new VLayout();
+        layout.setAlign(VerticalAlignment.TOP);
+        layout.setHeight(25);
+
+
+        form = new DynamicForm();
+        VLayout formLayout = new VLayout();
+
+        formLayout.setLayoutLeftMargin(60);
+        int size = data.size();
+
+        for (int i = 0; i < size; i++) {
+            Data d = data.get(i);
+
+            Label label = new Label(d.getDescription());
+            label.setValign(VerticalAlignment.TOP);
+            label.setHeight(20);
+
+            for (DataItem item: d.getItems()) {
+                LinkItem link = new LinkItem("river");
+                link.setLinkTitle(item.getLabel());
+                link.setTarget(item.getStringValue());
+                link.setShowTitle(false);
+                DynamicForm f = new DynamicForm();
+                f.setItems(link);
+                formLayout.addMember(f);
+                link.addClickHandler(new ClickHandler() {
+                    public void onClick(ClickEvent event) {
+                        DataItem item = new DefaultDataItem(
+                            ((LinkItem)event.getItem()).getLinkTitle(),
+                            null,
+                            ((LinkItem)event.getItem()).getLinkTitle());
+
+                            river = new DefaultData(
+                                "river",
+                                null,
+                                null,
+                                new DataItem [] {item});
+                        fireStepForwardEvent (new StepForwardEvent (getData()));
+                    }
+                });
+
+            }
+            label.setWidth(50);
+
+            layout.addMember(label);
+            layout.addMember(formLayout);
+        }
+        layout.setAlign(VerticalAlignment.TOP);
+
+        return layout;
+    }
+
+
+    protected Data[] getData() {
+        Data[] module = super.getData();
+        if (module != null) {
+            return new Data[] {module[0], river};
+        }
+        else {
+            return new Data[] {river};
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,898 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
+import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
+import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+
+import com.smartgwt.client.widgets.tab.TabSet;
+import com.smartgwt.client.widgets.tab.Tab;
+import com.smartgwt.client.data.Record;
+
+import com.smartgwt.client.types.ListGridFieldType;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.shared.model.DistanceInfoObject;
+import de.intevation.flys.client.shared.model.DistanceInfoRecord;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+
+import de.intevation.flys.client.client.services.DistanceInfoService;
+import de.intevation.flys.client.client.services.DistanceInfoServiceAsync;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.FLYSImages;
+import de.intevation.flys.client.client.Config;
+
+
+/**
+ * This UIProvider creates a widget to enter locations or a distance.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class LocationDistancePanel
+extends      AbstractUIProvider
+implements   ChangeHandler, BlurHandler
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    /** The interface that provides the image resources. */
+    private FLYSImages IMAGES = GWT.create(FLYSImages.class);
+
+    /** The DistanceInfoService used to retrieve locations about rivers.*/
+    protected DistanceInfoServiceAsync distanceInfoService =
+        GWT.create(DistanceInfoService.class);
+
+    /** The constant name of the input field to enter locations.*/
+    public static final String FIELD_LOCATION = "location";
+
+    /** The constant name of the input field to enter distance.*/
+    public static final String FIELD_DISTANCE = "distance";
+
+    /** The constant name of the input field to enter the start of a distance.*/
+    public static final String FIELD_FROM = "from";
+
+    /** The constant name of the input field to enter the end of a distance.*/
+    public static final String FIELD_TO = "to";
+
+    /** The constant name of the input field to enter the step width of a
+     * distance.*/
+    public static final String FIELD_WIDTH = "width";
+
+    public static final int WIDTH = 250;
+
+
+    /** The radio group for input mode selection.*/
+    protected DynamicForm mode;
+
+    /** A container that will contain the location or the distance panel.*/
+    protected HLayout container;
+
+    /** The min value for a distance.*/
+    protected double min;
+
+    /** The max value for a distance.*/
+    protected double max;
+
+    /** The 'from' value entered in the distance mode.*/
+    protected double from;
+
+    /** The 'to' value entered in the distance mode.*/
+    protected double to;
+
+    /** The 'step' value entered in the distance mode.*/
+    protected double step;
+
+    /** The values entered in the location mode.*/
+    protected double[] values;
+
+    /** The input panel for locations */
+    protected DoubleArrayPanel locationPanel;
+
+    /** The input panel for distances */
+    protected DoubleRangePanel distancePanel;
+
+    /** The tab set containing the location and distance table*/
+    protected TabSet inputTables;
+
+    /** The distance table. */
+    protected ListGrid distanceTable;
+
+    /** The locations table */
+    protected ListGrid locationsTable;
+
+    /** The locations table for distance input. */
+    protected ListGrid locationDistanceTable;
+
+    /** The table data. */
+    protected DistanceInfoObject[] tableData;
+
+    /**
+     * Creates a new LocationDistancePanel instance.
+     */
+    public LocationDistancePanel() {
+        distanceTable  = new ListGrid();
+        locationsTable = new ListGrid();
+        locationDistanceTable = new ListGrid();
+        locationDistanceTable.setShowHeaderContextMenu(false);
+        distanceTable.setShowHeaderContextMenu(false);
+        locationsTable.setShowHeaderContextMenu(false);
+    }
+
+
+    /**
+     * This method creates a widget that contains a label, a panel with
+     * checkboxes to switch the input mode between location and distance input,
+     * and a the mode specific panel.
+     *
+     * @param data The data that might be inserted.
+     *
+     * @return a panel.
+     */
+    public Canvas create(DataList data) {
+        VLayout layout = new VLayout();
+        layout.setMembersMargin(10);
+
+        initDefaults(data);
+
+        Label label   = new Label(MESSAGES.location_distance_state());
+        Canvas widget = createWidget(data);
+        Canvas submit = getNextButton();
+        createDistanceInputPanel();
+
+        createDistanceTable();
+        createLocationTable();
+        createLocationTableDistance ();
+
+        widget.setHeight(50);
+        label.setHeight(25);
+
+        layout.addMember(label);
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        return layout;
+    }
+
+
+    /**
+     * This method creates a table that contains the distance values.
+     */
+    protected void createDistanceTable() {
+        distanceTable.setWidth100();
+        distanceTable.setShowRecordComponents(true);
+        distanceTable.setShowRecordComponentsByCell(true);
+        distanceTable.setHeight100();
+        distanceTable.setEmptyMessage(MESSAGES.empty_table());
+
+        ListGridField addDistance = new ListGridField ("", "");
+        addDistance.setType (ListGridFieldType.ICON);
+        addDistance.setWidth ("30");
+        addDistance.addRecordClickHandler (new RecordClickHandler () {
+            public void onRecordClick (RecordClickEvent e) {
+                if (!isLocationMode ()) {
+                    Record r = e.getRecord();
+                    double min = r.getAttributeAsDouble("from");
+                    double max = r.getAttributeAsDouble("to");
+                    setDistanceValues(min, max);
+                }
+                else {
+                    double[] selected;
+                    Record r = e.getRecord();
+                    double min = r.getAttributeAsDouble("from");
+                    double max = r.getAttributeAsDouble("to");
+                    if (getLocationValues() != null) {
+                        double[] val = getLocationValues();
+                        selected = new double[val.length + 2];
+                        for(int i = 0; i < val.length; i++){
+                            selected[i] = val[i];
+                        }
+                        selected[val.length] = min;
+                        selected[val.length + 1] = max;
+                    }
+                    else {
+                        selected = new double[2];
+                        selected[0] = min;
+                        selected[1] = max;
+                    }
+                setLocationValues(selected);
+                }
+            }
+        });
+        addDistance.setCellIcon (IMAGES.markerGreen ().getURL ());
+
+        ListGridField ddescr = new ListGridField("description",
+                MESSAGES.description());
+        ddescr.setType(ListGridFieldType.TEXT);
+        ddescr.setWidth("*");
+        ListGridField from = new ListGridField("from", MESSAGES.from());
+        from.setType(ListGridFieldType.TEXT);
+        from.setWidth(75);
+        ListGridField to = new ListGridField("to", MESSAGES.to());
+        to.setType(ListGridFieldType.TEXT);
+        to.setWidth(75);
+        ListGridField dside = new ListGridField("riverside",
+                MESSAGES.riverside());
+        dside.setType(ListGridFieldType.TEXT);
+        dside.setWidth(60);
+
+        distanceTable.setFields(addDistance, ddescr, from, to, dside);
+    }
+
+
+    /**
+     * This method creates a table that contains the location values.
+     */
+    protected void createLocationTable() {
+        locationsTable.setWidth100();
+        locationsTable.setShowRecordComponents(true);
+        locationsTable.setShowRecordComponentsByCell(true);
+        locationsTable.setHeight100();
+        locationsTable.setEmptyMessage(MESSAGES.empty_table());
+
+        ListGridField addLocation = new ListGridField ("", "");
+        addLocation.setType (ListGridFieldType.ICON);
+        addLocation.setWidth ("30");
+        addLocation.addRecordClickHandler (new RecordClickHandler () {
+            public void onRecordClick (RecordClickEvent e) {
+                ListGridRecord[] records = locationsTable.getSelection();
+                double[] selected;
+                if (getLocationValues() != null) {
+                    double[] val = getLocationValues();
+                    selected = new double[val.length + 1];
+                    for(int i = 0; i < val.length; i++){
+                        selected[i] = val[i];
+                    }
+                    selected[val.length] =
+                        records[0].getAttributeAsDouble("from");
+                }
+                else {
+                    selected = new double[1];
+                    selected[0] = records[0].getAttributeAsDouble("from");
+                }
+                setLocationValues(selected);
+            }
+        });
+        addLocation.setCellIcon (IMAGES.markerGreen ().getURL ());
+
+        ListGridField ldescr = new ListGridField("description",
+                MESSAGES.description());
+        ldescr.setType(ListGridFieldType.TEXT);
+        ldescr.setWidth("*");
+        ListGridField lside = new ListGridField("riverside",
+                MESSAGES.riverside());
+        lside.setType(ListGridFieldType.TEXT);
+        lside.setWidth(60);
+        ListGridField loc = new ListGridField("from", MESSAGES.location());
+        loc.setType(ListGridFieldType.TEXT);
+        loc.setWidth(80);
+        locationsTable.setFields(addLocation, ldescr, loc, lside);
+    }
+
+
+    /**
+     * This method creates a table that contains the location values.
+     */
+    protected void createLocationTableDistance (){
+        locationDistanceTable = null;
+        locationDistanceTable = new ListGrid ();
+        locationDistanceTable.setWidth100();
+        locationDistanceTable.setShowRecordComponents(true);
+        locationDistanceTable.setShowRecordComponentsByCell(true);
+        locationDistanceTable.setHeight100();
+        locationDistanceTable.setEmptyMessage(MESSAGES.empty_table());
+
+        ListGridField addfrom = new ListGridField ("", "");
+        addfrom.setType (ListGridFieldType.ICON);
+        addfrom.setWidth ("30");
+        addfrom.setCellIcon (IMAGES.markerGreen ().getURL ());
+
+        ListGridField addto2 = new ListGridField ("", "");
+        addto2.setType (ListGridFieldType.ICON);
+        addto2.setWidth ("30");
+        addto2.setCellIcon (IMAGES.markerRed ().getURL ());
+
+
+        ListGridField ldescr = new ListGridField("description",
+                MESSAGES.description());
+        ldescr.setType(ListGridFieldType.TEXT);
+        ldescr.setWidth("*");
+        ListGridField lside = new ListGridField("riverside",
+                MESSAGES.riverside());
+        lside.setType(ListGridFieldType.TEXT);
+        lside.setWidth(60);
+        ListGridField loc = new ListGridField("from", MESSAGES.location());
+        loc.setType(ListGridFieldType.TEXT);
+        loc.setWidth(80);
+        locationDistanceTable.addCellClickHandler (new CellClickHandler () {
+            public void onCellClick (CellClickEvent e) {
+                if (e.getColNum() == 0) {
+                    Record r = e.getRecord ();
+                    double fromvalue = r.getAttributeAsDouble ("from");
+                    double tovalue = getTo ();
+                    setDistanceValues (fromvalue, tovalue);
+                }
+                else if (e.getColNum() == 1) {
+                    Record r = e.getRecord ();
+                    double fromvalue = getFrom ();
+                    double tovalue = r.getAttributeAsDouble ("to");
+                    setDistanceValues (fromvalue, tovalue);
+                }
+            }
+        });
+        locationDistanceTable.setFields(addfrom, addto2, ldescr, loc, lside);
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        List<Data> items = dataList.getAll();
+
+        Data dFrom = getData(items, "ld_from");
+        Data dTo   = getData(items, "ld_to");
+        Data dStep = getData(items, "ld_step");
+
+        DataItem[] from = dFrom.getItems();
+        DataItem[] to   = dTo.getItems();
+        DataItem[] step = dStep.getItems();
+
+        HLayout layout = new HLayout();
+        layout.setWidth("400px");
+
+        Label   label  = new Label(dataList.getLabel());
+        label.setWidth("200px");
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(from[0].getLabel());
+        sb.append(" " + MESSAGES.unitFrom() + " ");
+        sb.append(to[0].getLabel());
+        sb.append(" " + MESSAGES.unitTo() + " ");
+        sb.append(step[0].getLabel());
+        sb.append(" " + MESSAGES.unitWidth());
+
+        Canvas back = getBackButton(dataList.getState());
+
+        Label selected = new Label(sb.toString());
+        selected.setWidth("130px");
+
+        layout.addMember(label);
+        layout.addMember(selected);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+
+    /**
+     * This method reads the default values defined in the DataItems of the Data
+     * objects in <i>list</i>.
+     *
+     * @param list The DataList container that stores the Data objects.
+     */
+    protected void initDefaults(DataList list) {
+        Data f = getData(list.getAll(), "ld_from");
+        Data t = getData(list.getAll(), "ld_to");
+        Data s = getData(list.getAll(), "ld_step");
+
+        DataItem[] fItems = f.getItems();
+        DataItem[] tItems = t.getItems();
+        DataItem[] sItems = s.getItems();
+
+        min  = Double.valueOf(fItems[0].getStringValue());
+        max  = Double.valueOf(tItems[0].getStringValue());
+        step = Double.valueOf(sItems[0].getStringValue());
+
+        this.from = min;
+        this.to   = max;
+        this.step = step;
+    }
+
+
+    /**
+     * This method greps the Data with name <i>name</i> from the list and
+     * returns it.
+     *
+     * @param items A list of Data.
+     * @param name The name of the Data that we are searching for.
+     *
+     * @return the Data with the name <i>name</i>.
+     */
+    protected Data getData(List<Data> data, String name) {
+        for (Data d: data) {
+            if (name.equals(d.getLabel())) {
+                return d;
+            }
+        }
+
+        return null;
+    }
+
+
+    protected Canvas createWidget(DataList data) {
+        VLayout layout       = new VLayout();
+        container            = new HLayout();
+        Canvas checkboxPanel = createRadioButtonPanel();
+
+        // the initial view will display the location input mode
+        locationPanel = new DoubleArrayPanel(
+                MESSAGES.unitLocation(),
+                getLocationValues(),
+                this);
+        container.addMember(locationPanel);
+
+        layout.addMember(checkboxPanel);
+        layout.addMember(container);
+
+        container.setMembersMargin(30);
+
+        inputTables   = new TabSet();
+        Tab locations = new Tab(MESSAGES.location());
+        Tab distances = new Tab(MESSAGES.distance());
+
+        inputTables.setWidth100();
+        inputTables.setHeight100();
+
+        locations.setPane(locationsTable);
+        distances.setPane(distanceTable);
+
+        inputTables.addTab(locations);
+        inputTables.addTab(distances);
+
+        helperContainer.addChild(inputTables);
+
+        return layout;
+    }
+
+
+    /**
+     * This method returns the selected data.
+     *
+     * @return the selected/inserted data.
+     */
+    public Data[] getData() {
+        // XXX If we have entered a value and click right afterwards on the
+        // 'next' button, the BlurEvent is not fired, and the values are not
+        // saved. So, we gonna save those values explicitly.
+        if (isLocationMode()) {
+            Canvas member = container.getMember(0);
+            if (member instanceof DoubleArrayPanel) {
+                DoubleArrayPanel form = (DoubleArrayPanel) member;
+                saveLocationValues(form);
+            }
+        }
+        else {
+            Canvas member = container.getMember(0);
+            if (member instanceof DoubleRangePanel) {
+                DoubleRangePanel form = (DoubleRangePanel) member;
+                saveDistanceValues(form);
+            }
+        }
+
+        return new Data[] { getDataFrom(), getDataTo(), getDataStep() };
+    }
+
+
+    /**
+     * Returns the Data object for the 'from' attribute.
+     *
+     * @return the Data object for the 'from' attribute.
+     */
+    protected Data getDataFrom() {
+        String value  = Double.valueOf(getFinalFrom()).toString();
+        DataItem item = new DefaultDataItem("ld_from", "ld_from", value);
+        return new DefaultData(
+            "ld_from", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the Data object for the 'to' attribute.
+     *
+     * @return the Data object for the 'to' attribute.
+     */
+    protected Data getDataTo() {
+        String value  = Double.valueOf(getFinalTo()).toString();
+        DataItem item = new DefaultDataItem("ld_to", "ld_to", value);
+        return new DefaultData(
+            "ld_to", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the Data object for the 'step' attribute.
+     *
+     * @return the Data object for the 'step' attribute.
+     */
+    protected Data getDataStep() {
+        String value  = Double.valueOf(getFinalStep()).toString();
+        DataItem item = new DefaultDataItem("ld_step","ld_step", value);
+        return new DefaultData(
+            "ld_step", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the value of 'from' depending on the selected input mode.
+     *
+     * @return the value of 'from' depending on the selected input mode.
+     */
+    protected double getFinalFrom() {
+        if (isLocationMode()) {
+            double[] values = getLocationValues();
+            double   value  = Double.MAX_VALUE;
+
+            for (double v: values) {
+                value = value < v ? value : v;
+            }
+
+            return value;
+        }
+        else {
+            return getFrom();
+        }
+    }
+
+
+    /**
+     * Returns the value of 'to' depending on the selected input mode.
+     *
+     * @return the value of 'to' depending on the selected input mode.
+     */
+    protected double getFinalTo() {
+        if (isLocationMode()) {
+            double[] values = getLocationValues();
+            double   value  = Double.MIN_VALUE;
+
+            for (double v: values) {
+                value = value > v ? value : v;
+            }
+
+            return value;
+        }
+        else {
+            return getTo();
+        }
+    }
+
+
+    /**
+     * Returns the value of 'step' depending on the selected input mode.
+     *
+     * @return the value of 'step' depending on the selected input mode.
+     */
+    protected double getFinalStep() {
+        if (isLocationMode()) {
+            // we have no field to enter the 'step' attribute in the location
+            // mode
+            return 0.0;
+        }
+        else {
+            return getStep();
+        }
+    }
+
+
+    /**
+     * Determines the current input mode.
+     *
+     * @return true, if 'location' is the current input mode, otherwise false.
+     */
+    public boolean isLocationMode() {
+        String inputMode = mode.getValueAsString("mode");
+
+        return inputMode.equals(FIELD_LOCATION) ? true : false;
+    }
+
+
+    /**
+     * This method switches the input mode between location and distance input.
+     *
+     * @param event The click event fired by a RadioButtonGroupItem.
+     */
+    public void onChange(ChangeEvent event) {
+        String value = (String) event.getValue();
+
+        if (value == null) {
+            return;
+        }
+        if (value.equals(FIELD_LOCATION)) {
+            locationPanel = new DoubleArrayPanel(
+                MESSAGES.unitLocation(),
+                getLocationValues(),
+                this);
+
+            container.removeMembers(container.getMembers());
+            container.addMember(locationPanel);
+            while (inputTables.getNumTabs() > 0) {
+                inputTables.removeTab(0);
+            }
+            Tab t1 = new Tab (MESSAGES.location());
+            createLocationTable();
+            t1.setPane(locationsTable);
+            inputTables.addTab(t1);
+            createDistanceTable();
+            Tab t2 = new Tab (MESSAGES.distance());
+            t2.setPane(distanceTable);
+            inputTables.addTab(t2);
+            updateDistanceInfo(tableData);
+
+            helperContainer.addChild(inputTables);
+            inputTables.selectTab(0);
+        }
+        else {
+            distancePanel = new DoubleRangePanel(
+                MESSAGES.unitFrom(), MESSAGES.unitTo(), MESSAGES.unitWidth(),
+                getFrom(), getTo(), getStep(),
+                250,
+                this);
+
+            container.removeMembers(container.getMembers());
+            container.addMember(distancePanel);
+            while (inputTables.getNumTabs () > 0) {
+                inputTables.removeTab(0);
+            }
+            Tab t1 = new Tab(MESSAGES.location ());
+            createLocationTableDistance ();
+            t1.setPane(locationDistanceTable);
+            inputTables.addTab(t1);
+            createDistanceTable ();
+            Tab t2 = new Tab(MESSAGES.distance ());
+            t2.setPane(distanceTable);
+            inputTables.addTab(t2);
+            if (tableData != null) {
+                updateDistanceInfo(tableData);
+            }
+
+            helperContainer.addChild(inputTables);
+            inputTables.selectTab(1);
+        }
+    }
+
+
+    /**
+     * This method is used to validate the inserted data in the form fields.
+     *
+     * @param event The BlurEvent that gives information about the FormItem that
+     * has been modified and its value.
+     */
+    public void onBlur(BlurEvent event) {
+        FormItem item = event.getItem();
+        String  field = item.getFieldName();
+
+        if (field == null) {
+            return;
+        }
+
+        if (field.equals(DoubleArrayPanel.FIELD_NAME)) {
+            DoubleArrayPanel p = (DoubleArrayPanel) event.getForm();
+
+            saveLocationValue(p, item);
+        }
+        else {
+            DoubleRangePanel p = (DoubleRangePanel) event.getForm();
+
+            saveDistanceValue(p, item);
+        }
+    }
+
+
+
+    /**
+     * Validates and stores all values entered in the location mode.
+     *
+     * @param p The DoubleArrayPanel.
+     */
+    protected void saveLocationValues(DoubleArrayPanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) {
+                saveLocationValue(p, item);
+            }
+        }
+    }
+
+
+    /**
+     * Validates and stores all values entered in the distance mode.
+     *
+     * @param p The DoubleRangePanel.
+     */
+    protected void saveDistanceValues(DoubleRangePanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            saveDistanceValue(p, item);
+        }
+    }
+
+
+    /**
+     * Validates and stores a value entered in the location mode.
+     *
+     * @param p The DoubleArrayPanel.
+     * @param item The item that needs to be validated.
+     */
+    protected void saveLocationValue(DoubleArrayPanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setLocationValues(p.getInputValues(item));
+        }
+    }
+
+
+    /**
+     * Validates and stores value entered in the distance mode.
+     *
+     * @param p The DoubleRangePanel.
+     * @param item The item that needs to be validated.
+     */
+    protected void saveDistanceValue(DoubleRangePanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setFrom(p.getFrom());
+            setTo(p.getTo());
+            setStep(p.getStep());
+        }
+    }
+
+
+    /**
+     * This method creates the panel that contains the checkboxes to switch
+     * between the input mode 'location' and 'distance'.
+     *
+     * @return the checkbox panel.
+     */
+    protected Canvas createRadioButtonPanel() {
+        mode = new DynamicForm();
+
+        RadioGroupItem radio = new RadioGroupItem("mode");
+        radio.setShowTitle(false);
+        radio.setVertical(false);
+
+        LinkedHashMap values = new LinkedHashMap();
+        values.put(FIELD_LOCATION, MESSAGES.location());
+        values.put(FIELD_DISTANCE, MESSAGES.distance());
+
+        LinkedHashMap initial = new LinkedHashMap();
+        initial.put("mode", FIELD_LOCATION);
+
+        radio.setValueMap(values);
+        radio.addChangeHandler(this);
+
+        mode.setFields(radio);
+        mode.setValues(initial);
+
+        return mode;
+    }
+
+
+    protected void createDistanceInputPanel() {
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale ();
+        String river  = "";
+
+        ArtifactDescription adescr = artifact.getArtifactDescription();
+        DataList[] data = adescr.getOldData();
+
+        if (data != null && data.length > 0) {
+            for (int i = 0; i < data.length; i++) {
+                DataList dl = data[i];
+                if (dl.getState().equals("state.winfo.river")) {
+                    for (int j = 0; j < dl.size(); j++) {
+                        Data d = dl.get(j);
+                        DataItem[] di = d.getItems();
+                        if (di != null && di.length == 1) {
+                           river = d.getItems()[0].getStringValue();
+                        }
+                    }
+                }
+            }
+        }
+
+        distanceInfoService.getDistanceInfo(url, locale, river,
+            new AsyncCallback<DistanceInfoObject[]>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not recieve distance informations.");
+                    GWT.log(caught.getMessage());
+                }
+
+                public void onSuccess(DistanceInfoObject[] di) {
+                    int num = di != null ? di.length :0;
+                    GWT.log("Recieved " + num + " distance informations.");
+
+                    if (num == 0) {
+                        return;
+                    }
+                    tableData = di;
+                    updateDistanceInfo(di);
+                }
+            }
+        );
+    }
+
+
+    protected void updateDistanceInfo(DistanceInfoObject[] di) {
+        int i = 0;
+        for (DistanceInfoObject dio: di) {
+            if (dio.getTo() != null) {
+                distanceTable.addData(new DistanceInfoRecord(dio));
+            }
+            else {
+                locationsTable.addData(new DistanceInfoRecord(dio));
+                locationDistanceTable.addData(new DistanceInfoRecord(dio));
+            }
+        }
+        return;
+    }
+
+
+    protected double getFrom() {
+        return from;
+    }
+
+
+    protected void setFrom(double from) {
+        this.from = from;
+    }
+
+
+    protected double getTo() {
+        return to;
+    }
+
+
+    protected void setTo(double to) {
+        this.to = to;
+    }
+
+
+    protected double getStep() {
+        return step;
+    }
+
+
+    protected void setStep(double step) {
+        this.step = step;
+    }
+
+
+    protected double[] getLocationValues() {
+        return values;
+    }
+
+
+    protected void setLocationValues(double[] values) {
+        this.values = values;
+        locationPanel.setValues(values);
+    }
+
+
+    protected void setDistanceValues (double from, double to) {
+        setFrom(from);
+        setTo(to);
+        distancePanel.setValues(from, to, getStep());
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MainMenu.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,268 @@
+package de.intevation.flys.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.LocaleInfo;
+import com.google.gwt.user.client.Window;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.util.BooleanCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.shared.model.User;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class MainMenu extends HLayout {
+
+    /** The interface that provides i18n messages. */
+    private FLYSConstants messages = GWT.create(FLYSConstants.class);
+
+    /** An instance to FLYS.*/
+    protected FLYS flys;
+
+    /** The user that is currently logged in. */
+    protected User currentUser;
+
+    /** The label that displays the current logged in user. */
+    protected Label userText;
+
+    /** The button to log the current user out.*/
+    protected Label logout;
+
+    /** The button to add new projects.*/
+    protected Label newProject;
+
+    /** The button to open the project list.*/
+    protected Label projectList;
+
+    /** The button to switch between the english and german version.*/
+    protected Label language;
+
+    /** The button to open an info panel.*/
+    protected Label info;
+
+    /**
+     * The default constructor for creating a new MainMenu.
+     */
+    public MainMenu(FLYS flys) {
+        this.flys     = flys;
+
+        String guest = messages.user() + " " + messages.guest();
+
+        userText    = new Label(guest);
+        newProject  = new Label(messages.new_project());
+        projectList = new Label(messages.manage_projects());
+        logout      = new Label(messages.logout());
+        language    = new Label(messages.switch_language());
+        info        = new Label(messages.info());
+
+        newProject.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                GWT.log("Clicked 'New Project' button.");
+                createNewProject();
+            }
+        });
+
+        projectList.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                GWT.log("Clicked 'Open ProjectList' button.");
+                ProjectList list = getFlys().getProjectList();
+                if (list.isVisible())
+                    list.hide();
+                else
+                    list.show();
+            }
+        });
+
+        logout.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                GWT.log("Clicked 'logout' button.");
+                GWT.log("IMPLEMENT the 'logout' function.");
+            }
+        });
+
+        language.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                LocaleInfo info            = LocaleInfo.getCurrentLocale();
+                final String currentLocale = info.getLocaleName();
+                final String newLocale     = currentLocale.equals("de")
+                    ? "en"
+                    : "de";
+
+                SC.confirm(messages.warning(), messages.warning_language(),
+                    new BooleanCallback() {
+                        public void execute(Boolean value) {
+                            if (value) {
+                                switchLanguage(currentLocale, newLocale);
+                            }
+                        }
+                    });
+            }
+        });
+
+        info.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                GWT.log("Clicked 'info' button.");
+                GWT.log("IMPLEMENT the 'open info panel' function.");
+            }
+        });
+
+        init();
+    }
+
+
+    /**
+     * This method is called by the constructor after creating the necessary
+     * components. It initializes layout specific stuff like width, height,
+     * colors and so on and appends the components.
+     */
+    protected void init() {
+        setStyleName("bgBlueDark");
+        setHeight("25px");
+        setLayoutMargin(5);
+
+        newProject.setStyleName("fontLightSmall");
+        projectList.setStyleName("fontLightSmall");
+        userText.setStyleName("fontLightSmall");
+        newProject.setStyleName("fontLightSmall");
+        logout.setStyleName("fontLightSmall");
+        language.setStyleName("fontLightSmall");
+        info.setStyleName("fontLightSmall");
+
+        projectList.setWidth("140px");
+
+        HLayout leftPanel = new HLayout();
+        leftPanel.setWidth("80%");
+        leftPanel.setMembersMargin(5);
+        leftPanel.addMember(newProject);
+        leftPanel.addMember(projectList);
+
+        userText.setAlign(Alignment.RIGHT);
+        logout.setAlign(Alignment.RIGHT);
+        info.setAlign(Alignment.RIGHT);
+        language.setAlign(Alignment.RIGHT);
+
+        userText.setWidth(200);
+        logout.setWidth(70);
+        info.setWidth(40);
+        language.setWidth(70);
+
+        HLayout rightPanel = new HLayout();
+        rightPanel.setAlign(Alignment.RIGHT);
+        rightPanel.setMembersMargin(3);
+        rightPanel.setLayoutRightMargin(5);
+        rightPanel.addMember(userText);
+        rightPanel.addMember(logout);
+        rightPanel.addMember(language);
+        rightPanel.addMember(info);
+
+        addMember(leftPanel);
+        addMember(rightPanel);
+    }
+
+
+    /**
+     * Returns the FLYS instance stored in this class.
+     *
+     * @return the flys instance.
+     */
+    protected FLYS getFlys() {
+        return flys;
+    }
+
+
+    /**
+     * Set the current {@link User} and call {@link updateCurrentUser()}
+     * afterwards.
+     *
+     * @param user the new user.
+     */
+    public void setCurrentUser(User currentUser) {
+        this.currentUser = currentUser;
+
+        updateCurrentUser();
+    }
+
+
+    /**
+     * Update the text field that shows the current user. If no user is
+     * currently logged in, the text will display {@link FLYSConstants.guest()}.
+     */
+    public void updateCurrentUser() {
+        String name = currentUser != null
+            ? currentUser.getName()
+            : messages.guest();
+
+        GWT.log("Update the current user: " + name);
+
+        String username = messages.user() + " " + name;
+        userText.setContents(username);
+    }
+
+
+    /**
+     * Create a new project by calling FLYS.newProject().
+     */
+    protected void createNewProject() {
+        flys.newProject();
+    }
+
+
+    /**
+     * This method triggers the language switch between the <i>currentLocale</i>
+     * and the <i>newLocale</i>. The switch is done by replacing a "locale="
+     * parameter in the url of the application. We could use the GWT UrlBuilder
+     * class to create a new URL, but - in my eyes - this class is a bit
+     * inconsistens in its implementation.
+     *
+     * @param currentLocale The current locale string (e.g. "en").
+     * @param newLocale The new locale string (e.g. "de").
+     */
+    protected void switchLanguage(String currentLocale, String newLocale) {
+        String newLocation = Window.Location.getHref();
+
+        String oldLocation = newLocation;
+
+        if (newLocation.endsWith("/")) {
+            newLocation = newLocation.substring(0, newLocation.length()-1);
+        }
+
+        String replace     = null;
+        String replaceWith = null;
+
+        if (newLocation.indexOf("&locale=") >= 0) {
+            replace = currentLocale.equals("de")
+                ? "&locale=de"
+                : "&locale=en";
+
+            replaceWith = "&locale=" + newLocale;
+        }
+        else if (newLocation.indexOf("?locale=") >= 0) {
+            replace = currentLocale.equals("de")
+                ? "?locale=de"
+                : "?locale=en";
+
+            replaceWith = "?locale=" + newLocale;
+        }
+        else {
+            newLocation += newLocation.indexOf("?") >= 0
+                ? "&locale=" + newLocale
+                : "?locale=" + newLocale;
+        }
+
+        if (replace != null && replaceWith != null) {
+            newLocation = newLocation.replace(replace, replaceWith);
+        }
+
+        Window.open(newLocation, "_self", "");
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MapSelection.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,79 @@
+package de.intevation.flys.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ImageResource;
+
+import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.client.FLYSImages;
+import de.intevation.flys.client.client.event.HasStepForwardHandlers;
+import de.intevation.flys.client.shared.model.Data;
+
+
+/**
+ * This UIProvider displays the DataItems contained in the Data object in a
+ * combo box as SelectProvider does. Furthermore, there is a map displayed that
+ * lets the user choose a river by selecting it on the map.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class MapSelection extends SelectProvider {
+
+    /** The interface that provides the image resources. */
+    private FLYSImages IMAGES = GWT.create(FLYSImages.class);
+
+    protected ModuleSelection moduleSelection;
+
+    public MapSelection() {
+    }
+
+
+    /**
+     * This method currently returns a
+     * {@link com.smartgwt.client.widgets.form.DynamicForm} that contains all
+     * data items in a combobox stored in <i>data</i>.<br>
+     *
+     * <b>TODO: The map panel for the river selection needs to be
+     * implemented!</b>
+     *
+     * @param data The {@link DataList} object.
+     *
+     * @return a combobox.
+     */
+    protected Canvas createWidget(DataList data) {
+        GWT.log("MapSelection - create()");
+
+        HLayout h = new HLayout();
+        h.setAlign(VerticalAlignment.TOP);
+        h.setHeight(100);
+        moduleSelection = new ModuleSelection();
+
+        Canvas form  = moduleSelection.create(data);
+        form.setWidth(250);
+        form.setLayoutAlign(VerticalAlignment.TOP);
+
+        ImageResource mapRes = IMAGES.riverMap();
+        Img map              = new Img(mapRes.getURL(), 400, 452);
+
+        // TODO implement event handling in the river map
+
+        h.addMember(form);
+        helperContainer.addChild(map);
+
+        return h;
+    }
+
+    protected Data[] getData() {
+        if (moduleSelection != null) {
+            return moduleSelection.getData();
+        }
+        else {
+            return null;
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,150 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.LinkedHashMap;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.client.event.HasStepForwardHandlers;
+
+import de.intevation.flys.client.client.FLYSConstants;
+
+/**
+ * The ModuleSelection combines the river selection and the module selection in
+ * one widget. It will display a vertical splitted widget - the upper part will
+ * render checkboxes for each module, the lower one will display a combobox at
+ * the left and a map panel on the right to choose the river.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ModuleSelection extends MapSelection {
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+
+    /** Constant field name for the plugin selection.*/
+    public static final String FIELD_PLUGIN = "plugin";
+
+    /** Constant value for the WINFO plugin.*/
+    public static final String FIELD_PLUGIN_WINFO = "winfo";
+
+    /** Constant value for the MINFO plugin.*/
+    public static final String FIELD_PLUGIN_MINFO = "minfo";
+
+    /** Constant value for the MAP plugin.*/
+    public static final String FIELD_PLUGIN_MAP   = "map";
+
+    /** Constant value for the CHART plugin.*/
+    public static final String FIELD_PLUGIN_CHART = "chart";
+
+    /** Constant value for the FIX plugin.*/
+    public static final String FIELD_PLUGIN_FIX   = "fix";
+
+
+    /** The module checkboxes.*/
+    protected RadioGroupItem radio;
+
+
+    /**
+     * The default constructor.
+     */
+    public ModuleSelection() {
+    }
+
+
+    /**
+     * This method returns a widget that renders the checkboxes for each module
+     * and the MapSelection that lets the user choose the river.
+     *
+     * @param data The provided rivers.
+     *
+     * @return the module selection combined with the river selection.
+     */
+    public Canvas create(DataList data) {
+        VLayout newLayout = new VLayout();
+        newLayout.setMembersMargin(10);
+        newLayout.setAlign(VerticalAlignment.TOP);
+        Canvas moduleSelection = createWidget();
+
+        moduleSelection.setHeight(100);
+        newLayout.setHeight(70);
+        newLayout.addMember(moduleSelection);
+
+        return newLayout;
+    }
+
+
+    /**
+     * Creates a widget that displays a checkbox for each module.
+     *
+     * @return a widget with checkboxes.
+     */
+    protected Canvas createWidget() {
+        HLayout layout = new HLayout();
+
+        Label      label = new Label(MESSAGES.module_selection());
+        DynamicForm form = new DynamicForm();
+
+        radio = new RadioGroupItem("plugin");
+
+        label.setWidth(50);
+        label.setHeight(25);
+
+        LinkedHashMap values = new LinkedHashMap();
+        values.put(FIELD_PLUGIN_WINFO, messages.winfo());
+        values.put(FIELD_PLUGIN_MINFO, messages.minfo());
+        values.put(FIELD_PLUGIN_FIX, messages.fix());
+        values.put(FIELD_PLUGIN_CHART, messages.chart());
+        values.put(FIELD_PLUGIN_MAP, messages.map());
+
+        radio.setShowTitle(false);
+        radio.setVertical(true);
+        radio.setValueMap(values);
+
+        LinkedHashMap initial = new LinkedHashMap();
+        initial.put(FIELD_PLUGIN, FIELD_PLUGIN_WINFO);
+
+        form.setFields(radio);
+        form.setValues(initial);
+
+        layout.addMember(label);
+        layout.addMember(form);
+
+        return layout;
+    }
+
+
+    /**
+     * This method prepares the data of two widgets - the module selection and
+     * the river selection. The returning field will contain the Data that
+     * represents the module selection at first position, the second position
+     * stores the Data object that represents the river selection.
+     *
+     * @return the Data that was chosen in this widget.
+     */
+    protected Data[] getData() {
+
+        String module = radio.getValueAsString();
+
+        DataItem[] items = new DefaultDataItem[1];
+        items[0]         = new DefaultDataItem(module, module, module);
+
+        Data       data  = new DefaultData("module", null, null, items);
+
+        return new Data[] {data};
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/OutputTab.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,36 @@
+package de.intevation.flys.client.client.ui;
+
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.tab.Tab;
+
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.OutputMode;
+
+
+public class OutputTab extends Tab {
+
+    /** The OutputMode that should be displayed in this tab.*/
+    protected OutputMode mode;
+
+    /** The Collection that should be displayed in this tab.*/
+    protected Collection collection;
+
+
+    /**
+     * The default constructor that creates a new Tab for displaying a specific
+     * OutputMode of a Collection.
+     *
+     * @param title The title of the tab.
+     * @param collection The collection that need to be displayed.
+     * @param outputmode The OutputMode that need to be displayed.
+     */
+    public OutputTab(String title, Collection collection, OutputMode mode) {
+        super(title);
+
+        this.collection = collection;
+        this.mode       = mode;
+
+        setPane(new Label("Implement concrete subclasses to vary the output."));
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,550 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.tab.Tab;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.shared.model.ExportMode;
+import de.intevation.flys.client.shared.model.OutputMode;
+import de.intevation.flys.client.shared.model.River;
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.event.CollectionChangeEvent;
+import de.intevation.flys.client.client.event.CollectionChangeHandler;
+import de.intevation.flys.client.client.event.HasParameterChangeHandler;
+import de.intevation.flys.client.client.event.HasStepBackHandlers;
+import de.intevation.flys.client.client.event.HasStepForwardHandlers;
+import de.intevation.flys.client.client.event.ParameterChangeEvent;
+import de.intevation.flys.client.client.event.ParameterChangeHandler;
+import de.intevation.flys.client.client.event.StepBackEvent;
+import de.intevation.flys.client.client.event.StepBackHandler;
+import de.intevation.flys.client.client.event.StepForwardEvent;
+import de.intevation.flys.client.client.event.StepForwardHandler;
+import de.intevation.flys.client.client.services.AdvanceService;
+import de.intevation.flys.client.client.services.AdvanceServiceAsync;
+import de.intevation.flys.client.client.services.ArtifactService;
+import de.intevation.flys.client.client.services.ArtifactServiceAsync;
+import de.intevation.flys.client.client.services.StepForwardService;
+import de.intevation.flys.client.client.services.StepForwardServiceAsync;
+
+
+public class ParameterList
+extends      Tab
+implements   StepBackHandler, StepForwardHandler, ParameterChangeHandler,
+             HasParameterChangeHandler, CollectionChangeHandler
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    /** The ArtifactService used to communicate with the Artifact server. */
+    protected ArtifactServiceAsync artifactService =
+        GWT.create(ArtifactService.class);
+
+    /** The StepForwardService used to put data into an existing artifact. */
+    protected StepForwardServiceAsync forwardService =
+        GWT.create(StepForwardService.class);
+
+    /** The StepForwardService used to put data into an existing artifact. */
+    protected AdvanceServiceAsync advanceService =
+        GWT.create(AdvanceService.class);
+
+
+    /** The list of ParameterizationChangeHandler.*/
+    protected List<ParameterChangeHandler> parameterHandlers;
+
+    protected FLYS flys;
+
+    protected CollectionView cView;
+
+    protected Artifact artifact;
+
+    protected List<DataList> old;
+    protected DataList   current;
+
+    protected UIProvider uiProvider;
+
+    protected VLayout topLayout;
+    protected VLayout oldItems;
+    protected VLayout currentItems;
+    protected VLayout exportModes;
+    protected Canvas  helperPanel;
+    protected Canvas  tablePanel;
+
+    public ParameterList(FLYS flys, CollectionView cView, String title) {
+        super(title);
+
+        this.cView = cView;
+        this.flys  = flys;
+
+        parameterHandlers = new ArrayList<ParameterChangeHandler>();
+        old               = new ArrayList<DataList>();
+        topLayout         = new VLayout();
+        oldItems          = new VLayout();
+        currentItems      = new VLayout();
+        exportModes       = new VLayout();
+
+        addParameterChangeHandler(this);
+
+        init();
+    }
+
+
+    public ParameterList(
+        FLYS           flys,
+        CollectionView cView,
+        String         title,
+        Artifact       artifact)
+    {
+        super(title);
+
+        this.cView    = cView;
+        this.flys     = flys;
+        this.artifact = artifact;
+
+        parameterHandlers = new ArrayList<ParameterChangeHandler>();
+        old               = new ArrayList<DataList>();
+        topLayout         = new VLayout();
+        oldItems          = new VLayout();
+        currentItems      = new VLayout();
+        exportModes       = new VLayout();
+
+        init();
+
+        addParameterChangeHandler(this);
+
+        setArtifact(artifact);
+    }
+
+
+    protected void init() {
+        HLayout rootLayout = new HLayout();
+        tablePanel = new Canvas();
+        rootLayout.setMembersMargin(20);
+
+        VLayout left = new VLayout();
+
+        if (old == null || old.size() == 0) {
+            oldItems.setHeight(0);
+        }
+
+        oldItems.setMembersMargin(10);
+        currentItems.setAlign(VerticalAlignment.TOP);
+
+        left.setMembersMargin(20);
+        left.setWidth(300);
+
+        left.addMember(oldItems);
+        left.addMember(currentItems);
+        left.addMember(exportModes);
+
+        // This canvas is used to render helper widgets
+        helperPanel = new Canvas();
+        helperPanel.setWidth("*");
+        helperPanel.setHeight100();
+
+        rootLayout.addMember(left);
+        rootLayout.addMember(helperPanel);
+
+        topLayout.addMember(rootLayout);
+        if (artifact == null) {
+            Canvas moduleSelection = renderNew();
+            moduleSelection.setLayoutAlign(VerticalAlignment.TOP);
+            currentItems.addMember(moduleSelection);
+        }
+
+        setPane(topLayout);
+    }
+
+
+    protected void setArtifact(Artifact artifact) {
+        Artifact tmp  = this.artifact;
+        this.artifact = artifact;
+
+        fireParameterChangeEvent(tmp, this.artifact);
+    }
+
+
+    /**
+     * This method registers a new ParameterChangeHandler.
+     *
+     * @param handler The new ParameterChangeHandler.
+     */
+    public void addParameterChangeHandler(ParameterChangeHandler handler) {
+        if (handler != null) {
+            parameterHandlers.add(handler);
+        }
+    }
+
+
+    /**
+     * This method calls the <code>onParameterChange()</code> method of all
+     * registered ParameterChangeHandler.
+     */
+    protected void fireParameterChangeEvent(Artifact old, Artifact newArt) {
+        for (ParameterChangeHandler handler: parameterHandlers) {
+            handler.onParameterChange(new ParameterChangeEvent(old, newArt));
+        }
+    }
+
+
+    /**
+     * This method creates a Canvas displaying the plugins of FLYS combined with
+     * a widget to select a river.
+     *
+     * @return a Canvas that displays the supported plugins and rivers of FLYS.
+     */
+    protected Canvas renderNew() {
+        River[] rivers   = flys.getRivers();
+        DataItem[] items = new DataItem[rivers.length];
+
+        int i = 0;
+        for (River river: rivers) {
+            String name = river.getName();
+            items[i++]  = new DefaultDataItem(name, null, name);
+        }
+
+        Data data = new DefaultData(
+            "river",
+            MSG.river_selection(),
+            null,
+            items);
+
+        LinkSelection widget         = new LinkSelection();
+        HasStepForwardHandlers handler = (HasStepForwardHandlers) widget;
+
+        widget.setContainer(helperPanel);
+
+        handler.addStepForwardHandler(new StepForwardHandler() {
+            public void onStepForward(StepForwardEvent event) {
+                Data[] data = event.getData();
+
+                DataItem[] moduleItems = data[0].getItems();
+                DataItem[] riversItems = data[1].getItems();
+
+                String module = moduleItems[0].getStringValue();
+                String river  = riversItems[0].getStringValue();
+
+                if (module == null) {
+                    // TODO throw / show error!
+                    return;
+                }
+
+                String newTitle = MSG.getString(module);
+                setTitle(newTitle);
+
+                Config config       = Config.getInstance();
+                final String url    = config.getServerUrl();
+                final String locale = config.getLocale();
+
+                final Data[] feedData  = new Data[] { data[1] };
+
+                artifactService.create(
+                    url, locale, module.toLowerCase(),
+                    new AsyncCallback<Artifact>() {
+                        public void onFailure(Throwable caught) {
+                            GWT.log("Could not create the new artifact.");
+                            SC.warn(MSG.getString(caught.getMessage()));
+                        }
+
+                        public void onSuccess(Artifact artifact) {
+                            GWT.log("Successfully created a new artifact.");
+
+                            forwardService.go(url, locale, artifact, feedData,
+                            new AsyncCallback<Artifact>() {
+                                public void onFailure(Throwable caught) {
+                                    GWT.log("Could not feed the artifact.");
+                                    SC.warn(caught.getMessage());
+                                }
+
+                                public void onSuccess(Artifact artifact) {
+                                    GWT.log("Successfully feed the artifact.");
+                                    setArtifact(artifact);
+                                }
+                            });
+                        }
+                });
+            }
+        });
+
+        DataList list = new DataList();
+        list.add(data);
+
+        return widget.create(list);
+    }
+
+
+    protected void clearOldData() {
+        old.clear();
+    }
+
+
+    public void addOldData(DataList old) {
+        if (old != null) {
+            this.old.add(old);
+        }
+
+        refreshOld();
+    }
+
+
+    public void addOldDatas(DataList[] old) {
+        if (old != null && old.length > 0) {
+            for (DataList o: old) {
+                if (!exists(o)) {
+                    GWT.log("Data '" + o.getLabel() + "' is new.");
+                    addOldData(o);
+                }
+            }
+
+            return;
+        }
+
+        addOldData(null);
+    }
+
+
+    public boolean exists(DataList data) {
+        String stateName = data.getState();
+
+        for (DataList o: old) {
+            if (stateName.equals(o.getState())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    public void setCurrentData(DataList current, UIProvider uiProvider) {
+        this.current    = current;
+        this.uiProvider = uiProvider;
+
+        refreshCurrent();
+    }
+
+
+    public void refreshOld() {
+        // XXX maybe we should not remove all items but just add the newest item
+        // to the list.
+        oldItems.removeMembers(oldItems.getMembers());
+
+        for (DataList dataList: old) {
+            HLayout h = new HLayout();
+            h.setAlign(VerticalAlignment.TOP);
+            h.setHeight(20);
+
+            String     provider   = dataList.getUIProvider();
+            UIProvider uiprovider = UIProviderFactory.getProvider(provider);
+            ((HasStepBackHandlers) uiprovider).addStepBackHandler(this);
+
+            oldItems.addMember(uiprovider.createOld(dataList));
+        }
+
+        int minHeight = oldItems.getMinHeight();
+        if (minHeight <= 20) {
+            oldItems.setHeight(20);
+        }
+        else {
+            oldItems.setHeight(minHeight);
+        }
+    }
+
+
+    /**
+     * This method refreshes the part displaying the data of the current state.
+     * The UI is created using the UIProvider stored in the Data object.
+     */
+    public void refreshCurrent() {
+        currentItems.removeMembers(currentItems.getMembers());
+
+        if (current != null && uiProvider != null) {
+            Canvas c = uiProvider.create(current);
+            c.setLayoutAlign(VerticalAlignment.TOP);
+
+            currentItems.addMember(c);
+        }
+        else {
+            currentItems.setHeight(1);
+        }
+    }
+
+
+    /**
+     * This method is called if the user clicks on the 'next' button to advance
+     * to the next state.
+     *
+     * @param event The StepForwardEvent.
+     */
+    public void onStepForward(StepForwardEvent event) {
+        GWT.log("CollectionView - onStepForward()");
+
+        Config config    = Config.getInstance();
+        String serverUrl = config.getServerUrl();
+        String locale    = config.getLocale();
+
+        forwardService.go(serverUrl, locale, artifact, event.getData(),
+            new AsyncCallback<Artifact>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not feed the artifact.");
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(Artifact artifact) {
+                    GWT.log("Successfully feed the artifact.");
+                    setArtifact(artifact);
+                }
+        });
+    }
+
+
+    /**
+     * This method is used to remove all old items from this list after the user
+     * has clicked the step back button.
+     *
+     * @param e The StepBackEvent that holds the identifier of the target state.
+     */
+    public void onStepBack(StepBackEvent e) {
+        final String target    = e.getTarget();
+
+        Config config          = Config.getInstance();
+        final String serverUrl = config.getServerUrl();
+        final String locale    = config.getLocale();
+
+        advanceService.advance(serverUrl, locale, artifact, target,
+            new AsyncCallback<Artifact>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not go back to '" + target + "'");
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(Artifact artifact) {
+                    GWT.log("Successfully step back to '" + target + "'");
+
+                    old.clear();
+                    oldItems.removeMembers(oldItems.getMembers());
+
+                    setArtifact(artifact);
+                }
+            }
+        );
+    }
+
+
+    /**
+     * Implements the onCollectionChange() method to do update the GUI after the
+     * parameterization has changed.
+     *
+     * @param event The ParameterChangeEvent.
+     */
+    public void onParameterChange(ParameterChangeEvent event) {
+        GWT.log("ParameterList.onParameterChange");
+
+        for (Canvas c: helperPanel.getChildren()) {
+            helperPanel.removeChild(c);
+        }
+
+        Artifact art             = event.getNewValue();
+        ArtifactDescription desc = art.getArtifactDescription();
+
+        DataList currentData = desc.getCurrentData();
+        if (currentData != null) {
+            // the user has to enter some attributes
+            String uiProvider   = currentData.getUIProvider();
+            UIProvider provider = UIProviderFactory.getProvider(uiProvider);
+
+            provider.setContainer(helperPanel);
+            provider.setArtifact(art);
+
+            ((HasStepForwardHandlers) provider).addStepForwardHandler(this);
+            ((HasStepBackHandlers) provider).addStepBackHandler(this);
+
+            setCurrentData(currentData, provider);
+        }
+        else {
+            // we have reached a final state with no more user input
+            setCurrentData(null, null);
+        }
+
+        addOldDatas(desc.getOldData());
+    }
+
+
+    public void onCollectionChange(CollectionChangeEvent event) {
+        Collection c = event.getNewValue();
+
+        Map<String, OutputMode> outs = c.getOutputModes();
+        Set<String>             keys = outs.keySet();
+
+        List<ExportMode> exports = new ArrayList<ExportMode>();
+
+        for (String outname: keys) {
+            OutputMode out = outs.get(outname);
+
+            if (out instanceof ExportMode) {
+                exports.add((ExportMode) out);
+            }
+        }
+
+        updateExportModes(c, exports);
+    }
+
+
+    protected void updateExportModes(Collection c, List<ExportMode> exports) {
+        int num = exports != null ? exports.size() : 0;
+        GWT.log("Update export modes: " + num);
+
+        exportModes.removeMembers(exportModes.getMembers());
+
+        if (exports.size() > 0) {
+            exportModes.addMember(new ExportPanel(c, exports));
+        }
+    }
+
+
+    /**
+     * Adds a table to the parameterlist to show calculated data.
+     *
+     * @param table The table data panel.
+     */
+    public void setPanel (TableDataPanel table) {
+        tablePanel = table.create();
+        tablePanel.setHeight100();
+        tablePanel.setWidth100();
+        helperPanel.addChild(tablePanel);
+    }
+
+
+    /**
+     * Removes the table from the parameter list.
+     */
+    public void removePanel() {
+        topLayout.removeMember(tablePanel);
+    }
+
+
+    public boolean hasPanel() {
+        return topLayout.hasMember(tablePanel);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ProjectList.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,304 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.types.SortDirection;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellDoubleClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellDoubleClickHandler;
+import com.smartgwt.client.widgets.grid.events.RowContextClickEvent;
+import com.smartgwt.client.widgets.grid.events.RowContextClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.menu.Menu;
+import com.smartgwt.client.widgets.menu.MenuItem;
+import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
+import com.smartgwt.client.widgets.menu.events.ClickHandler;
+import com.smartgwt.client.types.VerticalAlignment;
+
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.CollectionRecord;
+import de.intevation.flys.client.shared.model.User;
+
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.event.CollectionChangeEvent;
+import de.intevation.flys.client.client.event.CollectionChangeHandler;
+import de.intevation.flys.client.client.services.UserCollectionsService;
+import de.intevation.flys.client.client.services.UserCollectionsServiceAsync;
+
+
+/**
+ * The project list shows a list of projects of a specific user.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ProjectList
+extends      VLayout
+implements   CollectionChangeHandler
+{
+    /** The interface that provides i18n messages. */
+    private FLYSConstants messages = GWT.create(FLYSConstants.class);
+
+    /** The UserService used to retrieve information about the current user. */
+    protected UserCollectionsServiceAsync userCollectionsService =
+        GWT.create(UserCollectionsService.class);
+
+    /** A pointer to the FLYS instance.*/
+    protected FLYS flys;
+
+    /** The user whose projects should be displayed.*/
+    protected User user;
+
+    /** The grid that contains the project rows.*/
+    protected ListGrid grid;
+
+    /**
+     * The default constructor that creates a new ProjectList for a specific
+     * user.
+     *
+     * @param user The user.
+     */
+    public ProjectList(FLYS flys, User user) {
+        this.flys = flys;
+        this.user = user;
+
+        grid = new ListGrid();
+        initGrid();
+        init();
+
+        updateUserCollections();
+    }
+
+
+    protected void initGrid() {
+        grid.setEmptyMessage(messages.no_projects());
+        grid.setLoadingDataMessage(messages.load_projects());
+        grid.setShowRecordComponents(true);
+        grid.setShowRecordComponentsByCell(true);
+        grid.setCanRemoveRecords(false);
+        grid.setShowHeader(false);
+        grid.setWidth100();
+        grid.setHeight100();
+        grid.setSortDirection(SortDirection.DESCENDING);
+        grid.setSortField(0);
+
+        ListGridField date = buildDateField();
+        ListGridField name = buildNameField();
+
+        grid.setFields(date, name);
+
+        grid.addCellDoubleClickHandler(new CellDoubleClickHandler() {
+            public void onCellDoubleClick(CellDoubleClickEvent e) {
+                CollectionRecord record = (CollectionRecord) e.getRecord();
+                String uuid = record != null
+                    ? record.getCollection().identifier()
+                    : "";
+                getFlys().openProject(uuid);
+            }
+        });
+
+        grid.addRowContextClickHandler(new RowContextClickHandler() {
+            public void onRowContextClick(RowContextClickEvent event) {
+                CollectionRecord record = (CollectionRecord) event.getRecord();
+
+                Menu menu = createContextMenu(record);
+                grid.setContextMenu(menu);
+                menu.showContextMenu();
+
+                event.cancel();
+            }
+        });
+    }
+
+
+    public FLYS getFlys() {
+        return flys;
+    }
+
+
+    /**
+     * Creates a new context menu that interacts with a CollectionRecord.
+     *
+     * @param record The selected record.
+     *
+     * @return the context menu with operations that interact with
+     * <i>record</i>.
+     */
+    protected Menu createContextMenu(final CollectionRecord record) {
+        Menu menu = new Menu();
+
+        MenuItem open = new MenuItem(messages.open_project());
+        open.addClickHandler(new ClickHandler() {
+            public void onClick(MenuItemClickEvent evt) {
+                getFlys().openProject(record.getCollection().identifier());
+            }
+        });
+
+        MenuItem del = new MenuItem(messages.delete_project());
+        del.addClickHandler(new ClickHandler() {
+            public void onClick(MenuItemClickEvent evt) {
+                SC.warn("Removing projects is not implemented.");
+            }
+        });
+
+        menu.addItem(open);
+        menu.addItem(del);
+
+        return menu;
+    }
+
+
+    /**
+     * The init() method handles the layout stuff for this widget.
+     */
+    protected void init() {
+        setWidth(300);
+        setHeight100();
+        setShowResizeBar(true);
+        setShowEdges(false);
+        setLayoutMargin(0);
+        setLayoutAlign(VerticalAlignment.TOP);
+
+        Label title = new Label(messages.projects());
+        title.setHeight("20");
+        title.setMargin(5);
+        title.setWidth100();
+        title.setStyleName("fontLightSmall");
+
+        Canvas titleWrapper = new Canvas();
+        titleWrapper.setStyleName("bgBlueDark");
+        titleWrapper.setWidth100();
+        titleWrapper.setHeight("20px");
+        titleWrapper.addChild(title);
+
+        Canvas gridWrapper = new Canvas();
+        gridWrapper.setPadding(0);
+        titleWrapper.setWidth100();
+        gridWrapper.addChild(grid);
+
+        addMember(titleWrapper);
+        addMember(gridWrapper);
+    }
+
+
+    public void onCollectionChange(CollectionChangeEvent event) {
+        GWT.log("ProjectList.onCollectionChange");
+
+        updateUserCollections();
+    }
+
+
+    protected void updateUserCollections() {
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale();
+
+        userCollectionsService.getUserCollections(url, locale, user.identifier(),
+            new AsyncCallback<Collection[]>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not recieve a list of user collections.");
+                    GWT.log(caught.getMessage());
+                }
+
+                public void onSuccess(Collection[] collections) {
+                    int num = collections != null ? collections.length : 0;
+
+                    GWT.log("Received " + num + " user collections.");
+
+                    if (num == 0) {
+                        return;
+                    }
+
+                    updateGrid(collections);
+                }
+            }
+        );
+    }
+
+
+    protected void clearGrid() {
+        ListGridRecord[] records = grid.getRecords();
+
+        for (ListGridRecord record: records) {
+            grid.removeData(record);
+        }
+    }
+
+
+    protected void updateGrid(Collection[] collections) {
+        clearGrid();
+
+        for (Collection c: collections) {
+            grid.addData(new CollectionRecord(c));
+        }
+    }
+
+
+    /**
+     * Builds the field in the grid that displays the creation time of a
+     * project.
+     *
+     * @return the grid field.
+     */
+    protected ListGridField buildDateField() {
+        ListGridField date = new ListGridField("creationTime", "creationTime");
+        date.setType(ListGridFieldType.DATE);
+
+        date.setCellFormatter(new CellFormatter() {
+            public String format(Object value, ListGridRecord rec, int r, int c) {
+                if (value == null) {
+                    return null;
+                }
+
+                DateTimeFormat dtf = DateTimeFormat.getFormat(
+                    messages.datetime_format());
+
+                return dtf.format((Date)value);
+            }
+        });
+
+        date.setWidth(105);
+        date.setAlign(Alignment.LEFT);
+
+        return date;
+    }
+
+
+    /**
+     * Builds the field in the grid that displays the name of a project.
+     *
+     * @return the grid field.
+     */
+    protected ListGridField buildNameField() {
+        ListGridField name = new ListGridField("name", "name");
+        name.setType(ListGridFieldType.TEXT);
+
+        name.setCellFormatter(new CellFormatter() {
+            public String format(Object value, ListGridRecord record, int row, int col) {
+                String n = (String) value;
+                int len  = n.length();
+                int sec  = len - 15;
+                return n.substring(0, 14) + "..." + n.substring(sec, len-1);
+            }
+        });
+
+        name.setWidth(195);
+        name.setAlign(Alignment.LEFT);
+
+        return name;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/SelectProvider.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,177 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+/**
+ * This UIProvider displays the DataItems of the Data object in a combo box.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class SelectProvider
+extends      AbstractUIProvider
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants messages = GWT.create(FLYSConstants.class);
+
+    /** The combobox.*/
+    protected DynamicForm form;
+
+
+    /**
+     * This method currently returns a
+     * {@link com.smartgwt.client.widgets.form.DynamicForm} that contains all
+     * data items in a combobox stored in <i>data</i>.
+     *
+     * @param data The {@link Data} object.
+     *
+     * @return a combobox.
+     */
+    public Canvas create(DataList data) {
+        VLayout v = new VLayout();
+        v.setMembersMargin(10);
+
+        Canvas content = createWidget(data);
+        Canvas button  = getNextButton();
+
+        v.addMember(content);
+        v.addMember(button);
+
+        return v;
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        HLayout layout  = new HLayout();
+        VLayout vLayout = new VLayout();
+        layout.setWidth("400px");
+
+        Label label = new Label(dataList.getLabel());
+        label.setWidth("200px");
+
+        int size = dataList.size();
+        for (int i = 0; i < size; i++) {
+            Data data        = dataList.get(i);
+            DataItem[] items = data.getItems();
+
+            for (DataItem item: items) {
+                HLayout hLayout = new HLayout();
+
+                hLayout.addMember(label);
+                hLayout.addMember(new Label(item.getLabel()));
+
+                vLayout.addMember(hLayout);
+                vLayout.setWidth("130px");
+            }
+        }
+
+        Canvas back = getBackButton(dataList.getState());
+
+        layout.addMember(label);
+        layout.addMember(vLayout);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+
+    /**
+     * This method creates the content of the widget.
+     *
+     * @param data The {@link Data} object.
+     *
+     * @return a combobox.
+     */
+    protected Canvas createWidget(DataList data) {
+        GWT.log("SelectProvider - create()");
+
+        VLayout layout   = new VLayout();
+        layout.setAlign(VerticalAlignment.TOP);
+        layout.setHeight(25);
+
+        LinkedHashMap initial = new LinkedHashMap();
+
+        form = new DynamicForm();
+
+        int size = data.size();
+
+        for (int i = 0; i < size; i++) {
+            Data d = data.get(i);
+
+            Label label = new Label(d.getDescription());
+            label.setValign(VerticalAlignment.TOP);
+            label.setHeight(20);
+
+            ComboBoxItem combobox = new ComboBoxItem(d.getLabel());
+
+            LinkedHashMap<String, String> it = new LinkedHashMap<String, String>();
+
+            boolean firstItem = true;
+
+            for (DataItem item: d.getItems()) {
+                if (firstItem) {
+                    initial.put(d.getLabel(), item.getStringValue());
+                    firstItem = false;
+                }
+
+                it.put(item.getStringValue(), item.getLabel());
+            }
+
+            label.setWidth(50);
+            combobox.setValueMap(it);
+            combobox.setShowTitle(false);
+            form.setItems(combobox);
+
+            layout.addMember(label);
+            layout.addMember(form);
+        }
+
+        form.setValues(initial);
+
+        layout.setAlign(VerticalAlignment.TOP);
+
+        return layout;
+    }
+
+
+    protected Data[] getData() {
+        Map values    = form.getValues();
+        Iterator keys = values.keySet().iterator();
+
+        Data[] list = new Data[values.size()];
+        int       i = 0;
+
+        while (keys.hasNext()) {
+            String fieldname = (String) keys.next();
+            String selection = (String) values.get(fieldname);
+
+            DataItem item    = new DefaultDataItem(fieldname, null, selection);
+
+            list[i++] = new DefaultData(
+                fieldname, null, null, new DataItem[] { item });
+        }
+
+        return list;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,350 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+
+import com.smartgwt.client.types.ListGridFieldType;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.shared.model.DistanceInfoObject;
+import de.intevation.flys.client.shared.model.DistanceInfoRecord;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+
+import de.intevation.flys.client.client.services.DistanceInfoService;
+import de.intevation.flys.client.client.services.DistanceInfoServiceAsync;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.FLYSImages;
+import de.intevation.flys.client.client.Config;
+
+
+/**
+ * This UIProvider creates a widget to enter locations.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class SingleLocationPanel
+extends      AbstractUIProvider
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    /** The interface that provides the image resources. */
+    private FLYSImages IMAGES = GWT.create(FLYSImages.class);
+
+    /** The DistanceInfoService used to retrieve locations about rivers.*/
+    protected DistanceInfoServiceAsync distanceInfoService =
+        GWT.create(DistanceInfoService.class);
+
+    /** A container that will contain the location or the distance panel.*/
+    protected HLayout container;
+
+    /** The values entered in the location mode.*/
+    protected double[] values;
+
+    /** The input panel for locations */
+    protected DoubleArrayPanel locationPanel;
+
+    /** The locations table */
+    protected ListGrid locationTable;
+
+    /** The table data. */
+    protected DistanceInfoObject[] tableData;
+
+    /**
+     * Creates a new LocationDistancePanel instance.
+     */
+    public SingleLocationPanel() {
+        locationTable = new ListGrid();
+        locationTable.setShowHeaderContextMenu(false);
+    }
+
+
+    /**
+     * This method creates a widget that contains a label, a panel with
+     * checkboxes to switch the input mode between location and distance input,
+     * and a the mode specific panel.
+     *
+     * @param data The data that might be inserted.
+     *
+     * @return a panel.
+     */
+    public Canvas create(DataList data) {
+        VLayout layout = new VLayout();
+        layout.setMembersMargin(10);
+
+        initDefaults(data);
+
+        Label label   = new Label(MESSAGES.location ());
+        Canvas widget = createWidget(data);
+        Canvas submit = getNextButton();
+
+        createLocationTable();
+
+        widget.setHeight(50);
+        label.setHeight(25);
+
+        layout.addMember(label);
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        return layout;
+    }
+
+
+    /**
+     * This method creates a table that contains the location values.
+     */
+    protected void createLocationTable() {
+        locationTable.setWidth100();
+        locationTable.setShowRecordComponents(true);
+        locationTable.setShowRecordComponentsByCell(true);
+        locationTable.setHeight100();
+        locationTable.setEmptyMessage(MESSAGES.empty_table());
+
+        ListGridField addLocation = new ListGridField ("", "");
+        addLocation.setType (ListGridFieldType.ICON);
+        addLocation.setWidth ("30");
+        addLocation.addRecordClickHandler (new RecordClickHandler () {
+            public void onRecordClick (RecordClickEvent e) {
+                ListGridRecord[] records = locationTable.getSelection();
+                double[] selected = new double[1];
+                selected[0] = records[0].getAttributeAsDouble("from");
+                setLocationValues(selected);
+            }
+        });
+        addLocation.setCellIcon (IMAGES.markerGreen ().getURL ());
+
+        ListGridField ldescr = new ListGridField("description",
+                MESSAGES.description());
+        ldescr.setType(ListGridFieldType.TEXT);
+        ldescr.setWidth("*");
+        ListGridField lside = new ListGridField("riverside",
+                MESSAGES.riverside());
+        lside.setType(ListGridFieldType.TEXT);
+        lside.setWidth(60);
+        ListGridField loc = new ListGridField("from", MESSAGES.location());
+        loc.setType(ListGridFieldType.TEXT);
+        loc.setWidth(80);
+        locationTable.setFields(addLocation, ldescr, loc, lside);
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        List<Data> items = dataList.getAll();
+        Data dLocation = getData(items, "ld_locations");
+        DataItem[] loc = dLocation.getItems();
+
+        HLayout layout = new HLayout();
+        layout.setWidth("400px");
+
+        Label   label  = new Label(dataList.getLabel());
+        label.setWidth("200px");
+
+        Canvas back = getBackButton(dataList.getState());
+
+        Label selected = new Label(loc[0].getLabel());
+        selected.setWidth("130px");
+
+        layout.addMember(label);
+        layout.addMember(selected);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+
+    /**
+     * This method reads the default values defined in the DataItems of the Data
+     * objects in <i>list</i>.
+     *
+     * @param list The DataList container that stores the Data objects.
+     */
+    protected void initDefaults(DataList list) {
+    }
+
+
+    /**
+     * This method greps the Data with name <i>name</i> from the list and
+     * returns it.
+     *
+     * @param items A list of Data.
+     * @param name The name of the Data that we are searching for.
+     *
+     * @return the Data with the name <i>name</i>.
+     */
+    protected Data getData(List<Data> data, String name) {
+        for (Data d: data) {
+            if (name.equals(d.getLabel())) {
+                return d;
+            }
+        }
+
+        return null;
+    }
+
+
+    protected Canvas createWidget(DataList data) {
+        VLayout layout       = new VLayout();
+        container            = new HLayout();
+
+        // the initial view will display the location input mode
+        locationPanel = new DoubleArrayPanel(
+                MESSAGES.unitLocation(),
+                getLocationValues(),
+                new BlurHandler(){public void onBlur(BlurEvent be) {}});
+        container.addMember(locationPanel);
+
+        layout.addMember(container);
+
+        container.setMembersMargin(30);
+
+        helperContainer.addChild(locationTable);
+        createInputPanel();
+        return layout;
+    }
+
+
+    /**
+     * This method returns the selected data.
+     *
+     * @return the selected/inserted data.
+     */
+    public Data[] getData() {
+        saveLocationValues(locationPanel);
+        double[] values = getLocationValues();
+        Data[] data = new Data[values.length];
+        DataItem item = new DefaultDataItem();
+        for (int i = 0; i < values.length; i++) {
+            item = new DefaultDataItem(
+                "ld_locations",
+                "ld_locations",
+                Double.valueOf(values[i]).toString());
+            data[i] = new DefaultData(
+                "ld_locations",
+                null,
+                null,
+                new DataItem[] {item});
+        }
+        return data;
+    }
+
+
+
+
+    /**
+     * Validates and stores all values entered in the location mode.
+     *
+     * @param p The DoubleArrayPanel.
+     */
+    protected void saveLocationValues(DoubleArrayPanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) {
+                saveLocationValue(p, item);
+            }
+        }
+    }
+
+
+    /**
+     * Validates and stores a value entered in the location mode.
+     *
+     * @param p The DoubleArrayPanel.
+     * @param item The item that needs to be validated.
+     */
+    protected void saveLocationValue(DoubleArrayPanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setLocationValues(p.getInputValues(item));
+        }
+    }
+
+
+    protected void createInputPanel() {
+        Config config = Config.getInstance();
+        String url    = config.getServerUrl();
+        String locale = config.getLocale ();
+        String river  = "";
+
+        ArtifactDescription adescr = artifact.getArtifactDescription();
+        DataList[] data = adescr.getOldData();
+
+        if (data != null && data.length > 0) {
+            for (int i = 0; i < data.length; i++) {
+                DataList dl = data[i];
+                if (dl.getState().equals("state.winfo.river")) {
+                    for (int j = 0; j < dl.size(); j++) {
+                        Data d = dl.get(j);
+                        DataItem[] di = d.getItems();
+                        if (di != null && di.length == 1) {
+                           river = d.getItems()[0].getStringValue();
+                           break;
+                        }
+                    }
+                }
+            }
+        }
+
+        distanceInfoService.getDistanceInfo(url, locale, river,
+            new AsyncCallback<DistanceInfoObject[]>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not recieve location informations.");
+                    GWT.log(caught.getMessage());
+                }
+
+                public void onSuccess(DistanceInfoObject[] di) {
+                    int num = di != null ? di.length :0;
+                    GWT.log("Recieved " + num + " location informations.");
+
+                    if (num == 0) {
+                        return;
+                    }
+                    tableData = di;
+                    updateLocationInfo(di);
+                }
+            }
+        );
+    }
+
+
+    protected void updateLocationInfo(DistanceInfoObject[] di) {
+        int i = 0;
+        for (DistanceInfoObject dio: di) {
+            if (dio.getTo() == null) {
+                locationTable.addData(new DistanceInfoRecord(dio));
+            }
+        }
+        return;
+    }
+
+
+    protected double[] getLocationValues() {
+        return values;
+    }
+
+
+    protected void setLocationValues(double[] values) {
+        this.values = values;
+        locationPanel.setValues(values);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/TableDataPanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,159 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import de.intevation.flys.client.shared.model.DataList;
+
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.Config;
+
+import de.intevation.flys.client.client.services.CSVExportService;
+import de.intevation.flys.client.client.services.CSVExportServiceAsync;
+
+/**
+ * This UIProvider creates a widget that displays calculated data in a table.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class TableDataPanel
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    /** The DistanceInfoService used to retrieve locations about rivers.*/
+    protected CSVExportServiceAsync exportService =
+        GWT.create(CSVExportService.class);
+
+    /** A container that will contain the location or the distance panel.*/
+    protected VLayout container;
+
+    /** The export type.*/
+    protected String name;
+
+    /** The UUID of the collection */
+    protected String uuid;
+
+    /** The table*/
+    protected ListGrid dataTable;
+
+
+    /**
+     * Creates a new LocationDistancePanel instance.
+     */
+    public TableDataPanel() {
+        container = new VLayout();
+        dataTable = new ListGrid();
+        name      = "";
+    }
+
+
+    /**
+     * This method creates a widget that contains a table
+     *
+     * @param data The data that might be inserted.//Use this?
+     *
+     * @return a panel.
+     */
+    public Canvas create() {
+        Config config    = Config.getInstance();
+        String url       = config.getServerUrl();
+        String locale    = config.getLocale ();
+        dataTable.setEmptyMessage(MESSAGES.empty_table());
+        dataTable.setShowHeaderContextMenu(false);
+
+        exportService.getCSV(url, locale, uuid, name,
+            new AsyncCallback<List>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not recieve csv.");
+                    GWT.log(caught.getMessage());
+                }
+
+                public void onSuccess(List l) {
+                    GWT.log("Recieved csv with " + l.size() + " lines.");
+                    setData(l);
+                }
+            }
+        );
+
+        Label l = new Label (MESSAGES.calcTableTitle());
+        l.setHeight(20);
+
+        container.addMember(l);
+        container.addMember(dataTable);
+
+        return container;
+    }
+
+
+    public void setName(String name) {
+      this.name = name;
+    }
+
+    public void setUuid(String uuid) {
+      this.uuid = uuid;
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        return null;
+    }
+
+
+    protected Canvas createWidget(DataList data) {
+        return null;
+    }
+
+
+    /**
+     * This method sets the data to a dynmic table.
+     *
+     * @param list List if String[] containing the data.
+     */
+    public void setData(List list) {
+        String[] header = (String[])list.get(0);
+        ListGridField[] fields = new ListGridField[header.length];
+        for(int i = 0; i < header.length; i++) {
+            ListGridField f = new ListGridField(String.valueOf(i));
+            fields[i] = f;
+            f.setTitle(header[i]);
+        }
+
+        if (header.length == 2) {
+            dataTable.setFields(fields[0], fields[1]);
+        }
+        else if(header.length == 3) {
+            dataTable.setFields(fields[0], fields[1], fields[2]);
+        }
+        else if(header.length == 4) {
+            dataTable.setFields(fields[0], fields[1], fields[2], fields[3]);
+        }
+        else if(header.length == 5) {
+            dataTable.setFields(
+                fields[0],
+                fields[1],
+                fields[2],
+                fields[3],
+                fields[4]);
+        }
+
+        for(int i = 1; i < list.size(); i++) {
+            String[] sItem = (String[])list.get(i);
+            ListGridRecord r = new ListGridRecord();
+            for(int j = 0; j < sItem.length; j++) {
+                r.setAttribute(String.valueOf(j), sItem[j]);
+            }
+            dataTable.addData(r);
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProvider.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,55 @@
+package de.intevation.flys.client.client.ui;
+
+import java.io.Serializable;
+
+import com.smartgwt.client.widgets.Canvas;
+
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.Artifact;
+
+/**
+ * This interface describes a method that creates a Canvas element displaying
+ * DataItems for a current state of the artifact.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface UIProvider extends Serializable {
+
+    /**
+     * This method creates a Canvas element showing the DataItems in
+     * <i>data</i>.
+     *
+     * @param data The DataList object.
+     *
+     * @return the Canvas showing the Data.
+     */
+    public Canvas create(DataList data);
+
+
+    /**
+     * This method creates a Canvas element showing the old Data objects in the
+     * DataList <i>data</i>.
+     *
+     * @param dataList The DataList which elements should be displayed.
+     *
+     * @return a Canvas displaying the Data.
+     */
+    public Canvas createOld(DataList dataList);
+
+
+    /**
+     * This method injects a container that is used to position helper widgets.
+     *
+     * @param container A container that is used to position helper widgets.
+     */
+    public void setContainer(Canvas container);
+
+
+    /**
+     * Sets an artifact that contains the status data information for a project.
+     *
+     * @param artifact The artifact containing status information.
+     */
+    public void setArtifact(Artifact artifact);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,35 @@
+package de.intevation.flys.client.client.ui;
+
+public class UIProviderFactory {
+
+    private UIProviderFactory() {
+    }
+
+    public static UIProvider getProvider(String uiProvider) {
+      System.out.println("Provider: " + uiProvider);
+        if (uiProvider == null || uiProvider.equals("")) {
+            return new SelectProvider();
+        }
+        else if (uiProvider.equals("select_with_map")) {
+            return new MapSelection();
+        }
+        else if (uiProvider.equals("location_distance_panel")) {
+            return new LocationDistancePanel();
+        }
+        else if (uiProvider.equals("location_panel")) {
+            return new SingleLocationPanel();
+        }
+        else if (uiProvider.equals("wq_panel")) {
+            return new WQInputPanel();
+        }
+        else if (uiProvider.equals("wq_panel_adapted")) {
+            return new WQAdaptedInputPanel();
+        }
+        else if (uiProvider.equals("river_panel")) {
+            return new LinkSelection();
+        }
+        else {
+            return new SelectProvider();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/WQAdaptedInputPanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,333 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.TitleOrientation;
+import com.smartgwt.client.types.VerticalAlignment;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
+import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
+import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+
+import de.intevation.flys.client.client.FLYSConstants;
+
+
+/**
+ * This UIProvider creates a widget to enter W or Q data for discharge
+ * longitudinal section computations.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class WQAdaptedInputPanel
+extends      AbstractUIProvider
+implements   ChangeHandler, BlurHandler
+{
+    public static final String FIELD_WQ_MODE = "wq_mode";
+    public static final String FIELD_WQ_W    = "W";
+    public static final String FIELD_WQ_Q    = "Q";
+
+    public static final String GAUGE_SEPARATOR = ":";
+
+    public static final String GAUGE_PART_SEPARATOR = ";";
+
+    public static final String VALUE_SEPARATOR = ",";
+
+    public static final int ROW_HEIGHT = 20;
+
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    /** Stores the input panels related to their keys.*/
+    protected Map<String, DoubleArrayPanel> wqranges;
+
+    /** The RadioGroupItem that determines the w/q input mode.*/
+    protected DynamicForm modes;
+
+
+
+    public WQAdaptedInputPanel() {
+        wqranges = new HashMap<String, DoubleArrayPanel>();
+    }
+
+
+    public Canvas create(DataList data) {
+        Canvas submit = getNextButton();
+        Canvas widget = createWidget(data);
+        Label  label  = new Label(MSG.wqadaptedTitle());
+
+        label.setHeight(25);
+
+        VLayout layout = new VLayout();
+        layout.setMembersMargin(10);
+        layout.setWidth(350);
+
+        layout.addMember(label);
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        return layout;
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        List<Data> all = dataList.getAll();
+        Data    wqData = getData(all, "wq_values");
+        Data    wqMode = getData(all, "wq_mode");
+
+        Canvas back = getBackButton(dataList.getState());
+
+        HLayout valLayout  = new HLayout();
+        HLayout modeLayout = new HLayout();
+        VLayout vlayout    = new VLayout();
+
+        Label wqLabel   = new Label(dataList.getLabel());
+        Label modeLabel = new Label("");
+
+        wqLabel.setValign(VerticalAlignment.TOP);
+
+        wqLabel.setWidth(200);
+        wqLabel.setHeight(25);
+        modeLabel.setHeight(25);
+        modeLabel.setWidth(200);
+
+        valLayout.addMember(wqLabel);
+        valLayout.addMember(createOldWQValues(wqData));
+        valLayout.addMember(back);
+        modeLayout.addMember(modeLabel);
+
+        vlayout.addMember(valLayout);
+        vlayout.addMember(modeLayout);
+
+        return vlayout;
+    }
+
+
+    protected Canvas createOldWQValues(Data wqData) {
+        VLayout layout = new VLayout();
+
+        DataItem item  = wqData.getItems()[0];
+        String   value = item.getStringValue();
+
+        String[] gauges = value.split(GAUGE_SEPARATOR);
+
+        for (String gauge: gauges) {
+            HLayout h = new HLayout();
+
+            String[] parts  = gauge.split(GAUGE_PART_SEPARATOR);
+            String[] values = parts[2].split(VALUE_SEPARATOR);
+
+            Label l = new Label(parts[0] + " - " + parts[1] + ": ");
+
+            StringBuilder sb = new StringBuilder();
+            boolean    first = true;
+
+            for (String v: values) {
+                if (!first) {
+                    sb.append(", ");
+                }
+
+                sb.append(v);
+
+                first = false;
+            }
+
+            Label v = new Label(sb.toString());
+
+            l.setWidth(65);
+            v.setWidth(65);
+
+            h.addMember(l);
+            h.addMember(v);
+
+            layout.addMember(h);
+        }
+
+        return layout;
+    }
+
+
+    protected Canvas createWidget(DataList dataList) {
+        VLayout layout = new VLayout();
+
+        Canvas mode = createMode(dataList);
+        Canvas list = createList(dataList);
+
+        DataItem[] items = getWQItems(dataList);
+        int listHeight   = ROW_HEIGHT * items.length;
+
+        mode.setHeight(25);
+        mode.setWidth(200);
+
+        layout.addMember(mode);
+        layout.addMember(list);
+
+        layout.setHeight(25 + listHeight);
+        layout.setWidth(350);
+
+        return layout;
+    }
+
+
+    protected Canvas createList(DataList dataList) {
+        VLayout layout = new VLayout();
+
+        DataItem[] items = getWQItems(dataList);
+
+        for (DataItem item: items) {
+            String title = item.getLabel();
+
+            DoubleArrayPanel dap = new DoubleArrayPanel(
+                createLineTitle(title), null, this, TitleOrientation.LEFT);
+
+            wqranges.put(title, dap);
+
+            layout.addMember(dap);
+        }
+
+        layout.setHeight(items.length * ROW_HEIGHT);
+
+        return layout;
+    }
+
+
+    protected DataItem[] getWQItems(DataList dataList) {
+        List<Data> data = dataList.getAll();
+
+        for (Data d: data) {
+            String name = d.getLabel();
+
+            if (name.equals(FIELD_WQ_MODE)) {
+                continue;
+            }
+
+            return d.getItems();
+        }
+
+        return null;
+    }
+
+
+    protected Canvas createMode(DataList dataList) {
+        RadioGroupItem wq = new RadioGroupItem(FIELD_WQ_MODE);
+        wq.setShowTitle(false);
+        wq.setVertical(false);
+        wq.setWidth(200);
+
+        LinkedHashMap wqValues = new LinkedHashMap();
+        wqValues.put(FIELD_WQ_W, MSG.wqW());
+        wqValues.put(FIELD_WQ_Q, MSG.wqQ());
+
+        wq.setValueMap(wqValues);
+
+        modes = new DynamicForm();
+        modes.setFields(wq);
+        modes.setWidth(200);
+
+        LinkedHashMap initial = new LinkedHashMap();
+        initial.put(FIELD_WQ_MODE, FIELD_WQ_W);
+        modes.setValues(initial);
+
+        return modes;
+    }
+
+
+    public String createLineTitle(String key) {
+        String[] splitted = key.split(";");
+
+        return splitted[0] + " - " + splitted[1];
+    }
+
+
+    public Data[] getData() {
+        Data mode   = getWQMode();
+        Data values = getWQValues();
+
+        return new Data[] { mode, values };
+    }
+
+
+    protected Data getWQMode() {
+        String wqMode = modes.getValueAsString(FIELD_WQ_MODE);
+        DataItem item = new DefaultDataItem("wq_mode", "wq_mode", wqMode);
+        Data mode = new DefaultData(
+            "wq_mode", null, null, new DataItem[] { item });
+
+        return mode;
+    }
+
+
+    protected Data getWQValues() {
+        String wqvalue = null;
+
+        Iterator<String> iter = wqranges.keySet().iterator();
+        while (iter.hasNext()) {
+            String           key = iter.next();
+            DoubleArrayPanel dap = wqranges.get(key);
+
+            double[] values = dap.getInputValues();
+            if (wqvalue == null) {
+                wqvalue = createValueString(key, values);
+            }
+            else {
+                wqvalue += GAUGE_SEPARATOR + createValueString(key, values);
+            }
+        }
+
+        DataItem valueItem = new DefaultDataItem(
+            "wq_values", "wq_values", wqvalue);
+        Data values = new DefaultData(
+            "wq_values", null, null, new DataItem[] { valueItem });
+
+        return values;
+    }
+
+
+    protected String createValueString(String key, double[] values) {
+        StringBuilder sb = new StringBuilder();
+
+        boolean first = true;
+
+        for (double value: values) {
+            if (!first) {
+                sb.append(",");
+            }
+
+            sb.append(Double.toString(value));
+
+            first = false;
+        }
+
+        return key + ";" + sb.toString();
+    }
+
+
+    public void onChange(ChangeEvent event) {
+        // TODO IMPLEMENT ME
+    }
+
+
+    public void onBlur(BlurEvent event) {
+        DoubleArrayPanel dap = (DoubleArrayPanel) event.getForm();
+        dap.validateForm(event.getItem());
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,1166 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.data.Record;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
+import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
+import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.shared.model.WQInfoObject;
+import de.intevation.flys.client.shared.model.WQInfoRecord;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.types.SelectionStyle;
+
+import de.intevation.flys.client.client.services.WQInfoService;
+import de.intevation.flys.client.client.services.WQInfoServiceAsync;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.FLYSImages;
+import de.intevation.flys.client.client.Config;
+
+
+/**
+ * This UIProvider creates a widget to enter W or Q data.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class WQInputPanel
+extends      AbstractUIProvider
+implements   ChangeHandler, BlurHandler
+{
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGE = GWT.create(FLYSConstants.class);
+
+    /** The interface that provides the image resources. */
+    private FLYSImages IMAGES = GWT.create(FLYSImages.class);
+
+    /** The DistanceInfoService used to retrieve locations about rivers.*/
+    protected WQInfoServiceAsync wqInfoService =
+        GWT.create(WQInfoService.class);
+
+    /** The constant field name for choosing w or q mode.*/
+    public static final String FIELD_WQ = "wq";
+
+    /** The constant field value for W input mode.*/
+    public static final String FIELD_WQ_W = "W";
+
+    /** The constant field value for Q input mode.*/
+    public static final String FIELD_WQ_Q = "Q";
+
+    /** The constant field name for choosing single values or range.*/
+    public static final String FIELD_MODE = "mode";
+
+    /** The constant field value for single input mode.*/
+    public static final String FIELD_MODE_SINGLE = "single";
+
+    /** The constant field value for range input mode.*/
+    public static final String FIELD_MODE_RANGE = "range";
+
+    /** The constant value that determines the width of the left panel.*/
+    public static final int WIDTH_LEFT = 200;
+
+
+    /** The container that manages the w and q panels.*/
+    protected HLayout container;
+
+    /** The RadioGroupItem that determines the w/q input mode.*/
+    protected DynamicForm modes;
+
+    /** The min values for the 'from' property in the W-Range input mode.*/
+    protected double minW;
+
+    /** The min values for the 'from' property in the Q-Range input mode.*/
+    protected double minQ;
+
+    /** The max values for the 'from' property in the W-Range input mode.*/
+    protected double maxW;
+
+    /** The max values for the 'from' property in the Q-Range input mode.*/
+    protected double maxQ;
+
+    /** The 'from' value entered in the range W mode.*/
+    protected double fromW;
+
+    /** The 'to' value entered in the range W mode.*/
+    protected double toW;
+
+    /** The 'step' value entered in the range W mode.*/
+    protected double stepW;
+
+    /** The values entered in the single W mode.*/
+    protected double[] valuesW;
+
+    /** The 'from' value entered in the range Q mode.*/
+    protected double fromQ;
+
+    /** The 'to' value entered in the range Q mode.*/
+    protected double toQ;
+
+    /** The 'step' value entered in the range Q mode.*/
+    protected double stepQ;
+
+    /** The values entered in the single Q mode.*/
+    protected double[] valuesQ;
+
+    /** The input panel for W values*/
+    protected DoubleArrayPanel wArrayPanel;
+
+    /** The input panel for q values*/
+    protected DoubleArrayPanel qArrayPanel;
+
+    /** The input panel for w range*/
+    protected DoubleRangePanel wRangePanel;
+
+    /** The input panel for q range*/
+    protected DoubleRangePanel qRangePanel;
+
+    /** The WQ Data*/
+    protected WQInfoObject[] tableData;
+
+    /** The WQ Input Table*/
+    protected ListGrid wqTable;
+
+    /** The WQ input table for ranges.*/
+    protected ListGrid wqRangeTable;
+
+    /**
+     * Creates a new WQInputPanel instance.
+     */
+    public WQInputPanel() {
+        wqTable      = new ListGrid();
+        wqRangeTable = new ListGrid();
+        wqTable.setShowHeaderContextMenu(false);
+        wqRangeTable.setShowHeaderContextMenu(false);
+    }
+
+
+    /**
+     * This method calls createWidget and puts a 'next' button to the bottom.
+     *
+     * @param data The data that is displayed.
+     *
+     * @return the widget.
+     */
+    public Canvas create(DataList data) {
+        initDefaults(data);
+
+
+        Canvas  widget = createWidget(data);
+        Canvas  submit = getNextButton();
+        Label   label  = new Label(MESSAGE.wqTitle());
+
+        label.setHeight(25);
+
+        VLayout layout = new VLayout();
+        layout.setMembersMargin(10);
+
+        layout.addMember(label);
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        return layout;
+    }
+
+
+    public Canvas createOld(DataList dataList) {
+        List<Data> items = dataList.getAll();
+
+        Data dMode      = getData(items, "wq_mode");
+        Data dSelection = getData(items, "wq_selection");
+        Data dSingle    = getData(items, "wq_single");
+        Data dFrom      = getData(items, "wq_from");
+        Data dTo        = getData(items, "wq_to");
+        Data dStep      = getData(items, "wq_step");
+
+        DataItem[] mode = dMode.getItems();
+        String strMode  = mode[0].getStringValue();
+        boolean wMode   = strMode.equals(FIELD_WQ_W);
+
+        HLayout layout = new HLayout();
+        layout.setWidth("400px");
+
+        Label label  = new Label(dataList.getLabel());
+        label.setWidth("200px");
+
+        String text = null;
+
+        DataItem[] selItem = dSelection.getItems();
+        String     sel     = selItem != null
+            ? selItem[0].getStringValue()
+            : "";
+
+        if (sel.equals("single")) {
+            DataItem[] single = dSingle.getItems();
+
+            text = wMode
+                ? createWString(single[0])
+                : createQString(single[0]);
+        }
+        else {
+            DataItem[] from = dFrom.getItems();
+            DataItem[] to   = dTo.getItems();
+            DataItem[] step = dStep.getItems();
+
+            text = wMode
+                ? createWString(from[0], to[0], step[0])
+                : createQString(from[0], to[0], step[0]);
+        }
+
+        Label selected = new Label(text);
+        selected.setWidth("130px");
+
+        Canvas back = getBackButton(dataList.getState());
+
+        layout.addMember(label);
+        layout.addMember(selected);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+
+    protected void createWQInputPanel() {
+        wqTable.setWidth100();
+        wqTable.setShowRecordComponents(true);
+        wqTable.setShowRecordComponentsByCell(true);
+        wqTable.setHeight100();
+        wqTable.setEmptyMessage(MESSAGE.empty_table());
+
+        wqRangeTable.setWidth100();
+        wqRangeTable.setShowRecordComponents(true);
+        wqRangeTable.setShowRecordComponentsByCell(true);
+        wqRangeTable.setHeight100();
+        wqRangeTable.setEmptyMessage(MESSAGE.empty_table());
+
+        ListGridField addWQ = new ListGridField("", "");
+        addWQ.setType(ListGridFieldType.ICON);
+        addWQ.setWidth(30);
+
+        CellClickHandler cch = new CellClickHandler() {
+            public void onCellClick(CellClickEvent e) {
+                if (e.getColNum() == 0 && e.getRecord().getEnabled ()) {
+                    Record r = e.getRecord ();
+                    double val = r.getAttributeAsDouble("value");
+                    if(isWMode() && !isRangeMode()) {
+                        double[] in = wArrayPanel.getInputValues();
+                        int size = 0;
+                        if (in == null) {
+                            double[] vals = new double[1];
+                            vals[0] = val;
+                            wArrayPanel.setValues(vals);
+                            setSingleW(vals);
+                        }
+                        else {
+                            double[] vals = new double[in.length+1];
+                            for(int i = 0; i < in.length; i++) {
+                                vals[i] = in[i];
+                            }
+                            vals[in.length] = val;
+                            wArrayPanel.setValues(vals);
+                            setSingleW(vals);
+                        }
+                    }
+                    else if (!isWMode() && !isRangeMode()) {
+                        double[] in = qArrayPanel.getInputValues();
+                        int size = 0;
+                        if (in == null) {
+                            double[] vals = new double[1];
+                            vals[0] = val;
+                            qArrayPanel.setValues(vals);
+                            setSingleQ(vals);
+                        }
+                        else {
+                            double[] vals = new double[in.length+1];
+                            for(int i = 0; i < in.length; i++) {
+                                vals[i] = in[i];
+                            }
+                            vals[in.length] = val;
+                            qArrayPanel.setValues(vals);
+                            setSingleQ(vals);
+                        }
+                    }
+                }
+            }
+        };
+
+        CellClickHandler cchRange = new CellClickHandler() {
+            public void onCellClick(CellClickEvent e) {
+                if (e.getColNum() == 0 && e.getRecord().getEnabled ()) {
+                    Record r = e.getRecord ();
+                    double val = r.getAttributeAsDouble("value");
+                    if(isWMode() && isRangeMode()) {
+                        wRangePanel.setValues(
+                            val,
+                            wRangePanel.getTo(),
+                            wRangePanel. getStep());
+                    }
+                    else if (!isWMode() && isRangeMode()) {
+                        qRangePanel.setValues(
+                            val,
+                            qRangePanel.getTo(),
+                            qRangePanel.getStep());
+                    }
+                }
+                if (e.getColNum() == 1 && e.getRecord().getEnabled()) {
+                    Record r = e.getRecord ();
+                    double val = r.getAttributeAsDouble("value");
+                    if (isWMode() && isRangeMode()) {
+                         wRangePanel.setValues(
+                             wRangePanel.getFrom(),
+                             val,
+                             wRangePanel.getStep());
+                    }
+                    else if(!isWMode() && isRangeMode()) {
+                        qRangePanel.setValues(
+                            qRangePanel.getFrom(),
+                            val,
+                            qRangePanel.getStep());
+                    }
+                }
+            }
+        };
+        wqTable.addCellClickHandler(cch);
+        wqRangeTable.addCellClickHandler(cchRange);
+        addWQ.setCellIcon (IMAGES.markerGreen().getURL());
+
+        ListGridField addWQMin = new ListGridField("", "");
+        addWQMin.setType(ListGridFieldType.ICON);
+        addWQMin.setWidth(30);
+        ListGridField addWQMax = new ListGridField("", "");
+        addWQMax.setType(ListGridFieldType.ICON);
+        addWQMax.setWidth(30);
+
+        wqRangeTable.addCellClickHandler(cch);
+        addWQMin.setCellIcon(IMAGES.markerGreen().getURL());
+        addWQMax.setCellIcon(IMAGES.markerRed().getURL());
+
+        ListGridField name = new ListGridField("name", MESSAGE.name());
+        name.setType(ListGridFieldType.TEXT);
+        name.setWidth("*");
+        ListGridField type = new ListGridField("type", MESSAGE.type());
+        type.setType(ListGridFieldType.TEXT);
+        type.setWidth("50");
+        ListGridField value = new ListGridField("value", MESSAGE.wq_value());
+        value.setType(ListGridFieldType.TEXT);
+        type.setWidth("50");
+
+        ListGridField name_r = new ListGridField("name", MESSAGE.name());
+        name_r.setType(ListGridFieldType.TEXT);
+        name_r.setWidth("*");
+        ListGridField type_r = new ListGridField("type", MESSAGE.type());
+        type_r.setType(ListGridFieldType.TEXT);
+        type_r.setWidth("50");
+        ListGridField value_r = new ListGridField("value", MESSAGE.wq_value());
+        value_r.setType(ListGridFieldType.TEXT);
+        type_r.setWidth("50");
+
+        wqTable.setSelectionType(SelectionStyle.SINGLE);
+        wqRangeTable.setSelectionType(SelectionStyle.SINGLE);
+        wqTable.setFields(addWQ, name, type, value);
+        wqRangeTable.setFields(addWQMin, addWQMax, name_r, type_r, value_r);
+    }
+
+    /**
+     * This method reads the default values defined in the DataItems of the Data
+     * objects in <i>list</i>.
+     *
+     * @param list The DataList container that stores the Data objects.
+     */
+    protected void initDefaults(DataList list) {
+        Data f = getData(list.getAll(), "wq_from");
+        Data t = getData(list.getAll(), "wq_to");
+        Data s = getData(list.getAll(), "wq_step");
+
+        DataItem fQItem = getDataItem(f.getItems(), "minQ");
+        DataItem fWItem = getDataItem(f.getItems(), "minW");
+        DataItem tQItem = getDataItem(t.getItems(), "maxQ");
+        DataItem tWItem = getDataItem(t.getItems(), "maxW");
+        DataItem sQItem = getDataItem(s.getItems(), "stepQ");
+        DataItem sWItem = getDataItem(s.getItems(), "stepW");
+
+        minW  = Double.valueOf(fWItem.getStringValue());
+        maxW  = Double.valueOf(tWItem.getStringValue());
+        stepW = Double.valueOf(sWItem.getStringValue());
+
+        minQ  = Double.valueOf(fQItem.getStringValue());
+        maxQ  = Double.valueOf(tQItem.getStringValue());
+        stepQ = Double.valueOf(sQItem.getStringValue());
+
+        this.fromW = minW;
+        this.toW   = maxW;
+        this.stepW = stepW;
+
+        this.fromQ = minQ;
+        this.toQ   = maxQ;
+        this.stepQ = stepQ;
+    }
+
+
+    protected String createWString(DataItem from, DataItem to, DataItem step) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(from.getLabel());
+        sb.append(" " + MESSAGE.unitWFrom() + " ");
+        sb.append(to.getLabel());
+        sb.append(" " + MESSAGE.unitWTo() + " ");
+        sb.append(step.getLabel());
+        sb.append(" " + MESSAGE.unitWStep());
+
+        return sb.toString();
+    }
+
+
+    protected String createWString(DataItem single) {
+        return single.getLabel();
+    }
+
+
+    protected String createQString(DataItem from, DataItem to, DataItem step) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(from.getLabel());
+        sb.append(" " + MESSAGE.unitQFrom() + " ");
+        sb.append(to.getLabel());
+        sb.append(" " + MESSAGE.unitQTo() + " ");
+        sb.append(step.getLabel());
+        sb.append(" " + MESSAGE.unitQStep());
+
+        return sb.toString();
+    }
+
+
+    protected String createQString(DataItem single) {
+        return single.getLabel();
+    }
+
+
+    /**
+     * This method creates the whole widget. There is a panel on the left, that
+     * allows the user to enter values manually by keyboard. On the right, there
+     * is a table that allows the user to enter values by mouse click.
+     *
+     * @param data The data that is displayed in the table on the right.
+     *
+     * @return the widget.
+     */
+    protected Canvas createWidget(DataList data) {
+        VLayout layout  = new VLayout();
+        container       = new HLayout();
+        Canvas modeForm = createModePanel();
+
+        container.setMembersMargin(30);
+        createWQInputTable();
+        createWQInputPanel();
+        // the initial panel is the Single-W panel.
+        double[] values = getSingleW();
+        wArrayPanel = new DoubleArrayPanel(
+            MESSAGE.unitWSingle(), values, this);
+        container.addMember(wArrayPanel);
+        helperContainer.addChild(wqTable);
+        layout.addMember(modeForm);
+        layout.addMember(container);
+
+        return layout;
+    }
+
+
+    /**
+     * This method creates the mode panel. It contains two radio button panels
+     * that allows the user to switch the input mode between w/q and
+     * single/range input.
+     *
+     * @return a panel.
+     */
+    protected Canvas createModePanel() {
+        RadioGroupItem wq = new RadioGroupItem(FIELD_WQ);
+        wq.setShowTitle(false);
+        wq.setVertical(false);
+        wq.setWidth(WIDTH_LEFT);
+
+        RadioGroupItem mode = new RadioGroupItem(FIELD_MODE);
+        mode.setShowTitle(false);
+        mode.setVertical(false);
+        mode.setWidth(WIDTH_LEFT);
+
+        LinkedHashMap wqValues = new LinkedHashMap();
+        wqValues.put(FIELD_WQ_W, MESSAGE.wqW());
+        wqValues.put(FIELD_WQ_Q, MESSAGE.wqQ());
+
+        LinkedHashMap modeValues = new LinkedHashMap();
+        modeValues.put(FIELD_MODE_SINGLE, MESSAGE.wqSingle());
+        modeValues.put(FIELD_MODE_RANGE, MESSAGE.wqRange());
+
+        wq.setValueMap(wqValues);
+        mode.setValueMap(modeValues);
+
+        wq.addChangeHandler(this);
+        mode.addChangeHandler(this);
+
+        modes = new DynamicForm();
+        modes.setFields(wq, mode);
+        modes.setWidth(WIDTH_LEFT);
+        modes.setNumCols(1);
+
+        LinkedHashMap initial = new LinkedHashMap();
+        initial.put(FIELD_WQ, FIELD_WQ_W);
+        initial.put(FIELD_MODE, FIELD_MODE_SINGLE);
+        modes.setValues(initial);
+
+        return modes;
+    }
+
+
+    /**
+     * This method returns the selected data.
+     *
+     * @return the selected/inserted data.
+     */
+    public Data[] getData() {
+        // XXX If we have entered a value and click right afterwards on the
+        // 'next' button, the BlurEvent is not fired, and the values are not
+        // saved. So, we gonna save those values explicitly.
+        if (!isRangeMode()) {
+            Canvas member = container.getMember(0);
+            if (member instanceof DoubleArrayPanel) {
+                DoubleArrayPanel form = (DoubleArrayPanel) member;
+                if (isWMode()) {
+                    saveSingleWValues(form);
+                }
+                else {
+                    saveSingleQValues(form);
+                }
+            }
+
+            return new Data[] {
+                getDataMode(),
+                getDataSelectionMode(),
+                getDataSingle() };
+        }
+        else {
+            Canvas member = container.getMember(0);
+            if (member instanceof DoubleRangePanel) {
+                DoubleRangePanel form = (DoubleRangePanel) member;
+
+                if (isWMode()) {
+                    saveRangeWValues(form);
+                }
+                else {
+                    saveRangeQValues(form);
+                }
+            }
+
+            return new Data[] {
+                getDataMode(),
+                getDataSelectionMode(),
+                getDataFrom(),
+                getDataTo(),
+                getDataStep() };
+        }
+    }
+
+
+    /**
+     * Returns the Data object for the 'mode' attribute.
+     *
+     * @return the Data object for the 'mode' attribute.
+     */
+    protected Data getDataMode() {
+        String wqMode = modes.getValueAsString(FIELD_WQ);
+        DataItem item = new DefaultDataItem("wq_mode", "wq_mode", wqMode);
+        return new DefaultData(
+            "wq_mode", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the Data object for the 'mode' attribute.
+     *
+     * @return the Data object for the 'mode' attribute.
+     */
+    protected Data getDataSelectionMode() {
+        String wqSelection = modes.getValueAsString(FIELD_MODE);
+        DataItem item = new DefaultDataItem(
+            "wq_selection", "wq_selection", wqSelection);
+
+        return new DefaultData(
+            "wq_selection", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the data object for the 'single' attribute.
+     *
+     * @return the Data object for the 'single' attribute.
+     */
+    protected Data getDataSingle() {
+        double[] values  = getFinalSingle();
+        StringBuilder sb = new StringBuilder();
+        for (double value: values) {
+            sb.append(Double.toString(value));
+            sb.append(" ");
+        }
+
+        DataItem item = new DefaultDataItem(
+            "wq_single", "wq_single", sb.toString());
+
+        return new DefaultData(
+            "wq_single", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the Data object for the 'from' attribute.
+     *
+     * @return the Data object for the 'from' attribute.
+     */
+    protected Data getDataFrom() {
+        String value  = Double.valueOf(getFinalFrom()).toString();
+        DataItem item = new DefaultDataItem("wq_from", "wq_from", value);
+        return new DefaultData(
+            "wq_from", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the Data object for the 'to' attribute.
+     *
+     * @return the Data object for the 'to' attribute.
+     */
+    protected Data getDataTo() {
+        String value  = Double.valueOf(getFinalTo()).toString();
+        DataItem item = new DefaultDataItem("wq_to", "wq_to", value);
+        return new DefaultData(
+            "wq_to", null, null, new DataItem[] { item });
+    }
+
+
+    /**
+     * Returns the Data object for the 'step' attribute.
+     *
+     * @return the Data object for the 'step' attribute.
+     */
+    protected Data getDataStep() {
+        String value  = Double.valueOf(getFinalStep()).toString();
+        DataItem item = new DefaultDataItem("wq_step","wq_step", value);
+        return new DefaultData(
+            "wq_step", null, null, new DataItem[] { item });
+    }
+
+
+    protected double[] getFinalSingle() {
+        boolean wMode = isWMode();
+
+        return wMode ? getSingleW() : getSingleQ();
+    }
+
+
+    /**
+     * Returns the value of 'from' depending on the selected input mode.
+     *
+     * @return the value of 'from' depending on the selected input mode.
+     */
+    protected double getFinalFrom() {
+        boolean wMode     = isWMode();
+        boolean rangeMode = isRangeMode();
+
+        if (rangeMode) {
+            return wMode ? getFromW() : getFromQ();
+
+        }
+        else {
+            double[] values = wMode ? getSingleW() : getSingleQ();
+            double   value  = Double.MAX_VALUE;
+
+            for (double v: values) {
+                value = value < v ? value : v;
+            }
+
+            return value;
+        }
+    }
+
+
+    /**
+     * Returns the value of 'to' depending on the selected input mode.
+     *
+     * @return the value of 'to' depending on the selected input mode.
+     */
+    protected double getFinalTo() {
+        boolean wMode     = isWMode();
+        boolean rangeMode = isRangeMode();
+
+        if (rangeMode) {
+            return wMode ? getToW() : getToQ();
+
+        }
+        else {
+            double[] values = wMode ? getSingleW() : getSingleQ();
+            double   value  = Double.MIN_VALUE;
+
+            for (double v: values) {
+                value = value > v ? value : v;
+            }
+
+            return value;
+        }
+    }
+
+
+    /**
+     * Returns the value of 'step' depending on the selected input mode.
+     *
+     * @return the value of 'step' depending on the selected input mode.
+     */
+    protected double getFinalStep() {
+        boolean wMode     = isWMode();
+        boolean rangeMode = isRangeMode();
+
+        if (rangeMode) {
+            return wMode ? getStepW() : getStepQ();
+        }
+        else {
+            // we have no field to enter the 'step' attribute in the
+            // single mode
+            return 0d;
+        }
+    }
+
+
+    /**
+     * Determines the range/single mode.
+     *
+     * @return true if the range mode is activated.
+     */
+    public boolean isRangeMode() {
+        String rMode = modes.getValueAsString(FIELD_MODE);
+
+        return rMode.equals(FIELD_MODE_RANGE) ? true : false;
+    }
+
+
+    /**
+     * Determines the w/q mode.
+     *
+     * @return true, if the W mode is activated.
+     */
+    public boolean isWMode() {
+        String wq = modes.getValueAsString(FIELD_WQ);
+
+        return wq.equals(FIELD_WQ_W) ? true : false;
+    }
+
+
+    /**
+     * This method changes the lower panel with the input fields depending on
+     * the combination of the two radio button panels.
+     *
+     * @param event The ChangeEvent.
+     */
+    public void onChange(ChangeEvent event) {
+        DynamicForm form = event.getForm();
+        FormItem    item = event.getItem();
+
+        String wqMode    = null;
+        String inputMode = null;
+
+        if (item.getFieldName().equals(FIELD_MODE)) {
+            wqMode    = form.getValueAsString(FIELD_WQ);
+            inputMode = (String) event.getValue();
+        }
+        else {
+            wqMode    = (String) event.getValue();
+            inputMode = form.getValueAsString(FIELD_MODE);
+        }
+
+        updatePanels(wqMode, inputMode);
+    }
+
+
+    protected void updatePanels(String wqMode, String inputMode) {
+        container.removeMembers(container.getMembers());
+        GWT.log("updating Panel and Table");
+        if (wqMode.equals(FIELD_WQ_W)) {
+            if (inputMode.equals(FIELD_MODE_SINGLE)) {
+                // Single W mode
+                double[] values = getSingleW();
+
+                wArrayPanel = new DoubleArrayPanel(
+                    MESSAGE.unitWSingle(), values, this);
+
+                container.addMember(wArrayPanel);
+                helperContainer.addChild(wqTable);
+                int size = wqTable.getRecords().length;
+                for(int i = 0; i < size; i++) {
+                    ListGridRecord r = wqTable.getRecord(i);
+                    String type = r.getAttributeAsString("type");
+                    if (type.equals("W")) {
+                        wqTable.getRecord(i).setEnabled(true);
+                    }
+                    else if(type.equals("D") || type.equals("Q")) {
+                        wqTable.getRecord(i).setEnabled(false);
+                    }
+                }
+            }
+            else {
+                // Range W mode
+                double from = getFromW();
+                double to   = getToW();
+                double step = getStepW();
+
+                wRangePanel = new DoubleRangePanel(
+                    MESSAGE.unitWFrom(), MESSAGE.unitWTo(), MESSAGE.unitWStep(),
+                    from, to, step,
+                    250,
+                    this);
+                container.addMember(wRangePanel);
+                helperContainer.addChild(wqRangeTable);
+                int size = wqRangeTable.getRecords().length;
+                for(int i = 0; i < size; i++) {
+                    ListGridRecord r = wqRangeTable.getRecord(i);
+                    String type = r.getAttributeAsString("type");
+                    if (type.equals("W")) {
+                        wqRangeTable.getRecord(i).setEnabled(true);
+                    }
+                    else if(type.equals("D") || type.equals("Q")) {
+                        wqRangeTable.getRecord(i).setEnabled(false);
+                    }
+                }
+            }
+        }
+        else {
+            if (inputMode.equals(FIELD_MODE_SINGLE)) {
+                // Single Q mode
+                double[] values = getSingleQ();
+
+                qArrayPanel = new DoubleArrayPanel(
+                    MESSAGE.unitQSingle(), values, this);
+                container.addMember(qArrayPanel);
+                helperContainer.addChild(wqTable);
+                int size = wqTable.getRecords().length;
+                for(int i = 0; i < size; i++) {
+                    ListGridRecord r = wqTable.getRecord(i);
+                    String type = r.getAttributeAsString("type");
+                    if (type.equals("W")) {
+                        wqTable.getRecord(i).setEnabled(false);
+                    }
+                    else if(type.equals("D") || type.equals("Q")) {
+                        wqTable.getRecord(i).setEnabled(true);
+                    }
+            }
+
+            }
+            else {
+                // Range Q mode
+                double from = getFromQ();
+                double to   = getToQ();
+                double step = getStepQ();
+
+                qRangePanel = new DoubleRangePanel(
+                    MESSAGE.unitQFrom(), MESSAGE.unitQTo(), MESSAGE.unitQStep(),
+                    from, to, step,
+                    250,
+                    this);
+                container.addMember(qRangePanel);
+                helperContainer.addChild(wqRangeTable);
+                int size = wqRangeTable.getRecords().length;
+                for(int i = 0; i < size; i++) {
+                    ListGridRecord r = wqRangeTable.getRecord(i);
+                    String type = r.getAttributeAsString("type");
+                    if (type.equals("W")) {
+                        wqRangeTable.getRecord(i).setEnabled(false);
+                    }
+                    else if(type.equals("D") || type.equals("Q")) {
+                        wqRangeTable.getRecord(i).setEnabled(true);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * This method is called if the value of one of the input fields might have
+     * changed. The entered values are validated and stored.
+     *
+     * @param event The BlurEvent.
+     */
+    public void onBlur(BlurEvent event) {
+        DynamicForm form = event.getForm();
+        FormItem    item = event.getItem();
+
+        String wqMode    = (String) modes.getValue(FIELD_WQ);
+        String inputMode = (String) modes.getValue(FIELD_MODE);
+
+        if (wqMode.equals(FIELD_WQ_W)) {
+            if (inputMode.equals(FIELD_MODE_SINGLE)) {
+                DoubleArrayPanel p = (DoubleArrayPanel) form;
+                saveSingleWValue(p, item);
+            }
+            else {
+                DoubleRangePanel p = (DoubleRangePanel) form;
+                saveRangeWValue(p, item);
+            }
+        }
+        else {
+            if (inputMode.equals(FIELD_MODE_SINGLE)) {
+                DoubleArrayPanel p = (DoubleArrayPanel) form;
+                saveSingleQValue(p, item);
+            }
+            else {
+                DoubleRangePanel p = (DoubleRangePanel) form;
+                saveRangeQValue(p, item);
+            }
+        }
+    }
+
+
+    protected void saveSingleWValues(DoubleArrayPanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) {
+                saveSingleWValue(p, item);
+            }
+        }
+    }
+
+
+    protected void saveSingleQValues(DoubleArrayPanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) {
+                saveSingleQValue(p, item);
+            }
+        }
+    }
+
+
+    protected void saveSingleWValue(DoubleArrayPanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setSingleW(p.getInputValues(item));
+        }
+    }
+
+
+    protected void saveSingleQValue(DoubleArrayPanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setSingleQ(p.getInputValues(item));
+        }
+    }
+
+
+    protected void saveRangeWValues(DoubleRangePanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            saveRangeWValue(p, item);
+        }
+    }
+
+
+    protected void saveRangeQValues(DoubleRangePanel p) {
+        FormItem[] formItems = p.getFields();
+
+        for (FormItem item: formItems) {
+            saveRangeQValue(p, item);
+        }
+    }
+
+
+    protected void saveRangeWValue(DoubleRangePanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setFromW(p.getFrom());
+            setToW(p.getTo());
+            setStepW(p.getStep());
+        }
+    }
+
+
+    protected void saveRangeQValue(DoubleRangePanel p, FormItem item) {
+        if (p.validateForm(item)) {
+            setFromQ(p.getFrom());
+            setToQ(p.getTo());
+            setStepQ(p.getStep());
+        }
+    }
+
+
+    protected double[] getSingleQ() {
+        return valuesQ;
+    }
+
+
+    protected void setSingleQ(double[] values) {
+        valuesQ = values;
+    }
+
+
+    protected double getFromQ() {
+        return fromQ;
+    }
+
+
+    protected void setFromQ(double fromQ) {
+        this.fromQ = fromQ;
+    }
+
+
+    protected double getToQ() {
+        return toQ;
+    }
+
+
+    protected void setToQ(double toQ) {
+        this.toQ = toQ;
+    }
+
+
+    protected double getStepQ() {
+        return stepQ;
+    }
+
+
+    protected void setStepQ(double stepQ) {
+        this.stepQ = stepQ;
+    }
+
+
+    protected double[] getSingleW() {
+        return valuesW;
+    }
+
+
+    protected void setSingleW(double[] values) {
+        valuesW = values;
+    }
+
+
+    protected double getFromW() {
+        return fromW;
+    }
+
+
+    protected void setFromW(double fromW) {
+        this.fromW = fromW;
+    }
+
+
+    protected double getToW() {
+        return toW;
+    }
+
+
+    protected void setToW(double toW) {
+        this.toW = toW;
+    }
+
+
+    protected double getStepW() {
+        return stepW;
+    }
+
+
+    protected void setStepW(double stepW) {
+        this.stepW = stepW;
+    }
+
+
+    protected void createWQInputTable() {
+        Config config    = Config.getInstance();
+        String url       = config.getServerUrl();
+        String locale    = config.getLocale ();
+        String river     = "";
+        String value_min = "";
+        String value_max = "";
+
+        ArtifactDescription adescr = artifact.getArtifactDescription();
+        DataList[] data = adescr.getOldData();
+
+        //TODO: get the information about old data.
+        if (data != null && data.length > 0) {
+            for (int i = 0; i < data.length; i++) {
+                DataList dl = data[i];
+                if (dl.getState().equals("state.winfo.river")) {
+                    for (int j = 0; j < dl.size(); j++) {
+                        Data d = dl.get(j);
+                        DataItem[] di = d.getItems();
+                        if (di != null && di.length == 1) {
+                           river = d.getItems()[0].getStringValue();
+                        }
+                    }
+                }
+                else if (dl.getState().equals("state.winfo.location_distance")){
+                    for (int j = 0; j < dl.size(); j++) {
+                        Data d = dl.get(j);
+                        DataItem[] di = d.getItems();
+                        if (di != null && di.length >= 1 && j == 0) {
+                            value_max = d.getItems()[0].getStringValue();
+                        }
+                        else if (di != null &&
+                                 di.length >= 1 &&
+                                 j == dl.size() - 1) {
+                            value_min = d.getItems()[0].getStringValue();
+                        }
+                    }
+                }
+            }
+        }
+
+        double from = Double.valueOf(value_min);
+        double to = Double.valueOf(value_max);
+        wqInfoService.getWQInfo(url, locale, river, from, to,
+            new AsyncCallback<WQInfoObject[]>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not recieve wq informations.");
+                    GWT.log(caught.getMessage());
+                }
+
+                public void onSuccess(WQInfoObject[] wqi) {
+                    int num = wqi != null ? wqi.length :0;
+                    GWT.log("Recieved " + num + " wq informations.");
+
+                    if (num == 0) {
+                        return;
+                    }
+                    tableData = wqi;
+                    addWQInfo(wqi);
+                    updatePanels(FIELD_WQ_W, FIELD_MODE_SINGLE);
+                }
+            }
+        );
+    }
+
+
+    protected void addWQInfo (WQInfoObject[] wqi) {
+        int i = 0;
+        for(WQInfoObject wi: wqi) {
+            WQInfoRecord rec = new WQInfoRecord (wi);
+            wqTable.addData(rec);
+            wqRangeTable.addData(rec);
+        }
+        return;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/AddArtifactServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,61 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.client.services.AddArtifactService;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class AddArtifactServiceImpl
+extends      DescribeCollectionServiceImpl
+implements   AddArtifactService
+{
+    public static final String ERROR_ADD_ARTIFACT = "error_add_artifact";
+
+    public Collection add(
+        Collection collection,
+        Artifact   artifact,
+        String     url,
+        String     locale)
+    throws ServerException
+    {
+        System.out.println("AddArtifactServiceImpl.add");
+
+        Document add = ClientProtocolUtils.newAddArtifactDocument(
+            artifact.getUuid(), null);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+
+        try {
+            Document response = (Document) client.doCollectionAction(
+                add, collection.identifier(), new DocumentResponseHandler());
+
+            Collection c = parseCollection(response);
+
+            if (c == null) {
+                throw new ServerException(ERROR_ADD_ARTIFACT);
+            }
+
+            return c;
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+
+        }
+
+        throw new ServerException(ERROR_ADD_ARTIFACT);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,81 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.client.services.AdvanceService;
+
+
+/**
+ * This interface provides artifact specific operation ADVANCE.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class AdvanceServiceImpl
+extends      RemoteServiceServlet
+implements   AdvanceService
+{
+    public static final String XPATH_RESULT = "/art:result/text()";
+
+    public static final String OPERATION_FAILURE = "FAILED";
+
+    public static final String ERROR_ADVANCE_ARTIFACT = "error_advance_artifact";
+
+
+    public Artifact advance(
+        String   serverUrl,
+        String   locale,
+        Artifact artifact,
+        String   target)
+    throws ServerException
+    {
+        System.out.println("AdvanceServiceImpl.advance");
+
+        Document advance = ClientProtocolUtils.newAdvanceDocument(
+            artifact.getUuid(),
+            artifact.getHash(),
+            target);
+
+        HttpClient client = new HttpClientImpl(serverUrl, locale);
+
+        try {
+            Document description = (Document) client.advance(
+                new de.intevation.artifacts.httpclient.objects.Artifact(
+                    artifact.getUuid(),
+                    artifact.getHash()),
+                advance,
+                new DocumentResponseHandler());
+
+            if (description == null) {
+                throw new ServerException(ERROR_ADVANCE_ARTIFACT);
+            }
+
+            String result = XMLUtils.xpathString(
+                description,
+                XPATH_RESULT,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (result == null || !result.equals(OPERATION_FAILURE)) {
+                return (Artifact) new FLYSArtifactCreator().create(description);
+            }
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_ADVANCE_ARTIFACT);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,359 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.DefaultArtifactDescription;
+import de.intevation.flys.client.shared.model.DefaultData;
+import de.intevation.flys.client.shared.model.DefaultDataItem;
+import de.intevation.flys.client.shared.model.DefaultOutputMode;
+import de.intevation.flys.client.shared.model.OutputMode;
+
+
+/**
+ * This factory class helps creating an {@link ArtifactDescription} based on the
+ * DESCRIBE document of an artifact returned by the artifact server. Use the
+ * {@link createArtifactDescription(org.w3c.dom.Document)} method with the
+ * DESCRIBE document to create such an {@link ArtifactDescription}.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ArtifactDescriptionFactory {
+
+    public static final String XPATH_STATE_NAME = "@art:name";
+
+    public static final String XPATH_UIPROVIDER = "@art:uiprovider";
+
+    public static final String XPATH_REACHABLE_STATE = "art:state";
+
+    public static final String XPATH_STATIC_STATE_NODE = "art:state";
+
+    public static final String XPATH_STATIC_DATA_NODE = "art:data";
+
+    public static final String XPATH_STATIC_ITEM_NODE = "art:item";
+
+    /**
+     * This method creates the {@link ArtifactDescription} of the DESCRIBE
+     * document <i>doc</i>.
+     *
+     * @param doc A DESCRIBE document.
+     *
+     * @return the {@link ArtifactDescription}.
+     */
+    public static ArtifactDescription createArtifactDescription(Document doc) {
+        System.out.println("ArtifactDescriptionFactory - create()");
+
+        Node currentState = ClientProtocolUtils.getCurrentState(doc);
+        Node staticNode   = ClientProtocolUtils.getStaticUI(doc);
+        Node dynamicNode  = ClientProtocolUtils.getDynamicUI(doc);
+        Node reachable    = ClientProtocolUtils.getReachableStates(doc);
+        NodeList outputs  = ClientProtocolUtils.getOutputModes(doc);
+
+        String state = (String) XMLUtils.xpath(
+            currentState,
+            XPATH_STATE_NAME,
+            XPathConstants.STRING,
+            ArtifactNamespaceContext.INSTANCE);
+        System.out.println("Current state name: " + state);
+
+        DataList currentData = extractCurrentData(dynamicNode, state);
+        DataList[] old       = extractOldData(staticNode);
+        String[] states      = extractReachableStates(reachable);
+        OutputMode[] outs        = extractOutputModes(outputs);
+
+        return new DefaultArtifactDescription(
+            old,
+            currentData,
+            state,
+            states,
+            outs);
+    }
+
+
+    /**
+     * This method extracts the data that the user is able to enter in the
+     * current state of the artifact.
+     *
+     * @param dynamicNode The dynamic node of the DESCRIBE document.
+     * @param state The name of the current state.
+     *
+     * @return A {@link Data} object that represents the data which might be
+     * entered by the user in the current state or null, if no data might be
+     * entered.
+     */
+    protected static DataList extractCurrentData(Node dynamicNode, String state) {
+        System.out.println("ArtifactDescriptionFactory - extractCurrentData()");
+
+        NodeList data     = ClientProtocolUtils.getSelectNode(dynamicNode);
+        String uiProvider = extractUIProvider(dynamicNode);
+
+        if (data == null || data.getLength() == 0) {
+            return null;
+        }
+
+        int dataNum   = data.getLength();
+        DataList list = new DataList(state, dataNum, uiProvider);
+
+        for (int i = 0; i < dataNum; i++) {
+            Node d = data.item(i);
+
+            NodeList choices  = ClientProtocolUtils.getItemNodes(d);
+            String   label    = ClientProtocolUtils.getLabel(d);
+            String   name     = XMLUtils.xpathString(
+                d, "@art:name", ArtifactNamespaceContext.INSTANCE);
+
+            DataItem[] dataItems = extractCurrentDataItems(choices);
+
+            list.add(new DefaultData(name, label, null, dataItems));
+        }
+
+        return list;
+    }
+
+
+    /**
+     * This method extract the {@link DataItem}s of the DESCRIBE document.
+     *
+     * @param items The items in the DESCRIBE document.
+     *
+     * @return the {@link DataItem}s.
+     */
+    protected static DataItem[] extractCurrentDataItems(NodeList items) {
+        System.out.println(
+            "ArtifactDescriptionFactory - extractCurrentDataItems()");
+
+        if (items == null || items.getLength() == 0) {
+            System.out.println("No data items found.");
+            return null;
+        }
+
+        int count = items.getLength();
+
+        List<DataItem> dataItems = new ArrayList<DataItem>(count);
+
+        for (int i = 0; i < count; i++) {
+            Node item    = items.item(i);
+            String label = ClientProtocolUtils.getLabel(item);
+            String value = ClientProtocolUtils.getValue(item);
+
+            dataItems.add(new DefaultDataItem(label, null, value));
+        }
+
+        return (DataItem[]) dataItems.toArray(new DataItem[count]);
+    }
+
+
+    /**
+     * This method extracts the data objects from the data node of the static ui
+     * part of the DESCRIBE document.
+     *
+     * @param staticNode The static ui node of the DESCRIBE.
+     *
+     * @return the DataList objects.
+     */
+    protected static DataList[] extractOldData(Node staticNode) {
+        System.out.println("ArtifactDescriptionFactory - extractOldData()");
+
+        NodeList stateNodes = (NodeList) XMLUtils.xpath(
+            staticNode,
+            XPATH_STATIC_STATE_NODE,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (stateNodes == null || stateNodes.getLength() == 0) {
+            System.out.println("No old items found.");
+            return null;
+        }
+
+        int count       = stateNodes.getLength();
+        DataList[] data = new DataList[count];
+
+        for (int i = 0; i < count; i++) {
+            Node tmp = stateNodes.item(i);
+
+            String name = XMLUtils.xpathString(
+                tmp, "@art:name", ArtifactNamespaceContext.INSTANCE);
+            String uiprovider = XMLUtils.xpathString(
+                tmp, "@art:uiprovider", ArtifactNamespaceContext.INSTANCE);
+            String label = XMLUtils.xpathString(
+                tmp, "@art:label", ArtifactNamespaceContext.INSTANCE);
+
+            NodeList dataNodes = (NodeList) XMLUtils.xpath(
+                tmp,
+                XPATH_STATIC_DATA_NODE,
+                XPathConstants.NODESET,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (dataNodes == null || dataNodes.getLength() == 0) {
+                continue;
+            }
+
+            int size      = dataNodes.getLength();
+            DataList list = new DataList(name, size, uiprovider, label);
+
+            for (int j = 0; j < size; j++) {
+                Node dataNode = dataNodes.item(j);
+
+                String dName = XMLUtils.xpathString(
+                    dataNode, "@art:name", ArtifactNamespaceContext.INSTANCE);
+                String dType = XMLUtils.xpathString(
+                    dataNode, "@art:type", ArtifactNamespaceContext.INSTANCE);
+
+                DataItem[] items = extractOldDataItems(dataNode);
+
+                list.add(new DefaultData(dName, dName, dType, items));
+
+                data[i] = list;
+            }
+        }
+
+        return data;
+    }
+
+
+    /**
+     * This method extracts the data items from the data nodes that are placed
+     * in the static ui part of the DESCRIBE document.
+     *
+     * @param dataNode A data node that contains items.
+     *
+     * @return a list of DataItems.
+     */
+    protected static DataItem[] extractOldDataItems(Node dataNode) {
+        NodeList itemList = (NodeList) XMLUtils.xpath(
+            dataNode,
+            XPATH_STATIC_ITEM_NODE,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (itemList == null || itemList.getLength() == 0) {
+            System.out.println("No old data items found.");
+            return null;
+        }
+
+        int count = itemList.getLength();
+
+        DataItem[] items = new DataItem[count];
+
+        for (int i = 0; i < count; i++) {
+            Node tmp = itemList.item(i);
+
+            String value = XMLUtils.xpathString(
+                tmp, "@art:value", ArtifactNamespaceContext.INSTANCE);
+            String label = XMLUtils.xpathString(
+                tmp, "@art:label", ArtifactNamespaceContext.INSTANCE);
+
+            items[i] = new DefaultDataItem(label, label, value);
+        }
+
+        return items;
+    }
+
+
+    /**
+     * This method extracts the UIProvider specified by the data node.
+     *
+     * @param data The data node.
+     *
+     * @return the UIProvider that is specified in the data node.
+     */
+    protected static String extractUIProvider(Node ui) {
+        return (String) XMLUtils.xpath(
+            ui,
+            XPATH_UIPROVIDER,
+            XPathConstants.STRING,
+            ArtifactNamespaceContext.INSTANCE);
+    }
+
+
+    /**
+     * This method extracts the reachable states of the current artifact.
+     *
+     * @param reachable The reachable states node.
+     *
+     * @return an array with identifiers of reachable states.
+     */
+    protected static String[] extractReachableStates(Node reachable) {
+        System.out.println("ArtifactDescriptionFactory - extractReachableStates()");
+
+        NodeList list = (NodeList) XMLUtils.xpath(
+            reachable,
+            XPATH_REACHABLE_STATE,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (list == null || list.getLength() == 0) {
+            return null;
+        }
+
+        int count = list.getLength();
+
+        String[] states = new String[count];
+
+        for (int i = 0; i < count; i++) {
+            Node state = list.item(i);
+
+            String name = XMLUtils.xpathString(
+                state, "@art:name", ArtifactNamespaceContext.INSTANCE);
+
+            states[i] = name;
+        }
+
+        return states;
+    }
+
+
+    /**
+     * This method extract available output modes of the the current artifact.
+     *
+     * @param outputs A list of nodes that contain information about output
+     * modes.
+     *
+     * @return an array of Output modes.
+     */
+    protected static OutputMode[] extractOutputModes(NodeList outputs) {
+        System.out.println("ArtifactDescriptionFactory - extractOutputModes()");
+
+        if (outputs == null || outputs.getLength() == 0) {
+            return null;
+        }
+
+        int size = outputs.getLength();
+
+        List<OutputMode> outs = new ArrayList<OutputMode>(size);
+
+        for (int i = 0; i < size; i++) {
+            Node out = outputs.item(i);
+
+            String name = XMLUtils.xpathString(
+                out, "@art:name", ArtifactNamespaceContext.INSTANCE);
+            String desc = XMLUtils.xpathString(
+                out, "@art:description", ArtifactNamespaceContext.INSTANCE);
+            String mimeType = XMLUtils.xpathString(
+                out, "@art:mime-type", ArtifactNamespaceContext.INSTANCE);
+
+            if (name != null) {
+                outs.add(new DefaultOutputMode(name, desc, mimeType));
+            }
+            else {
+                System.err.println("Found an invalid output mode.");
+            }
+        }
+
+        return (OutputMode[]) outs.toArray(new OutputMode[size]);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,51 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.client.services.ArtifactService;
+
+
+/**
+ * This interface provides artifact specific services as CREATE, DESCRIBE, FEED,
+ * ADVANCE and OUT.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ArtifactServiceImpl
+extends      RemoteServiceServlet
+implements   ArtifactService
+{
+    /** The error message key that is thrown if an error occured while artifact
+     * creation.*/
+    public static final String ERROR_CREATE_ARTIFACT = "error_create_artifact";
+
+
+    public Artifact create(String serverUrl, String locale, String factory)
+    throws ServerException
+    {
+        System.out.println("ArtifactServiceImpl.create");
+
+        Document create   = ClientProtocolUtils.newCreateDocument(factory);
+        HttpClient client = new HttpClientImpl(serverUrl, locale);
+
+        try {
+            return (Artifact) client.create(create, new FLYSArtifactCreator());
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_CREATE_ARTIFACT);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/CSVExportServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,74 @@
+package de.intevation.flys.client.server;
+
+import java.util.List;
+
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import au.com.bytecode.opencsv.CSVReader;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.client.services.CSVExportService;
+
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class CSVExportServiceImpl
+extends      RemoteServiceServlet
+implements   CSVExportService
+{
+    public static final String ERROR_NO_EXPORT_FOUND =
+        "error_no_export_found";
+
+    public List getCSV(
+        String url,
+        String locale,
+        String uuid,
+        String name)
+    throws ServerException
+    {
+        System.out.println("CSVExportServiceImpl.getCSV");
+
+        Document requestDoc = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            requestDoc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element action = ec.create("action");
+        ec.addAttr(action, "type", "csv", true);
+        ec.addAttr(action, "name", name, true);
+
+        requestDoc.appendChild(action);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+        try {
+            InputStream in = client.collectionOut(requestDoc, uuid, "export");
+            Reader reader       = new InputStreamReader (in, "UTF-8");
+            CSVReader csvReader = new CSVReader (reader);
+
+            return csvReader.readAll ();
+        }
+        catch (IOException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_NO_EXPORT_FOUND);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ChartOutputServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,121 @@
+package de.intevation.flys.client.server;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
+
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+
+/**
+ * This service is used to request a chart from the artifact server. The
+ * response is directed directly to the output stream, so the image that is
+ * retrieved is displayed in the UI afterwards.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ChartOutputServiceImpl
+extends      HttpServlet
+{
+    /** The default chart width if no value is specified in the request.*/
+    public static final int DEFAULT_CHART_WIDTH  = 600;
+
+    /** The default chart height if no value is specified in the request.*/
+    public static final int DEFAULT_CHART_HEIGHT = 400;
+
+
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
+        System.out.println("ChartOutputServiceImpl.doGet");
+
+        try {
+            OutputStream out = resp.getOutputStream();
+
+            String serverUrl = req.getParameter("server");
+            String uuid      = req.getParameter("uuid");
+            String type      = req.getParameter("type");
+            String locale    = req.getParameter("locale");
+
+            Document request = ClientProtocolUtils.newOutCollectionDocument(
+                uuid, type, getChartAttributes(req));
+
+            HttpClient client = new HttpClientImpl(serverUrl, locale);
+            client.collectionOut(request, uuid, "chart", out);
+
+            out.close();
+            out.flush();
+        }
+        catch (IOException ioe) {
+            System.err.println(ioe.getMessage());
+        }
+        catch (Exception e) {
+            System.err.println(e.getMessage());
+        }
+    }
+
+
+    /**
+     * This method returns a document which might contain parameters to adjust
+     * chart settings. The document is created using the information that are
+     * contained in the request object.
+     *
+     * @param req The request document.
+     *
+     * @return a document to adjust chart settings.
+     */
+    protected Document getChartAttributes(HttpServletRequest req) {
+        Document doc = XMLUtils.newDocument();
+
+        ElementCreator ec = new ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        appendChartSize(req, doc, ec);
+
+        return doc;
+    }
+
+
+    /**
+     * This method extracts the size (width/height) of a chart from request
+     * object and append those values - if they exist - to the attribute
+     * document used to adjust chart settings.
+     *
+     * @param req The request object that might contain the chart size.
+     * @param doc The attribute document used to adjust chart settings.
+     * @param ec The ElementCreator that might be used to create new Elements.
+     */
+    protected void appendChartSize(
+        HttpServletRequest req,
+        Document           doc,
+        ElementCreator     ec)
+    {
+        Element size = ec.create("size");
+
+        String width  = req.getParameter("width");
+        String height = req.getParameter("height");
+
+        if (width == null || height == null) {
+            width  = Integer.toString(DEFAULT_CHART_WIDTH);
+            height = Integer.toString(DEFAULT_CHART_HEIGHT);
+        }
+
+        ec.addAttr(size, "width", width, true);
+        ec.addAttr(size, "height", height, true);
+
+        doc.appendChild(size);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/CreateCollectionServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,71 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.DefaultCollection;
+import de.intevation.flys.client.client.services.CreateCollectionService;
+
+
+/**
+ * This interface provides the createCollection service to create new
+ * collections in the artifact server.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class CreateCollectionServiceImpl
+extends      RemoteServiceServlet
+implements   CreateCollectionService
+{
+    /** XPath to figure out the uuid of the created collection.*/
+    public static final String XPATH_COLLECTION_UUID =
+        "/art:result/art:artifact-collection/@art:uuid";
+
+    /** Error message key that is thrown if an error occured while creating
+     *  a new collection.*/
+    public static final String ERROR_CREATE_COLLECTION =
+        "error_create_collection";
+
+
+    public Collection create(String serverUrl, String locale, String ownerId)
+    throws ServerException
+    {
+        System.out.println("Start creating a new collection.");
+
+        Document create   =
+            ClientProtocolUtils.newCreateCollectionDocument(null);
+        HttpClient client = new HttpClientImpl(serverUrl, locale);
+
+        try {
+            Document doc = (Document) client.createCollection(
+                create, ownerId, new DocumentResponseHandler());
+
+            String uuid = XMLUtils.xpathString(
+                doc, XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE);
+
+            if (uuid == null || uuid.trim().length() == 0) {
+                throw new ServerException(ERROR_CREATE_COLLECTION);
+            }
+
+            return new DefaultCollection(uuid);
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_CREATE_COLLECTION);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,273 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.CollectionItem;
+import de.intevation.flys.client.shared.model.DefaultCollection;
+import de.intevation.flys.client.shared.model.DefaultCollectionItem;
+import de.intevation.flys.client.shared.model.DefaultFacet;
+import de.intevation.flys.client.shared.model.DefaultOutputMode;
+import de.intevation.flys.client.shared.model.ExportMode;
+import de.intevation.flys.client.shared.model.Facet;
+import de.intevation.flys.client.shared.model.OutputMode;
+import de.intevation.flys.client.client.services.DescribeCollectionService;
+
+
+/**
+ * This service implements a method that queries the DESCRIBE document of a
+ * specific collection and returns a Collection object with the information of
+ * the document.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DescribeCollectionServiceImpl
+extends      RemoteServiceServlet
+implements   DescribeCollectionService
+{
+    /** The error message key that is thrown if an error occured while
+     * describe() a Collection.*/
+    public static final String ERROR_DESCRIBE_COLLECTION =
+        "error_describe_collection";
+
+    public static final String XPATH_FACETS = "art:facets/art:facet";
+
+
+    public Collection describe(String uuid, String serverUrl, String locale)
+    throws ServerException
+    {
+        System.out.println("DescribeCollectionServiceImpl.describe");
+
+        Document describe = ClientProtocolUtils.newDescribeCollectionDocument(
+            uuid);
+
+        HttpClient client = new HttpClientImpl(serverUrl, locale);
+
+        try {
+            Document response = (Document) client.doCollectionAction(
+                describe, uuid, new DocumentResponseHandler());
+
+            Collection c = parseCollection(response);
+
+            if (c == null) {
+                throw new ServerException(ERROR_DESCRIBE_COLLECTION);
+            }
+
+            return c;
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_DESCRIBE_COLLECTION);
+    }
+
+
+    /**
+     * This method takes the DESCRIBE document of the Collections describe()
+     * operation and extracts the information about the collection itself and
+     * the collection items.
+     *
+     * @param description The DESCRIBE document of the Collections describe()
+     * operation.
+     *
+     * @return a Collection with CollectionItems.
+     */
+    protected Collection parseCollection(Document description) {
+        System.out.println("AddArtifactServiceImpl.parseCollection");
+
+        if (description == null) {
+            System.err.println("The DESCRIBE of the Collection is null!");
+            return null;
+        }
+
+        String uuid = XMLUtils.xpathString(
+            description,
+            "art:artifact-collection/@art:uuid",
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (uuid == null || uuid.equals("")) {
+            System.err.println("Found an invalid Collection!");
+            return null;
+        }
+
+        Collection c = new DefaultCollection(uuid);
+
+        NodeList items = (NodeList) XMLUtils.xpath(
+            description,
+            "art:artifact-collection/art:artifacts/art:artifact",
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (items == null || items.getLength() == 0) {
+            System.out.println("No collection item found for this collection.");
+
+            return c;
+        }
+
+        int size = items.getLength();
+
+        for (int i = 0; i < size; i++) {
+            CollectionItem item = parseCollectionItem(items.item(i));
+
+            if (item != null) {
+                c.addItem(item);
+            }
+        }
+
+        System.out.println(
+            "Found " + c.getItemLength() + " collection items " +
+            "for the Collection '" + c.identifier() + "'.");
+
+        return c;
+    }
+
+
+    /**
+     * This method extracts the CollectionItem from <i>node</i> with its output
+     * modes. The output modes are parsed using the parseOutputModes() method.
+     *
+     * @param node A node that contains information about a CollectionItem.
+     *
+     * @return a CollectionItem.
+     */
+    protected CollectionItem parseCollectionItem(Node node) {
+        System.out.println("AddArtifactServiceImpl.parseCollectionItem");
+
+        if (node == null) {
+            System.err.println("The node for parsing CollectionItem is null!");
+            return null;
+        }
+
+        String uuid = XMLUtils.xpathString(
+            node, "@art:uuid", ArtifactNamespaceContext.INSTANCE);
+
+        String hash = XMLUtils.xpathString(
+            node, "@art:hash", ArtifactNamespaceContext.INSTANCE);
+
+        if (uuid == null || uuid.equals("")) {
+            System.err.println("Found an invalid CollectionItem!");
+        }
+
+        Node outputmodes = (Node) XMLUtils.xpath(
+            node,
+            "art:outputmodes",
+            XPathConstants.NODE,
+            ArtifactNamespaceContext.INSTANCE);
+
+        List<OutputMode> modes = parseOutputModes(outputmodes);
+
+        return new DefaultCollectionItem(uuid, hash, modes);
+    }
+
+
+    /**
+     * This method extracts the OutputModes available for a specific
+     * CollectionItem and returns them as list.
+     *
+     * @param node The root node of the outputmodes list.
+     *
+     * @return a list of OutputModes.
+     */
+    protected List<OutputMode> parseOutputModes(Node node) {
+        System.out.println("AddArtifactServiceImpl.parseOutputModes");
+
+        if (node == null) {
+            System.err.println("The node for parsing OutputModes is null!");
+            return null;
+        }
+
+        NodeList list = (NodeList) XMLUtils.xpath(
+            node,
+            "art:output",
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (list == null || list.getLength() == 0) {
+            System.err.println("No outputmode nodes found!");
+            return null;
+        }
+
+        int size = list.getLength();
+
+        List<OutputMode> modes = new ArrayList<OutputMode>(size);
+
+        for (int i = 0; i < size; i++) {
+            Node   tmp  = list.item(i);
+            String name = XMLUtils.xpathString(
+                tmp, "@art:name", ArtifactNamespaceContext.INSTANCE);
+            String desc = XMLUtils.xpathString(
+                tmp, "@art:description", ArtifactNamespaceContext.INSTANCE);
+            String mime = XMLUtils.xpathString(
+                tmp, "@art:mime-type", ArtifactNamespaceContext.INSTANCE);
+
+            if (name == null || name.equals("")) {
+                System.err.println("Found an invalid output mode.");
+
+                continue;
+            }
+
+            OutputMode outmode = null;
+            List<Facet> fs     = extractFacets(tmp);
+
+            if (name.indexOf("export") > -1) {
+                outmode = new ExportMode(name, desc, mime, fs);
+            }
+            else {
+                outmode = new DefaultOutputMode(name, desc, mime, fs);
+            }
+
+            modes.add(outmode);
+        }
+
+        return modes;
+    }
+
+
+    protected static List<Facet> extractFacets(Node outmode) {
+        System.out.println("ArtifactDescriptionFactory - extractFacets()");
+
+        NodeList facetList = (NodeList) XMLUtils.xpath(
+            outmode,
+            XPATH_FACETS,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        int num = facetList != null ? facetList.getLength() : 0;
+
+        List<Facet> facets = new ArrayList<Facet>(num);
+
+        for (int i = 0; i < num; i++) {
+            Node facetNode = facetList.item(i);
+
+            String name = XMLUtils.xpathString(
+                facetNode, "@art:name", ArtifactNamespaceContext.INSTANCE);
+
+            if (name != null && name.length() > 0) {
+                facets.add(new DefaultFacet(name));
+            }
+        }
+
+        return facets;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/DistanceInfoServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,164 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.client.services.DistanceInfoService;
+import de.intevation.flys.client.shared.model.DistanceInfoObject;
+import de.intevation.flys.client.shared.model.DistanceInfoObjectImpl;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DistanceInfoServiceImpl
+extends      RemoteServiceServlet
+implements   DistanceInfoService
+{
+    public static final String ERROR_NO_DISTANCEINFO_FOUND =
+        "error_no_distanceinfo_found";
+
+    public static final String XPATH_DISTANCES = "art:distances/art:distance";
+
+
+    public DistanceInfoObject[] getDistanceInfo(
+        String url,
+        String locale,
+        String river)
+    throws ServerException
+    {
+        System.out.println("DistanceInfoServiceImpl.getDistanceInfo");
+
+        Document doc = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element riverEl = ec.create("river");
+
+        riverEl.setTextContent(river);
+
+        doc.appendChild(riverEl);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+
+        try {
+            Document result = client.callService(url, "distanceinfo", doc);
+
+            System.out.println("Extract distance info objects now.");
+            DistanceInfoObject[] objects = extractDistanceInfoObjects(result);
+
+            if (objects != null && objects.length > 0) {
+                return objects;
+            }
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_NO_DISTANCEINFO_FOUND);
+    }
+
+
+    /**
+     * Extracts all distance info objects from <i>result</i> document.
+     *
+     * @param result The document retrieved by the server.
+     *
+     * @return a list of DistanceInfoObjects.
+     */
+    protected DistanceInfoObject[] extractDistanceInfoObjects(Document result)
+    throws    ServerException
+    {
+        NodeList list = (NodeList) XMLUtils.xpath(
+            result,
+            XPATH_DISTANCES,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (list == null || list.getLength() == 0) {
+            System.err.println("No distance info found.");
+
+            throw new ServerException(ERROR_NO_DISTANCEINFO_FOUND);
+        }
+
+        int num = list.getLength();
+        System.out.println("Response contains " + num + " objects.");
+
+        List<DistanceInfoObject> objects =
+            new ArrayList<DistanceInfoObject>(num);
+
+        for (int i = 0; i < num; i++) {
+            DistanceInfoObject obj = buildDistanceInfoObject(list.item(i));
+
+            if (obj != null) {
+                objects.add(obj);
+            }
+        }
+
+        System.out.println("Retrieved " + objects.size() + " distances.");
+
+        return (DistanceInfoObject[])
+            objects.toArray(new DistanceInfoObject[num]);
+    }
+
+
+    /**
+     * Extracts information for a single distance info object and intializes an
+     * DistanceInfoObject with them.
+     *
+     * @param node The node that contains the information.
+     *
+     * @return a valid DistanceInfoObject.
+     */
+    protected DistanceInfoObject buildDistanceInfoObject(Node node) {
+        String desc = XMLUtils.xpathString(
+            node, "@art:description", ArtifactNamespaceContext.INSTANCE);
+
+        String from = XMLUtils.xpathString(
+            node, "@art:from", ArtifactNamespaceContext.INSTANCE);
+
+        String to = XMLUtils.xpathString(
+            node, "@art:to", ArtifactNamespaceContext.INSTANCE);
+
+        String riverside = XMLUtils.xpathString(
+            node, "@art:riverside", ArtifactNamespaceContext.INSTANCE);
+
+        if (desc != null && from != null) {
+            try {
+                return new DistanceInfoObjectImpl(
+                    desc,
+                    new Double(from),
+                    to != null && to.trim().length() > 0 ? new Double(to) : null,
+                    riverside);
+            }
+            catch (NumberFormatException nfe) {
+                System.err.println(nfe.getLocalizedMessage());
+            }
+        }
+
+        System.err.println("Invalid distance info object found.");
+
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ExportServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,57 @@
+package de.intevation.flys.client.server;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+import org.w3c.dom.Document;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+
+/**
+ * This service is used to request a data export from the artifact server. The
+ * response is directed directly to the output stream, so that a file dialog is
+ * opened.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ExportServiceImpl
+extends      HttpServlet
+{
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
+        System.out.println("ExportServiceImpl.doGet");
+
+        try {
+            OutputStream out = resp.getOutputStream();
+
+            String serverUrl = req.getParameter("server");
+            String uuid      = req.getParameter("uuid");
+            String mode      = req.getParameter("mode");
+            String type      = req.getParameter("type");
+            String locale    = req.getParameter("locale");
+            String fn        = mode + "." + type;
+
+            resp.setHeader("Content-Disposition", "attachment;filename=" + fn);
+
+            Document request = ClientProtocolUtils.newOutCollectionDocument(
+                uuid, mode);
+
+            HttpClient client = new HttpClientImpl(serverUrl, locale);
+            client.collectionOut(request, uuid, mode, out);
+
+            out.close();
+            out.flush();
+        }
+        catch (IOException ioe) {
+            System.err.println(ioe.getMessage());
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,97 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+
+import de.intevation.artifacts.httpclient.utils.ArtifactCreator;
+
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.DefaultArtifact;
+import de.intevation.flys.client.shared.model.WINFOArtifact;
+
+
+/**
+ * An implementation of an {@link ArtifactCreator}. This class uses the document
+ * that is returned by the artifact server to parse important information (like
+ * uuid, hash) and returns a new {@link Artifact} instance.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYSArtifactCreator implements ArtifactCreator {
+
+    /** The XPath to the artifact's uuid.*/
+    public static final String XPATH_UUID = "/art:result/art:uuid/@art:value";
+
+    /** The XPath to the artifact's hash value.*/
+    public static final String XPATH_HASH = "/art:result/art:hash/@art:value";
+
+    /** The XPath to the artifact's name value.*/
+    public static final String XPATH_NAME = "/art:result/art:name/@art:value";
+
+
+    /**
+     * Creates a new instance of an {@link ArtifactCreator}.
+     */
+    public FLYSArtifactCreator() {
+    }
+
+
+    /**
+     * This concreate implementation returns an instance of {@link Artifact}
+     * that is used in the FLYS GWT Client code.
+     *
+     * @param doc A document that describes the artifact that has been created
+     * in the artifact server.
+     *
+     * @return an instance if {@link Artifact}.
+     */
+    public Object create(Document doc) {
+        Artifact artifact = extractArtifact(doc);
+        artifact.setArtifactDescription(
+            ArtifactDescriptionFactory.createArtifactDescription(doc));
+
+        return artifact;
+    }
+
+
+    /**
+     * This method extracts the UUID und HASH information of the returned
+     * artifact document.
+     *
+     * @param doc The result of the CREATE operation.
+     *
+     * @return an instance of an {@link Artifact}.
+     */
+    protected Artifact extractArtifact(Document doc) {
+        System.out.println("FLYSArtifactCreator - extractArtifact()");
+
+        String uuid = XMLUtils.xpathString(
+            doc, XPATH_UUID, ArtifactNamespaceContext.INSTANCE);
+
+        String hash = XMLUtils.xpathString(
+            doc, XPATH_HASH, ArtifactNamespaceContext.INSTANCE);
+
+        String name = XMLUtils.xpathString(
+            doc, XPATH_NAME, ArtifactNamespaceContext.INSTANCE);
+
+        System.out.println("NEW Artifact UUID: " + uuid);
+        System.out.println("NEW Artifact HASH: " + hash);
+        System.out.println("NEW Artifact NAME: " + name);
+
+        if (name == null) {
+            return new DefaultArtifact(uuid, hash);
+        }
+
+        name = name.trim();
+
+        if (name.length() > 0 && name.equals("winfo")) {
+            System.out.println("+++++ NEW WINFO ARTIFACT.");
+            return new WINFOArtifact(uuid, hash);
+        }
+
+        return new DefaultArtifact(uuid, hash);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/GetArtifactServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,80 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.client.services.GetArtifactService;
+
+
+/**
+ * This service provides a method that returns an artifact based on its
+ * identifier.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class GetArtifactServiceImpl
+extends      RemoteServiceServlet
+implements   GetArtifactService
+{
+    public static final String ERROR_DESCRIBE_ARTIFACT =
+        "error_describe_artifact";
+
+    public static final String XPATH_RESULT = "/art:result/text()";
+
+    public static final String OPERATION_FAILURE = "FAILED";
+
+
+    public Artifact getArtifact(
+        String url,
+        String locale,
+        String uuid,
+        String hash)
+    throws ServerException
+    {
+        System.out.println("GetArtifactServiceImpl.getArtifact");
+
+        Document describe = ClientProtocolUtils.newDescribeDocument(
+            uuid, hash, true);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+
+        try {
+            Document description = (Document) client.describe(
+                new de.intevation.artifacts.httpclient.objects.Artifact(
+                    uuid, hash),
+                describe,
+                new DocumentResponseHandler());
+
+            if (description == null) {
+                throw new ServerException(ERROR_DESCRIBE_ARTIFACT);
+            }
+
+            String result = XMLUtils.xpathString(
+                description,
+                XPATH_RESULT,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (result == null || !result.equals(OPERATION_FAILURE)) {
+                return (Artifact) new FLYSArtifactCreator().create(description);
+            }
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_DESCRIBE_ARTIFACT);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,69 @@
+package de.intevation.flys.client.server;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+
+import de.intevation.flys.client.client.services.MetaDataService;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.model.DataCageTree;
+import de.intevation.flys.client.shared.model.DataCageNode;
+
+import de.intevation.flys.client.server.meta.Converter;
+
+public class MetaDataServiceImpl
+extends      RemoteServiceServlet
+implements   MetaDataService
+{
+    public static final String ERROR_NO_META_DATA_FOUND =
+        "error_no_meta_data_found";
+
+    public DataCageTree getMetaData(String url, String locale, String river) 
+    throws ServerException
+    {
+        System.out.println("MetaDataService.getDistanceInfo");
+
+        Document doc = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element riverEl = ec.create("river");
+
+        riverEl.setTextContent(river);
+
+        doc.appendChild(riverEl);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+
+        try {
+            Converter converter = new Converter();
+            return converter.convert(client.callService(url, "metadata", doc));
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_NO_META_DATA_FOUND);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,94 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.DefaultRiver;
+import de.intevation.flys.client.shared.model.River;
+import de.intevation.flys.client.client.services.RiverService;
+
+
+/**
+ * This interface provides a method to list the supported rivers of the artifact
+ * server.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class RiverServiceImpl
+extends      RemoteServiceServlet
+implements   RiverService
+{
+    /** The XPath string that points to the rivers in the resulting document.*/
+    public static final String XPATH_RIVERS = "/art:rivers/art:river";
+
+    /** The error message key that is thrown if an error occured while reading
+     * the supported rivers from server.*/
+    public static final String ERROR_NO_RIVERS_FOUND = "error_no_rivers_found";
+
+
+    public River[] list(String serverUrl, String locale)
+    throws ServerException
+    {
+        Document doc      = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        doc.appendChild(ec.create("action"));
+
+        HttpClient client = new HttpClientImpl(serverUrl, locale);
+
+        try {
+            Document res = client.callService(serverUrl, "rivers", doc);
+
+            NodeList rivers = (NodeList) XMLUtils.xpath(
+                res,
+                XPATH_RIVERS,
+                XPathConstants.NODESET,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (rivers == null || rivers.getLength() == 0) {
+                throw new ServerException(ERROR_NO_RIVERS_FOUND);
+            }
+
+            int count = rivers.getLength();
+
+            List<River> theRivers = new ArrayList<River>(count);
+
+            for (int i = 0; i < count; i++) {
+                Node tmp = rivers.item(i);
+
+                String name = XMLUtils.xpathString(
+                    tmp, "@art:name", ArtifactNamespaceContext.INSTANCE);
+
+                theRivers.add(new DefaultRiver(name));
+            }
+
+            return (River[]) theRivers.toArray(new River[count]);
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_NO_RIVERS_FOUND);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/StepForwardServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,172 @@
+package de.intevation.flys.client.server;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.ArtifactDescription;
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.client.services.StepForwardService;
+
+
+/**
+ * This interface provides a method that bundles the artifact specific
+ * operations FEED and ADVANCE.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class StepForwardServiceImpl
+extends      AdvanceServiceImpl
+implements   StepForwardService
+{
+    /** XPath that points to the result type of a feed or advance operation.*/
+    public static final String XPATH_RESULT = "/art:result/@art:type";
+
+    /** XPath that points to the result type of a feed or advance operation.*/
+    public static final String XPATH_RESULT_MSG = "/art:result/text()";
+
+    /** A constant that marks errors.*/
+    public static final String OPERATION_FAILURE = "FAILURE";
+
+    /** The error message key that is thrown if an error occured while feeding
+     * new data.*/
+    public static final String ERROR_FEED_DATA = "error_feed_data";
+
+
+    /**
+     * This method wraps the artifact operations FEED and ADVANCE. FEED is
+     * always triggerd, ADVANCE only, if there is at least one reachable state.
+     *
+     * @param url The url of the artifact server.
+     * @param locale The locale used for the request.
+     * @param artifact The artifact that needs to be fed.
+     * @param data An array of Data objects that contain the information that
+     *
+     * @return the modified artifact.
+     */
+    public Artifact go(String url, String locale, Artifact artifact, Data[] data)
+    throws ServerException
+    {
+        System.out.println("StepForwardServiceImpl.go");
+
+        Artifact afterFeed = feed(url, locale, artifact, data);
+
+        if (afterFeed == null) {
+            System.err.println("StepForwardService.feed() - FAILED");
+            throw new ServerException(ERROR_FEED_DATA);
+        }
+
+        ArtifactDescription desc = afterFeed.getArtifactDescription();
+        String[] reachable       = desc.getReachableStates();
+
+        if (reachable == null || reachable.length == 0) {
+            System.out.println("Did not find any reachable state.");
+            return afterFeed;
+        }
+
+        // We use the first reachable state as default target, maybe we need to
+        // change this later.
+        return advance(url, locale, afterFeed, reachable[0]);
+    }
+
+
+    /**
+     * This method triggers the FEED operation.
+     *
+     * @param url The url of the artifact server.
+     * @param artifact The artifact that needs to be fed.
+     * @param data An array of Data objects that contain the information that
+     * are used for the FEED operation.
+     *
+     * @return a new artifact parsed from the description of FEED.
+     */
+    protected Artifact feed(
+        String   url,
+        String   locale,
+        Artifact artifact,
+        Data[]   data)
+    throws    ServerException
+    {
+        System.out.println("StepForwardServiceImpl.feed");
+
+        Document feed = ClientProtocolUtils.newFeedDocument(
+            artifact.getUuid(),
+            artifact.getHash(),
+            createKVP(data));
+
+        HttpClient client = new HttpClientImpl(url, locale);
+
+        try {
+            Document description = (Document) client.feed(
+                new de.intevation.artifacts.httpclient.objects.Artifact(
+                    artifact.getUuid(),
+                    artifact.getHash()),
+                feed,
+                new DocumentResponseHandler());
+
+            if (description == null) {
+                System.err.println("StepForwardService.feed() - FAILED");
+                throw new ServerException(ERROR_FEED_DATA);
+            }
+
+            String result = XMLUtils.xpathString(
+                description,
+                XPATH_RESULT,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (result == null || !result.equals(OPERATION_FAILURE)) {
+                System.out.println("StepForwardService.feed() - SUCCESS");
+                return (Artifact) new FLYSArtifactCreator().create(description);
+            }
+            else if (result != null && result.equals(OPERATION_FAILURE)) {
+                String msg = XMLUtils.xpathString(
+                    description,
+                    XPATH_RESULT_MSG,
+                    ArtifactNamespaceContext.INSTANCE);
+                throw new ServerException(msg);
+            }
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        System.err.println("StepForwardService.feed() - FAILED");
+        throw new ServerException(ERROR_FEED_DATA);
+    }
+
+
+    /**
+     * This method creates an array of key/value pairs from an array of Data
+     * objects. The string array is used as parameter for the feed() operation.
+     *
+     * @param data The data that should be transformed into the string array.
+     *
+     * @return a string array that contains key/value pairs.
+     */
+    protected String[][] createKVP(Data[] data) {
+        String[][] kvp = new String[data.length][];
+
+        int i = 0;
+
+        for (Data d: data) {
+            DataItem[] items = d.getItems();
+            String key       = d.getLabel();
+            String value     = items[0].getStringValue();
+
+            kvp[i++] = new String[] { key, value };
+        }
+
+        return kvp;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,113 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.model.Collection;
+import de.intevation.flys.client.shared.model.DefaultCollection;
+import de.intevation.flys.client.client.services.UserCollectionsService;
+
+
+/**
+ * This service returns a list of collections owned by a specified user.
+ * <b>NOTE:</b> The Collections returned by this service provide no information 
+ * about the CollectionItems or OutputModes of the Collection. You need to fetch
+ * these information explicitly using another service.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class UserCollectionsServiceImpl
+extends      RemoteServiceServlet
+implements   UserCollectionsService
+{
+    public Collection[] getUserCollections(
+        String serverUrl,
+        String locale,
+        String userid)
+    {
+        System.out.println("UserCollectionsServiceImpl.getUserCollections");
+
+        HttpClient client = new HttpClientImpl(serverUrl, locale);
+
+        try {
+            Document result = client.listUserCollections(userid);
+
+            NodeList list = (NodeList) XMLUtils.xpath(
+                result,
+                "/art:artifact-collections/art:artifact-collection",
+                XPathConstants.NODESET,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (list == null || list.getLength() == 0) {
+                System.out.println("No collection found for user: " + userid);
+                return null;
+            }
+
+            int num = list.getLength();
+
+            List<Collection> all = new ArrayList<Collection>(num);
+
+            for (int i = 0; i < num; i++) {
+                Collection c = createCollection(list.item(i));
+
+                if (c != null) {
+                    all.add(c);
+                }
+            }
+
+            System.out.println("User has " + all.size() + " collections.");
+
+            return (Collection[]) all.toArray(new Collection[all.size()]);
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        System.err.println("No user collections found.");
+        return null;
+    }
+
+
+    /**
+     * Extracts a SimpleCollection from <i>node</i>.
+     *
+     * @param node Contains information about a collection.
+     *
+     * @return a list of Simplecollections.
+     */
+    protected Collection createCollection(Node node) {
+        String creationStr = XMLUtils.xpathString(
+            node, "@art:creation", ArtifactNamespaceContext.INSTANCE);
+
+        String name = XMLUtils.xpathString(
+            node, "@art:name", ArtifactNamespaceContext.INSTANCE);
+
+        String uuid = XMLUtils.xpathString(
+            node, "@art:uuid", ArtifactNamespaceContext.INSTANCE);
+
+        if (uuid != null) {
+            long time = Long.parseLong(creationStr);
+            return new DefaultCollection(uuid, name, new Date(time));
+        }
+
+        System.err.println("Found an invalid Collection.");
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/UserServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,68 @@
+package de.intevation.flys.client.server;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.client.services.UserService;
+import de.intevation.flys.client.shared.exceptions.AuthenticationException;
+import de.intevation.flys.client.shared.model.DefaultUser;
+import de.intevation.flys.client.shared.model.User;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class UserServiceImpl
+extends      RemoteServiceServlet
+implements   UserService
+{
+    public static final String ERROR_NO_SUCH_USER = "error_no_such_user";
+
+    public User getCurrentUser(String serverUrl, String locale)
+    throws AuthenticationException
+    {
+        HttpClient client = new HttpClientImpl(serverUrl);
+
+        try {
+            Document users = (Document) client.listUsers();
+
+            String XPATH_USERS = "/art:users/art:user";
+
+            NodeList theUsers = (NodeList) XMLUtils.xpath(
+                users,
+                XPATH_USERS,
+                XPathConstants.NODESET,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (theUsers != null && theUsers.getLength() > 0) {
+                Node user = theUsers.item(0);
+
+                String uuid = XMLUtils.xpathString(
+                    user, "@art:uuid", ArtifactNamespaceContext.INSTANCE);
+                String name = XMLUtils.xpathString(
+                    user, "@art:name", ArtifactNamespaceContext.INSTANCE);
+
+                return new DefaultUser(uuid, name);
+            }
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        System.err.println("No users existing in the server.");
+        throw new AuthenticationException(ERROR_NO_SUCH_USER);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/WQInfoServiceImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,172 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
+import de.intevation.artifacts.httpclient.http.HttpClient;
+import de.intevation.artifacts.httpclient.http.HttpClientImpl;
+
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.client.services.WQInfoService;
+import de.intevation.flys.client.shared.model.WQInfoObject;
+import de.intevation.flys.client.shared.model.WQInfoObjectImpl;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class WQInfoServiceImpl
+extends      RemoteServiceServlet
+implements   WQInfoService
+{
+    public static final String ERROR_NO_WQINFO_FOUND =
+        "error_no_wqinfo_found";
+
+    public static final String XPATH_WQS = "art:service/art:mainvalues/art:mainvalue";
+
+
+    public WQInfoObject[] getWQInfo(
+        String url,
+        String locale,
+        String river,
+        double from,
+        double to)
+    throws ServerException
+    {
+        System.out.println("WQInfoServiceImpl.getWQInfo");
+
+        Document doc = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element mainvalues = ec.create("mainvalues");
+        Element riverEl = ec.create("river");
+        Element startEl = ec.create("start");
+        Element endEl   = ec.create("end");
+
+        riverEl.setTextContent(river);
+        startEl.setTextContent(Double.valueOf(from).toString());
+        endEl.setTextContent(Double.valueOf(to).toString());
+
+        mainvalues.appendChild(riverEl);
+        mainvalues.appendChild(startEl);
+        mainvalues.appendChild(endEl);
+
+        doc.appendChild(mainvalues);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+
+        try {
+            Document result = client.callService(url, "mainvalues", doc);
+
+            System.out.println("Extract wq info objects now.");
+            WQInfoObject[] objects = extractWQInfoObjects(result);
+
+            if (objects != null && objects.length > 0) {
+                return objects;
+            }
+        }
+        catch (ConnectionException ce) {
+            System.err.println(ce.getLocalizedMessage());
+        }
+
+        throw new ServerException(ERROR_NO_WQINFO_FOUND);
+    }
+
+
+    /**
+     * Extracts all wq info objects from <i>result</i> document.
+     *
+     * @param result The document retrieved by the server.
+     *
+     * @return a list of WQInfoObjects.
+     */
+    protected WQInfoObject[] extractWQInfoObjects(Document result)
+    throws    ServerException
+    {
+        NodeList list = (NodeList) XMLUtils.xpath(
+            result,
+            XPATH_WQS,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        if (list == null || list.getLength() == 0) {
+            System.err.println("No wq info found.");
+
+            throw new ServerException(ERROR_NO_WQINFO_FOUND);
+        }
+
+        int num = list.getLength();
+        System.out.println("Response contains " + num + " objects.");
+
+        List<WQInfoObject> objects =
+            new ArrayList<WQInfoObject>(num);
+
+        for (int i = 0; i < num; i++) {
+            WQInfoObject obj = buildWQInfoObject(list.item(i));
+
+            if (obj != null) {
+                objects.add(obj);
+            }
+        }
+
+        System.out.println("Retrieved " + objects.size() + " wq values");
+
+        return (WQInfoObject[])
+            objects.toArray(new WQInfoObject[num]);
+    }
+
+
+    /**
+     * Extracts information for a single wq info object and intializes an
+     * WQInfoObject with them.
+     *
+     * @param node The node that contains the information.
+     *
+     * @return a valid WQInfoObject.
+     */
+    protected WQInfoObject buildWQInfoObject(Node node) {
+        String name = XMLUtils.xpathString(
+            node, "@name", ArtifactNamespaceContext.INSTANCE);
+
+        String type = XMLUtils.xpathString(
+            node, "@type", ArtifactNamespaceContext.INSTANCE);
+
+        String value = XMLUtils.xpathString(
+            node, "@value", ArtifactNamespaceContext.INSTANCE);
+
+
+        if (name != null && type != null) {
+            try {
+                return new WQInfoObjectImpl(
+                    name,
+                    type,
+                    new Double(value));
+            }
+            catch (NumberFormatException nfe) {
+                System.err.println(nfe.getLocalizedMessage());
+            }
+        }
+
+        System.err.println("Invalid wq info object found.");
+
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/meta/Converter.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,110 @@
+package de.intevation.flys.client.server.meta;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import de.intevation.flys.client.shared.model.DataCageTree;
+import de.intevation.flys.client.shared.model.DataCageNode;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+public class Converter
+{
+    public interface NodeConverter
+    {
+        DataCageNode convert(Element node, Converter converter);
+
+    } // interface NodeConverter
+
+    public static class NameConverter implements NodeConverter {
+        public DataCageNode convert(Element node, Converter converter) {
+            System.err.println("NameConverter called");
+            DataCageNode out = new DataCageNode(node.getAttribute("name"));
+            converter.convertChildren(out, node);
+            return out;
+        }
+    } // class NameConverter
+
+    public static class I18NConverter implements NodeConverter {
+        public DataCageNode convert(Element node, Converter converter) {
+            System.err.println("I18NConverter called");
+            DataCageNode out =
+                new DataCageNode("${" + node.getLocalName() + "}");
+            converter.convertChildren(out, node);
+            return out;
+        }
+    } // I18NConverter
+
+    protected Map<String, NodeConverter> converters;
+
+    protected void convertChildren(DataCageNode parent, Element sub) {
+        System.err.println("convertChildren called");
+        NodeList children = sub.getChildNodes();
+        for (int i = 0, N = children.getLength(); i < N; ++i) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                String name = child.getLocalName();
+                NodeConverter converter = converters.get(name);
+                if (converter != null) {
+                    DataCageNode son = converter.convert(
+                        (Element)child, this);
+                    parent.addChild(son);
+                }
+            }
+        } // for all children
+    }
+
+    public Converter() {
+        converters = new HashMap<String, NodeConverter>();
+        registerConverters();
+    }
+
+    protected void registerConverters() {
+        System.err.println("register converters called");
+        converters.put("datacage",                    new NameConverter());
+        converters.put("river",                       new NameConverter());
+        converters.put("gauge",                       new NameConverter());
+        converters.put("historical",                  new NameConverter());
+        converters.put("discharge-table-nn",          new I18NConverter());
+        converters.put("discharge-table-gauge",       new I18NConverter());
+        converters.put("fixations",                   new I18NConverter());
+        converters.put("fixation",                    new I18NConverter());
+        converters.put("columns",                     new I18NConverter());
+        converters.put("column",                      new NameConverter());
+        converters.put("flood-protections",           new I18NConverter());
+        converters.put("flood-protection",            new I18NConverter());
+        converters.put("flood-water-marks",           new I18NConverter());
+        converters.put("flood-water-mark",            new I18NConverter());
+        converters.put("water-levels",                new I18NConverter());
+        converters.put("water-level",                 new I18NConverter());
+        converters.put("extra-longitudinal-sections", new I18NConverter());
+        converters.put("extra-longitudinal-section",  new I18NConverter());
+        converters.put("longitudinal-section",        new I18NConverter());
+    }
+
+    public DataCageTree convert(Document document) {
+        System.err.println("convert called");
+
+        ArrayList<DataCageNode> roots = new ArrayList<DataCageNode>();
+        NodeList nodes = document.getChildNodes();
+        for (int i = 0, N = nodes.getLength(); i < N; ++i) {
+            Node node = nodes.item(i);
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                System.err.println("search for name: " + node.getLocalName());
+                NodeConverter converter = converters.get(node.getLocalName());
+                if (converter != null) {
+                    roots.add(converter.convert((Element)node, this));
+                }
+            }
+        }
+        return roots.isEmpty()
+            ? new DataCageTree()
+            : new DataCageTree(roots.get(0));
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/FieldVerifier.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,42 @@
+package de.intevation.flys.client.shared;
+
+/**
+ * <p>
+ * FieldVerifier validates that the name the user enters is valid.
+ * </p>
+ * <p>
+ * This class is in the <code>shared</code> package because we use it in both
+ * the client code and on the server. On the client, we verify that the name is
+ * valid before sending an RPC request so the user doesn't have to wait for a
+ * network round trip to get feedback. On the server, we verify that the name is
+ * correct to ensure that the input is correct regardless of where the RPC
+ * originates.
+ * </p>
+ * <p>
+ * When creating a class that is used on both the client and the server, be sure
+ * that all code is translatable and does not use native JavaScript. Code that
+ * is note translatable (such as code that interacts with a database or the file
+ * system) cannot be compiled into client side JavaScript. Code that uses native
+ * JavaScript (such as Widgets) cannot be run on the server.
+ * </p>
+ */
+public class FieldVerifier {
+
+  /**
+   * Verifies that the specified name is valid for our service.
+   * 
+   * In this example, we only require that the name is at least four
+   * characters. In your application, you can use more complex checks to ensure
+   * that usernames, passwords, email addresses, URLs, and other fields have the
+   * proper syntax.
+   * 
+   * @param name the name to validate
+   * @return true if valid, false if invalid
+   */
+  public static boolean isValidName(String name) {
+    if (name == null) {
+      return false;
+    }
+    return name.length() > 3;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/exceptions/AuthenticationException.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,23 @@
+package de.intevation.flys.client.shared.exceptions;
+
+import java.io.Serializable;
+
+
+/**
+ * This exception class is used if an error occured while user authentication.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class AuthenticationException
+extends      Exception
+implements   Serializable
+{
+    public AuthenticationException() {
+    }
+
+
+    public AuthenticationException(String msg) {
+        super(msg);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/exceptions/ServerException.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,17 @@
+package de.intevation.flys.client.shared.exceptions;
+
+import java.io.Serializable;
+
+
+public class ServerException
+extends      Exception
+implements   Serializable
+{
+    public ServerException() {
+    }
+
+
+    public ServerException(String msg) {
+        super(msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Artifact.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,52 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * This class represents an artifact for the client. It contains the necessary
+ * information for the client and the communication with the artifact server.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface Artifact extends Serializable {
+
+    /**
+     * Returns the UUID of the artifact.
+     *
+     * @return the UUID.
+     */
+    public String getUuid();
+
+
+    /**
+     * Returns the hash of the artifact.
+     *
+     * @return the hash.
+     */
+    public String getHash();
+
+
+    /**
+     * Returns the name of the artifact.
+     *
+     * @return the name-
+     */
+    public String getName();
+
+    /**
+     * Returns the ArtifactDescription.
+     *
+     * @return the artifact description.
+     */
+    public ArtifactDescription getArtifactDescription();
+
+
+    /**
+     * Sets a new ArtifactDescription.
+     *
+     * @param artifactDescription The new artifact description.
+     */
+    public void setArtifactDescription(ArtifactDescription artifactDescription);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/ArtifactDescription.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,56 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * The artifact description describes a state of an artifact. There are
+ * operations defined that return former inserted data, possible input values
+ * and output targets that are available in the current state of the artifact.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface ArtifactDescription extends Serializable {
+
+    /**
+     * Returns the data that have been inserted in former states of the
+     * artifact.
+     *
+     * @return the old data of former states.
+     */
+    public DataList[] getOldData();
+
+
+    /**
+     * Returns the data with all its options that might be inserted in the
+     * current state of the artifact.
+     *
+     * @return the current data.
+     */
+    public DataList getCurrentData();
+
+
+    /**
+     * Returns the current state as string.
+     *
+     * @return the current state.
+     */
+    public String getCurrentState();
+
+
+    /**
+     * Returns the reachable states as string.
+     *
+     * @return the reachable states.
+     */
+    public String[] getReachableStates();
+
+
+    /**
+     * Returns the available output modes.
+     * 
+     * @return the available output modes.
+     */
+    public OutputMode[] getOutputModes();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Collection.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,31 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Map;
+
+
+/**
+ * The artifact collection.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface Collection extends Serializable {
+
+    public String identifier();
+
+    public String getName();
+
+    public Date getCreationTime();
+
+    public Date getLastAccess();
+
+    public void addItem(CollectionItem item);
+
+    public int getItemLength();
+
+    public CollectionItem getItem(int idx);
+
+    public Map<String, OutputMode> getOutputModes();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/CollectionItem.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,49 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * The CollectionItem interface that provides methods to get information about
+ * artifacts and its output modes.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface CollectionItem extends Serializable {
+
+    /**
+     * Returns the identifier of the wrapped artifact.
+     *
+     * @return the identifier of the wrapped artifact.
+     */
+    String identifier();
+
+
+    /**
+     * Returns the hash of the wrapped artifact.
+     *
+     * @return the hash of the wrapped artifact.
+     */
+    String hash();
+
+
+    /**
+     * Returns the output modes of the wrapped artifact.
+     *
+     * @return the output modes of the wrapped artifact.
+     */
+    List<OutputMode> getOutputModes();
+
+
+    /**
+     * Returns the facets of the wrapped artifact for a specific output mode.
+     *
+     * @param outputmode The name of an output mode that is supported by this
+     * item.
+     *
+     * @return the facets of the wrapped artifact for a specific output mode.
+     */
+    List<Facet> getFacets(String outputmode);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/CollectionRecord.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,85 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.Date;
+
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+
+/**
+ * The CollectionRecord is a wrapper to put Collection objects into a ListGrid.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class CollectionRecord extends ListGridRecord {
+
+    /** The artifact collection. */
+    protected Collection collection;
+
+
+    /**
+     * The default constructor.
+     *
+     * @param collection The artifact collection.
+     */
+    public CollectionRecord(Collection collection) {
+        this.collection = collection;
+
+        setCreationTime(collection.getCreationTime());
+
+        String name = collection.getName();
+        setName(name != null && name.length() > 0
+            ? name
+            : collection.identifier());
+    }
+
+
+    /**
+     * Sets the creation time.
+     *
+     * @param creationTime The creation time.
+     */
+    public void setCreationTime(Date creationTime) {
+        setAttribute("creationTime", creationTime);
+    }
+
+
+    /**
+     * Returns the date of the creation.
+     *
+     * @return the creation time.
+     */
+    public Date getCreationTime() {
+        return getAttributeAsDate("creationTime");
+    }
+
+
+    /**
+     * Returns the name of the collection.
+     *
+     * @return the name of the collection.
+     */
+    public void setName(String name) {
+        setAttribute("name", name);
+    }
+
+
+    /**
+     * Returns the name of the collection or the uuid if no name is specified.
+     *
+     * @return the name of the collection.
+     */
+    public String getName() {
+        return getAttributeAsString("name");
+    }
+
+
+    /**
+     * Returns the collection objects itself.
+     *
+     * @return the collection object.
+     */
+    public Collection getCollection() {
+        return collection;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Data.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,46 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * A Data object represents the necessary data of a single state of the
+ * artifact. It might provide several DataItems or just a single DataItem. The
+ * <code>type</code> makes it possible to validate the input in the client.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface Data extends Serializable {
+
+    /**
+     * Returns the label of the item.
+     *
+     * @return the label.
+     */
+    public String getLabel();
+
+
+    /**
+     * Returns the description of the item.
+     *
+     * @return the description.
+     */
+    public String getDescription();
+
+
+    /**
+     * Returns the type of the item.
+     *
+     * @return the type.
+     */
+    public String getType();
+
+
+    /**
+     * Returns the DataItems provided by this Data object.
+     *
+     * @return the DataItems.
+     */
+    public DataItem[] getItems();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DataCageNode.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,39 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import java.io.Serializable;
+
+public class DataCageNode implements Serializable
+{
+    protected String             name;
+    protected List<DataCageNode> children;
+
+    public DataCageNode() {
+    }
+
+    public DataCageNode(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void addChild(DataCageNode child) {
+        if (children == null) {
+            children = new ArrayList<DataCageNode>();
+        }
+        children.add(child);
+    }
+
+    public List<DataCageNode> getChildren() {
+        return children;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DataCageTree.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,24 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+public class DataCageTree implements Serializable
+{
+    protected DataCageNode root;
+
+    public DataCageTree() {
+    }
+
+    public DataCageTree(DataCageNode root) {
+        this.root = root;
+    }
+
+    public void setRoot(DataCageNode root) {
+        this.root = root;
+    }
+
+    public DataCageNode getRoot() {
+        return root;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DataItem.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,37 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * A DataItem represents a concrete item that might be selected, chosen or
+ * inserted by the user.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface DataItem extends Serializable {
+
+    /**
+     * Returns the label of the item.
+     *
+     * @return the label.
+     */
+    public String getLabel();
+
+
+    /**
+     * Returns the description of the item.
+     *
+     * @return the description;
+     */
+    public String getDescription();
+
+
+    /**
+     * Returns the value of the item.
+     *
+     * @return the value.
+     */
+    public String getStringValue();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DataList.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,165 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DataList implements Serializable {
+
+    /** The list of Data objects managed by this list.*/
+    protected List<Data> data;
+
+    /** The name of the state that this list belongs to.*/
+    protected String state;
+
+    /** The name of a UIProvider that is recommended to render this DataList.*/
+    protected String uiprovider;
+
+    /** The label that should be used to label data objects.*/
+    protected String label;
+
+
+    /**
+     * The default constructor that creates a new DataList without Data objects
+     * and no UIProvider.
+     */
+    public DataList() {
+        data = new ArrayList<Data>();
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param state The name of the state that this list belongs to.
+     * @param size The initial size of the list.
+     */
+    public DataList(String state, int size) {
+        this.state = state;
+        this.data  = new ArrayList<Data>(size);
+    }
+
+
+    /**
+     * A constructor that creates a new DataList without Data objects and no
+     * UIProvider. Size defines the initial size of the list.
+     *
+     * @param state The name of the state that this list belongs to.
+     * @param size The initial size of the list.
+     * @param uiprovider The UIProvider that should be used to render this list.
+     */
+    public DataList(String state, int size, String uiprovider) {
+        this(state, size);
+        this.uiprovider = uiprovider;
+    }
+
+
+    /**
+     * A constructor that creates a new DataList without Data objects and no
+     * UIProvider. Size defines the initial size of the list.
+     *
+     * @param state The name of the state that this list belongs to.
+     * @param size The initial size of the list.
+     * @param uiprovider The UIProvider that should be used to render this list.
+     * @param label The label.
+     */
+    public DataList(String state, int size, String uiprovider, String label) {
+        this(state, size, uiprovider);
+        this.label = label;
+    }
+
+
+    /**
+     * Adds a new Data object to the list.
+     *
+     * @param obj The Data object.
+     */
+    public void add(Data obj) {
+        if (obj != null) {
+            data.add(obj);
+        }
+    }
+
+
+    /**
+     * Adds a new Data objects to the list.
+     *
+     * @param obj The Data object.
+     */
+    public void add(Data[] obj) {
+        if (obj != null) {
+            for (Data o: obj) {
+                data.add(o);
+            }
+        }
+    }
+
+
+    /**
+     * Returns the Data element at position <i>idx</i>.
+     *
+     * @param idx The position of an element that should be returned.
+     *
+     * @return the Data element at position <i>idx</i>.
+     */
+    public Data get(int idx) {
+        if (idx < size()) {
+            return data.get(idx);
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Returns the whole list of Data objects.
+     *
+     * @return the whole list of Data objects.
+     */
+    public List<Data> getAll() {
+        return data;
+    }
+
+    /**
+     * Returns the number of Data objects in the list.
+     *
+     * @param the number of Data objects in the list.
+     */
+    public int size() {
+        return data.size();
+    }
+
+
+    /**
+     * Returns the name of the state that this list belongs to.
+     *
+     * @return the name of the state that this list belongs to.
+     */
+    public String getState() {
+        return state;
+    }
+
+
+    /**
+     * Returns the label for this list.
+     *
+     * @return the label of this list.
+     */
+    public String getLabel() {
+        return label;
+    }
+
+
+    /**
+     * Retrieves the name of a UIProvider or null if no one is recommended.
+     *
+     * @return the name of a UIProvider or null if no one is recommended.
+     */
+    public String getUIProvider() {
+        return uiprovider;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifact.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,65 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The default implementation of an artifact that might be used in the client.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultArtifact implements Artifact {
+
+    /** The artifact's uuid.*/
+    protected String uuid;
+
+    /** The artifacts hash value.*/
+    protected String hash;
+
+    /** The current artifact description.*/
+    protected ArtifactDescription artifactDescription;
+
+    /**
+     * This constructor should not be used to create new instances of this
+     * class. An empty artifact without uuid and hash will be the result of
+     * this constructor call.
+     */
+    public DefaultArtifact() {
+    }
+
+
+    /**
+     * This constructor creates a new artifact instance with a uuid and a hash.
+     *
+     * @param uuid The artifact's uuid.
+     * @param hash The artifact's hash.
+     */
+    public DefaultArtifact(String uuid, String hash) {
+        this.uuid = uuid;
+        this.hash = hash;
+    }
+
+
+    public String getUuid() {
+        return uuid;
+    }
+
+
+    public String getHash() {
+        return hash;
+    }
+
+
+    public String getName() {
+        return "default";
+    }
+
+
+    public ArtifactDescription getArtifactDescription() {
+        return artifactDescription;
+    }
+
+
+    public void setArtifactDescription(ArtifactDescription description) {
+        this.artifactDescription = description;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,99 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The default implementation of an {@link ArtifactDescription}. This class just
+ * implements constructors to create new instances and the necessary methods of
+ * the interface.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultArtifactDescription implements ArtifactDescription {
+
+    /** Data that have been inserted in former states.*/
+    protected DataList[] oldData;
+
+    /** The Data that is allowed to be inserted in the current state.*/
+    protected DataList currentData;
+
+    /** The current state name.*/
+    protected String   currentState;
+
+    /** The names of reachable states.*/
+    protected String[] reachableStates;
+
+    /** The output modes of this state.*/
+    protected OutputMode[] outputModes;
+
+
+    public DefaultArtifactDescription() {
+    }
+
+
+    /**
+     * The default constructor.
+     *
+     * @param old The data that have been inserted in former states.
+     * @param current The data that might be inserted in the current state.
+     * @param state The name of the current state.
+     * @param reachableStates The names of the reachable states.
+     */
+    public DefaultArtifactDescription(
+        DataList[]   old,
+        DataList     current,
+        String       state,
+        String[]     reachableStates)
+    {
+        this.oldData         = old;
+        this.currentData     = current;
+        this.currentState    = state;
+        this.reachableStates = reachableStates;
+    }
+
+
+    /**
+     * The default constructor.
+     *
+     * @param old The data that have been inserted in former states.
+     * @param current The data that might be inserted in the current state.
+     * @param state The name of the current state.
+     * @param reachableStates The names of the reachable states.
+     * @param outputModes The available output modes of this artifact.
+     */
+    public DefaultArtifactDescription(
+        DataList[]   old,
+        DataList     current,
+        String       state,
+        String[]     reachableStates,
+        OutputMode[] outputModes)
+    {
+        this(old, current, state, reachableStates);
+        this.outputModes = outputModes;
+    }
+
+
+    public DataList[] getOldData() {
+        return oldData;
+    }
+
+
+    public DataList getCurrentData() {
+        return currentData;
+    }
+
+
+    public String getCurrentState() {
+        return currentState;
+    }
+
+
+    public String[] getReachableStates() {
+        return reachableStates;
+    }
+
+
+    public OutputMode[] getOutputModes() {
+        return outputModes;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,136 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * The default implementation of a {@link Collection}.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultCollection implements Collection {
+
+    /** The uuid of the collection. */
+    protected String uuid;
+
+    /** The name of the collection.*/
+    protected String name;
+
+    /** The creation time of this collection.*/
+    protected Date creation;
+
+    /** The list of artifacts that are managed by this Collection.*/
+    protected List<CollectionItem> items;
+
+
+    /**
+     * Constructor without arguments is necessary for GWT.
+     */
+    public DefaultCollection() {
+    }
+
+
+    /**
+     * Creates a new DefaultCollection with a UUID.
+     *
+     * @param uuid The UUID.
+     */
+    public DefaultCollection(String uuid) {
+        this.uuid  = uuid;
+        this.items = new ArrayList<CollectionItem>();
+    }
+
+
+    /**
+     * Creates a new DefaultCollection with uuid and name.
+     *
+     * @param uuid The identifier of this collection.
+     * @param name The name of this collection.
+     */
+    public DefaultCollection(String uuid, String name) {
+        this(uuid);
+
+        this.name = name;
+    }
+
+
+    /**
+     * Creates a new DefaultCollection with uuid and name.
+     *
+     * @param uuid The identifier of this collection.
+     * @param name The name of this collection.
+     * @param creation The creation time.
+     */
+    public DefaultCollection(String uuid, String name, Date creation) {
+        this(uuid, name);
+
+        this.creation = creation;
+    }
+
+
+    public String identifier() {
+        return uuid;
+    }
+
+
+    public Date getCreationTime() {
+        return creation;
+    }
+
+
+    public Date getLastAccess() {
+        return new Date();
+    }
+
+
+    public String getName() {
+        return name;
+    }
+
+
+    public void addItem(CollectionItem item) {
+        if (item != null) {
+            items.add(item);
+        }
+    }
+
+
+    public int getItemLength() {
+        return items.size();
+    }
+
+
+    public CollectionItem getItem(int idx) {
+        if (idx >= getItemLength()) {
+            return null;
+        }
+
+        return items.get(idx);
+    }
+
+
+    public Map<String, OutputMode> getOutputModes() {
+        Map<String, OutputMode> modes = new HashMap<String, OutputMode>();
+
+        for (CollectionItem item: items) {
+            List<OutputMode> itemModes = item.getOutputModes();
+
+            if (itemModes != null) {
+                for (OutputMode itemMode: itemModes) {
+                    String name = itemMode.getName();
+                    if (!modes.containsKey(name)) {
+                        // we dont want duplicated OutputModes in our result.
+                        modes.put(name, itemMode);
+                    }
+                }
+            }
+        }
+
+        return modes;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollectionItem.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,73 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.List;
+
+
+/**
+ * The default implementation of a CollectionItem.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultCollectionItem implements CollectionItem {
+
+    /** The identifier that specifies the artifact related to this item.*/
+    protected String identifier;
+
+    /** The hash that specifies the artifact related to this item.*/
+    protected String hash;
+
+    /** The list of output modes supported by the artifact of this item.*/
+    protected List<OutputMode> outputModes;
+
+
+    /**
+     * An empty constructor.
+     */
+    public DefaultCollectionItem() {
+    }
+
+
+    /**
+     * The default constructor to create a new CollectionItem related to an
+     * artifact with output modes.
+     *
+     * @param identifier The identifier of an artifact.
+     * @param outputModes The output modes supported by this item.
+     */
+    public DefaultCollectionItem(
+        String           identifier,
+        String           hash,
+        List<OutputMode> modes) {
+        this.identifier  = identifier;
+        this.hash        = hash;
+        this.outputModes = modes;
+    }
+
+
+    public String identifier() {
+        return identifier;
+    }
+
+
+    public String hash() {
+        return hash;
+    }
+
+
+    public List<OutputMode> getOutputModes() {
+        return outputModes;
+    }
+
+
+    public List<Facet> getFacets(String outputmode) {
+        for (OutputMode mode: outputModes) {
+            if (outputmode.equals(mode.getName())) {
+                // TODO Return facets, but facets are not implemented for
+                // OutputModes yet!
+            }
+        }
+
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultData.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,69 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The default implementation of a {@link Data} item. This class just implements
+ * constructors to create instances and the necessary methods of the interface.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultData implements Data {
+
+    /** The label of this Data object.*/
+    protected String label;
+
+    /** The description.*/
+    protected String description;
+
+    /** The type.*/
+    protected String type;
+
+    /** The DataItems.*/
+    protected DataItem[] items;
+
+
+    public DefaultData() {
+    }
+
+
+    /**
+     * The default constructor to create new DefaultData objects.
+     *
+     * @param label The label.
+     * @param description The description.
+     * @param type The type.
+     * @param items The DataItems.
+     */
+    public DefaultData(
+        String label,
+        String description,
+        String type,
+        DataItem[] items)
+    {
+        this.label       = label;
+        this.description = description;
+        this.type        = type;
+        this.items       = items;
+    }
+
+
+    public String getLabel() {
+        return label;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public String getType() {
+        return type;
+    }
+
+
+    public DataItem[] getItems() {
+        return items;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultDataItem.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,54 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The default implementation of a {@link DataItem}. This class just implements
+ * constructors to create instances and the necessary methods of the interface.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultDataItem implements DataItem {
+
+    /** The label.*/
+    protected String label;
+
+    /** The description.*/
+    protected String description;
+
+    /** The value.*/
+    protected String value;
+
+
+    public DefaultDataItem() {
+    }
+
+
+    /**
+     * The default constructor to create new instances.
+     *
+     * @param label The label.
+     * @param description The description.
+     * @param value The value.
+     */
+    public DefaultDataItem(String label, String description, String value) {
+        this.label       = label;
+        this.description = description;
+        this.value       = value;
+    }
+
+
+    public String getLabel() {
+        return label;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public String getStringValue() {
+        return value;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultFacet.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,36 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The default implementation of a Facet.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultFacet implements Facet {
+
+    /** The name of the facet.*/
+    protected String name;
+
+
+    /**
+     * An empty constructor.
+     */
+    public DefaultFacet() {
+    }
+
+
+    /**
+     * The default constructor to create new DefaultFacets.
+     *
+     * @param name The name of the facet.
+     */
+    public DefaultFacet(String name) {
+        this.name = name;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultOutputMode.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,124 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The default implementation of an Output.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultOutputMode implements OutputMode {
+
+    /** The name of this mode.*/
+    protected String name;
+
+    /** The description of this mode.*/
+    protected String description;
+
+    /** The mime-type of this mode.*/
+    protected String mimeType;
+
+    /** The list of available facets of this export mode.*/
+    protected List<Facet> facets;
+
+
+    /** A convinience constructor.*/
+    public DefaultOutputMode() {
+        facets = new ArrayList<Facet>();
+    }
+
+
+    /**
+     * The default constructor.
+     *
+     * @param name The name of this mode.
+     * @param description The description of this mode.
+     * @param mimeType The mime-type of this mode.
+     */
+    public DefaultOutputMode(String name, String description, String mimeType) {
+        this.name        = name;
+        this.description = description;
+        this.mimeType    = mimeType;
+    }
+
+
+    public DefaultOutputMode(
+        String name,
+        String description,
+        String mimeType,
+        List<Facet> facets)
+    {
+        this(name, description, mimeType);
+        this.facets = facets;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public String getMimeType() {
+        return mimeType;
+    }
+
+
+    /**
+     * Adds a new facet to this export.
+     *
+     * @param facet The new facet.
+     */
+    public void addFacet(Facet facet) {
+        facets.add(facet);
+    }
+
+
+    /**
+     * Returns the number of facets supported by this export.
+     *
+     * @return the number of facets.
+     */
+    public int getFacetCount() {
+        return facets.size();
+    }
+
+
+    /**
+     * Returns the facet at a given position.
+     *
+     * @param idx The position of a facet.
+     *
+     * @return a facet.
+     */
+    public Facet getFacet(int idx) {
+        if (idx < getFacetCount()) {
+            return facets.get(idx);
+        }
+
+        return null;
+    }
+
+
+    public Facet getFacet(String name) {
+        for (Facet facet: facets) {
+            if (name.equals(facet.getName())) {
+                return facet;
+            }
+        }
+
+        return null;
+    }
+
+
+    public List<Facet> getFacets() {
+        return facets;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultRiver.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,50 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The simpliest default implementation of a River that just stores a name.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultRiver implements River {
+
+    /** The name of the river.*/
+    protected String name;
+
+    /**
+     * The default constructor that creates empty river objects.
+     */
+    public DefaultRiver() {
+    }
+
+
+    /**
+     * This constructor should be used to create new rivers.
+     *
+     * @param name The name of the river.
+     */
+    public DefaultRiver(String name) {
+        this.name = name;
+    }
+
+
+    /**
+     * Sets the name of the river.
+     *
+     * @param name The name of the river.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    /**
+     * Returns the name of the river.
+     *
+     * @return the name of the river.
+     */
+    public String getName() {
+        return name;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultUser.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011 by Intevation GmbH
+ *
+ * This program is free software under the LGPL (>=v2.1)
+ * Read the file LGPL.txt coming with the software for details
+ * or visit http://www.gnu.org/licenses/ if it does not exist.
+ */
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * Trivial implementation of a user. Useful to be subclassed.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultUser
+implements   User
+{
+    /** The identifier of the user.*/
+    protected String identifier;
+
+    /** The name of the user.*/
+    protected String name;
+
+
+    /**
+     * The default constructor.
+     */
+    public DefaultUser() {
+    }
+
+
+    /**
+     * A constructor that creates a new user.
+     *
+     * @param identifier The uuid of the user.
+     * @param name The name of the user.
+     */
+    public DefaultUser(String identifier, String name) {
+        this.identifier = identifier;
+        this.name       = name;
+    }
+
+
+    /**
+     * Returns the identifier of this user.
+     *
+     * @return the identifier of this user.
+     */
+    public String identifier() {
+        return identifier;
+    }
+
+
+    /**
+     * Returns the name of the user.
+     *
+     * @return the name of the user.
+     */
+    public String getName() {
+        return name;
+    }
+
+
+    /**
+     * Set the identifier of the user.
+     *
+     * @param identifier The new identifier.
+     */
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+
+    /**
+     * Set the name of the user.
+     *
+     * @param name The name for this user.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DistanceInfoObject.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,19 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface DistanceInfoObject extends Serializable {
+
+    String getDescription();
+
+    Double getFrom();
+
+    Double getTo();
+
+    String getRiverside();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DistanceInfoObjectImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,54 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DistanceInfoObjectImpl implements DistanceInfoObject {
+
+    protected String description;
+
+    protected Double from;
+
+    protected Double to;
+
+    protected String riverside;
+
+
+    public DistanceInfoObjectImpl() {
+    }
+
+
+    public DistanceInfoObjectImpl(
+        String description,
+        Double from,
+        Double to,
+        String riverside)
+    {
+        this.description = description;
+        this.from        = from;
+        this.to          = to;
+        this.riverside   = riverside;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public Double getFrom() {
+        return from;
+    }
+
+
+    public Double getTo() {
+        return to;
+    }
+
+
+    public String getRiverside() {
+        return riverside;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DistanceInfoRecord.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,89 @@
+package de.intevation.flys.client.shared.model;
+
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+
+/**
+ * The DistanceInfoRecord is a wrapper to put DistanceInfo objects into
+ * a ListGrid.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class DistanceInfoRecord extends ListGridRecord {
+
+    /** The artifact collection. */
+    protected DistanceInfoObject distanceInfo;
+
+
+    /**
+     * The default constructor.
+     *
+     * @param info The distance info object.
+     */
+    public DistanceInfoRecord(DistanceInfoObject info) {
+        this.distanceInfo = info;
+
+        setDescription(info.getDescription());
+        setFrom(info.getFrom());
+        if (info.getTo() != null)
+            setTo(info.getTo());
+        else
+            setTo(info.getFrom());
+        setRiverside(info.getRiverside());
+    }
+
+
+    /**
+     * Sets the creation time.
+     *
+     * @param creationTime The creation time.
+     */
+    public void setDescription(String description) {
+        setAttribute("description", description);
+    }
+
+
+    /**
+     * Returns the description.
+     *
+     * @return the description.
+     */
+    public String getDescription() {
+        return getAttributeAsString("description");
+    }
+
+
+    public void setFrom(double from) {
+        setAttribute("from", from);
+    }
+
+
+    public double getFrom() {
+        return getAttributeAsDouble("from");
+    }
+
+    public void setTo(double to) {
+        setAttribute("to", to);
+    }
+
+
+    public double getTo() {
+        return getAttributeAsDouble("to");
+    }
+
+
+    public void setRiverside(String side) {
+        setAttribute("riverside", side);
+    }
+
+
+    public String getRiverside() {
+        return getAttributeAsString("riverside");
+    }
+
+
+    public DistanceInfoObject getDistanceInfo() {
+        return distanceInfo;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/ExportMode.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,33 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.List;
+
+
+/**
+ * An derived OutputMode that marks an OutputMode as an export. An export mode
+ * should at least support one (or more) facet which specify the type of export
+ * (e.g. CSV, WST).
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ExportMode extends DefaultOutputMode {
+
+    public ExportMode() {
+    }
+
+
+    public ExportMode(String name, String desc, String mimeType) {
+        super(name, desc, mimeType);
+    }
+
+
+    public ExportMode(
+        String name,
+        String descrition,
+        String mimeType,
+        List<Facet> facets)
+    {
+        super(name, descrition, mimeType, facets);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Facet.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,20 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * The interface that provides methods to retrieve information about a Facet.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface Facet extends Serializable {
+
+    /**
+     * Returns the name of a facet.
+     *
+     * @return the name of a facet.
+     */
+    String getName();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/OutputMode.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,82 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * This interface describes an output mode of an artifact.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface OutputMode extends Serializable {
+
+    /**
+     * Retrieves the name of this mode.
+     *
+     * @return the name of this mode.
+     */
+    String getName();
+
+
+    /**
+     * Retrieves the description of this mode.
+     *
+     * @return the description of this mode.
+     */
+    String getDescription();
+
+
+    /**
+     * Retrieves the mime-type of this mode.
+     *
+     *
+     * @return the mime-type of this mode.
+     */
+    String getMimeType();
+
+
+    /**
+     * Adds a new facet to this mode.
+     *
+     * @param facet The new facet.
+     */
+    void addFacet(Facet facet);
+
+
+    /**
+     * Returns the number of facets supported by this mode.
+     *
+     * @return the number of facets.
+     */
+    int getFacetCount();
+
+
+    /**
+     * Returns the facet at a given position.
+     *
+     * @param idx The position of a facet.
+     *
+     * @return a facet.
+     */
+    Facet getFacet(int idx);
+
+
+    /**
+     * Returns a facet based on its name.
+     *
+     * @param name The name of the facet.
+     *
+     * @return a facet or null if no such facet is available.
+     */
+    Facet getFacet(String name);
+
+
+    /**
+     * Returns all facets of this mode.
+     *
+     * @return all facets.
+     */
+    List<Facet> getFacets();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/River.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,12 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface River extends Serializable {
+
+    String getName();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/User.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011 by Intevation GmbH
+ *
+ * This program is free software under the LGPL (>=v2.1)
+ * Read the file LGPL.txt coming with the software for details
+ * or visit http://www.gnu.org/licenses/ if it does not exist.
+ */
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+public interface User
+extends          Serializable
+{
+    String identifier();
+
+    String getName();
+
+    void setName(String name);
+
+    void setIdentifier(String identifier);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/WINFOArtifact.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,28 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * The WINFO implementation of an Artifact.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class WINFOArtifact extends DefaultArtifact {
+
+    /** The name of this artifact: 'winfo'.*/
+    public static final String NAME = "winfo";
+
+
+    public WINFOArtifact() {
+    }
+
+
+    public  WINFOArtifact(String uuid, String hash) {
+        super(uuid, hash);
+    }
+
+
+    public String getName() {
+        return NAME;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/WQInfoObject.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,17 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public interface WQInfoObject extends Serializable {
+
+    String getName();
+
+    String getType();
+
+    Double getValue();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/WQInfoObjectImpl.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,45 @@
+package de.intevation.flys.client.shared.model;
+
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class WQInfoObjectImpl implements WQInfoObject {
+
+    protected String name;
+
+    protected String type;
+
+    protected Double value;
+
+
+    public WQInfoObjectImpl() {
+    }
+
+
+    public WQInfoObjectImpl(
+        String name,
+        String type,
+        Double value)
+    {
+        this.name  = name;
+        this.type  = type;
+        this.value = value;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+
+
+    public String getType() {
+        return type;
+    }
+
+
+    public Double getValue() {
+        return value;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/WQInfoRecord.java	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,68 @@
+package de.intevation.flys.client.shared.model;
+
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+
+/**
+ * The WQInfoRecord is a wrapper to put  WQ Info objects into
+ * a ListGrid.
+ *
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class WQInfoRecord extends ListGridRecord {
+
+    /** The artifact collection. */
+    protected WQInfoObject wqInfo;
+
+
+    /**
+     * The default constructor.
+     *
+     * @param info The wq info object.
+     */
+    public WQInfoRecord(WQInfoObject info) {
+        this.wqInfo = info;
+
+        setName(info.getName());
+        setType(info.getType());
+        if (info.getValue() != null)
+            setValue(info.getValue());
+        else
+            setValue(info.getValue());
+    }
+
+
+    public void setName(String name) {
+        setAttribute("name", name);
+    }
+
+
+    public String getName() {
+        return getAttributeAsString("name");
+    }
+
+
+    public void setType(String type) {
+        setAttribute("type", type);
+    }
+
+
+    public String getType() {
+        return getAttributeAsString("type");
+    }
+
+    public void setValue(double value) {
+        setAttribute("value", value);
+    }
+
+
+    public double getValue() {
+        return getAttributeAsDouble("value");
+    }
+
+
+    public WQInfoObject getWQInfo() {
+        return wqInfo;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/webapp/FLYS.css	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,96 @@
+/** Add css rules here for your application. */
+
+
+/** Example rules used by the template application (remove for your app) */
+h1 {
+  font-size: 2em;
+  font-weight: bold;
+  color: #777777;
+  margin: 40px 0px 70px;
+  text-align: center;
+}
+
+.sendButton {
+  display: block;
+  font-size: 16pt;
+}
+
+/** Most GWT widgets already have a style name defined */
+.gwt-DialogBox {
+  width: 400px;
+}
+
+.dialogVPanel {
+  margin: 5px;
+}
+
+.serverResponseLabelError {
+  color: red;
+}
+
+/** Set ids using widget.getElement().setId("idOfElement") */
+#closeButton {
+  margin: 15px 6px 6px;
+}
+
+
+/** BfG Colors */
+.bgWhite {
+  background-color: #ffffff;
+}
+
+.bgBlueLight {
+  background-color: #cfe1f1;
+}
+
+.bgBlueMid {
+  background-color: #a9c9e6;
+}
+
+.bgBlueDark {
+  background-color: #669fd1;
+}
+
+
+/** Fontstyles */
+.fontLightSmall {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 10pt;
+  color: #cfe1f1;
+}
+
+.fontLightMid {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 12pt;
+  color: #cfe1f1;
+}
+
+.fontLightBig {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 18pt;
+  color: #cfe1f1;
+}
+
+.fontNormalSmall {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 10pt;
+  color: #a9c9e6;
+}
+
+.fontNormalMid {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 12pt;
+  color: #a9c9e6;
+}
+
+.fontNormalBig {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 18pt;
+  color: #a9c9e6;
+}
+
+.fontNormalSmallUnderlined {
+  font-family: Arial,Verdana,sans-serif;
+  font-size: 10pt;
+  text-decoration: underline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/webapp/FLYS.html	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,52 @@
+<!doctype html>
+<!-- The DOCTYPE declaration above will set the    -->
+<!-- browser's rendering engine into               -->
+<!-- "Standards Mode". Replacing this declaration  -->
+<!-- with a "Quirks Mode" doctype may lead to some -->
+<!-- differences in layout.                        -->
+
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+    <meta name="gwt:property" content="locale=de">
+
+    <!--                                                               -->
+    <!-- Consider inlining CSS to reduce the number of requested files -->
+    <!--                                                               -->
+    <link type="text/css" rel="stylesheet" href="FLYS.css">
+
+    <!--                                           -->
+    <!-- Any title is fine                         -->
+    <!--                                           -->
+    <title>FLYS-3.0</title>
+    
+    <!--                                           -->
+    <!-- This script loads your compiled module.   -->
+    <!-- If you add any GWT meta tags, they must   -->
+    <!-- be added before this line.                -->
+    <!--                                           -->
+    <script type="text/javascript" language="javascript" src="flys/flys.nocache.js"></script>
+  </head>
+
+    <!--                                           -->
+    <!-- The body can have arbitrary html, or      -->
+    <!-- you can leave the body empty if you want  -->
+    <!-- to create a completely dynamic UI.        -->
+    <!--                                           -->
+    <body style="margin:0px">
+
+        <!-- OPTIONAL: include this if you want history support -->
+        <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
+
+        <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
+        <noscript>
+            <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
+                Your web browser must have JavaScript enabled
+                in order for this application to display correctly.
+            </div>
+        </noscript>
+
+        <div id="app"></div>
+    </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/webapp/WEB-INF/web.xml	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+  
+  <!-- Servlets -->
+  <servlet>
+    <servlet-name>user</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.UserServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>user</servlet-name>
+    <url-pattern>/flys/user</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>artifact</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.ArtifactServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>artifact</servlet-name>
+    <url-pattern>/flys/artifact</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>getartifact</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.GetArtifactServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>getartifact</servlet-name>
+    <url-pattern>/flys/getartifact</url-pattern>
+  </servlet-mapping>
+
+
+  <servlet>
+    <servlet-name>create-collection</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.CreateCollectionServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>create-collection</servlet-name>
+    <url-pattern>/flys/create-collection</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>rivers</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.RiverServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>rivers</servlet-name>
+    <url-pattern>/flys/rivers</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>forward</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.StepForwardServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>forward</servlet-name>
+    <url-pattern>/flys/forward</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>advance</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.AdvanceServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>advance</servlet-name>
+    <url-pattern>/flys/advance</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>add-artifact</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.AddArtifactServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>add-artifact</servlet-name>
+    <url-pattern>/flys/add-artifact</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>describe-collection</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.DescribeCollectionServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>describe-collection</servlet-name>
+    <url-pattern>/flys/describe-collection</url-pattern>
+  </servlet-mapping>
+
+    <servlet>
+    <servlet-name>user-collections</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.UserCollectionsServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>user-collections</servlet-name>
+    <url-pattern>/flys/user-collections</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>distanceinfo</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.DistanceInfoServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>distanceinfo</servlet-name>
+    <url-pattern>/flys/distanceinfo</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>meta-data</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.MetaDataServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>meta-data</servlet-name>
+    <url-pattern>/flys/meta-data</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>mainvalues</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.WQInfoServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>mainvalues</servlet-name>
+    <url-pattern>/flys/mainvalues</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>csv</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.CSVExportServiceImpl</servlet-class>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>csv</servlet-name>
+    <url-pattern>/flys/csv</url-pattern>
+  </servlet-mapping>
+  
+  <servlet>
+    <servlet-name>ChartOutputService</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.ChartOutputServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>ChartOutputService</servlet-name>
+    <url-pattern>/flys/chart</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>ExportService</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.ExportServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>ExportService</servlet-name>
+    <url-pattern>/flys/export</url-pattern>
+  </servlet-mapping>
+
+  <!-- Default page to serve -->
+  <welcome-file-list>
+    <welcome-file>FLYS.html</welcome-file>
+  </welcome-file-list>
+
+</web-app>
Binary file flys-client/src/main/webapp/images/back.png has changed
Binary file flys-client/src/main/webapp/images/back_de.png has changed
Binary file flys-client/src/main/webapp/images/back_en.png has changed
Binary file flys-client/src/main/webapp/images/next.png has changed
Binary file flys-client/src/main/webapp/images/next_de.png has changed
Binary file flys-client/src/main/webapp/images/next_en.png has changed
Binary file flys-client/src/main/webapp/images/save.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/test/java/de/intevation/flys/client/FLYSJUnit.gwt.xml	Fri Sep 28 12:14:10 2012 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module>
+  <!-- Inherit our applications main module.                      -->
+  <inherits name='de.intevation.flys.client.FLYS'/>
+
+  <!-- Specify the path to any remote services.                   -->
+  <!--
+  <servlet path="/flys/greet" class="de.intevation.flys.client.server.GreetingServiceImpl" />
+  -->
+
+</module>

http://dive4elements.wald.intevation.org