changeset 3971:5a8e05155fbd

dummy merge for repo head
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:15:40 +0200
parents 3cda41b5eb23 (diff) cb376f48dd37 (current diff)
children 0da10f22bbfd
files flys-client/src/main/java/de/intevation/flys/client/server/BaseServlet.java
diffstat 523 files changed, 35721 insertions(+), 7521 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/ChangeLog	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,2898 @@
+2012-09-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java:
+	  Also add the artifact name to the artifact description.
+
+2012-09-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* doc/conf/conf.xml,
+	  src/main/java/de/intevation/flys/artifacts/GaugeDischargeCurveArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/AbstractStaticStateArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/model/GaugeDischargeCurveFacet.java:
+	  Implement new Artifacts and State for displaying discharge curves at a
+	  gauge.
+
+2012-09-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/StaticState.java:
+	  Make addOuput public. Allow StaticArtifacts to add static outputs to the
+	  state.
+
+2012-09-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java:
+	  Add protected method addFacets to allow child classes to add facets
+	  without accessing the member variable.
+
+2012-09-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/meta-data.xml: Added 'info' column to the dem section of the
+	  datacage.
+
+2012-09-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Work on issue724 (i18n in minfo).
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  i18n strings.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java:
+	  Whitespace-cosmetics.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FlowVelocityAccess.java:
+	  Doc.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Work on issue724 (i18n in minfo).
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  i18n strings.
+
+	* src/main/java/de/intevation/flys/exports/MiddleBedHeightGenerator.java:
+	  Fix typo.
+
+2012-09-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java:
+	  Removed invalid entries of the SQL projection.
+
+2012-09-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java,
+	  Added more data fields from SedDB to calculate the fraction parts.
+
+	  src/main/java/de/intevation/flys/artifacts/model/sq/Measurement.java:
+	  Have now previous and next Measurement attached.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix part of issue871 (selected flow-veloc- parameter shown wrong).
+
+	* src/main/java/de/intevation/flys/artifacts/states/DischargeState.java:
+	  Fix conditional.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue863 (gaps in middle height bed data).
+
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java:
+	  Handle missing data.
+
+2012-09-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/wsplgen/FacetCreator.java: Set
+	  missing 'originalExtent' attribute of the WSPLGEN layer.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Towards fix issue863 (gaps in middle height bed data).
+
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightData.java
+	  (addAll): Do not expose single add*-Methods, instead always add a full
+	  set of data.
+	  Added new isEmpty-data and query it before exporting data as
+	  double[][] to e.g. ChartGenerator.
+	  
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java:
+	  Do not use single add()*-Methods, instead call new addAll method.
+	  Find out whether a gap-value is present.
+	  
+	* src/main/java/de/intevation/flys/exports/MiddleBedHeightGenerator.java:
+	  Prevent skipping of NaNs (gaps).
+
+2012-09-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/map/WMSLayerFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSDBArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/RiverAxisArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSFloodplainArtifact.java:
+	  Removed trailing whitespace.
+
+2012-09-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Measurements.java
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Measurement.java:
+	  Add more symbols.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java:
+	  Adjust symbols.
+
+2012-09-26	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java:
+	Change createOutputModes method to be private. It is not used in a child
+	class.
+
+2012-09-26	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/WaterlevelArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java:
+	  Mark FLYSArtifact data member as private and add setter method.
+
+2012-09-26	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml:
+	  Enable line labels for Delta W/t sector average lines (#896).
+
+2012-09-26  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/mapserver/db_layer.vm: Set initial projection of the database
+	  to "epsg:31467".
+
+	* doc/conf/mapserver/mapfile.vm: Set initial projection of the database to
+	  "epsg:31467". Set the max extent to the extent of the river Saar.
+
+	    TODO: Set the max extent to the extent of germany!
+
+	* src/main/java/de/intevation/flys/artifacts/WMSQPSArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSKmArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSHydrBoundaryArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSFixpointsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSFloodmapsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSHwsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSCatchmentArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSHydrBoundaryPolyArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSBuildingsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSGaugeLocationArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSDBArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/RiverAxisArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/MapArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSLineArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSFloodplainArtifact.java:
+	  Added a parameter "reproject" to the getExtent() method. If reproject is
+	  set, the method should return the extent of the layer in the projection
+	  that is specified for the relevant river in the configuration.
+	  Otherwise, this method should return the extent in the projection that
+	  is used by the database.
+
+	* src/main/java/de/intevation/flys/artifacts/model/map/WMSLayerFacet.java:
+	  Added new attributes and methods for the original extent of a layer. The
+	  original extent is used in the XML document that is generated by
+	  toXML().
+
+	* src/main/java/de/intevation/flys/exports/MapGenerator.java: Use the
+	  getOriginalExtent() method of WMSLayerFacet to determine the max extent
+	  for the map (maps should be in the river projection specified in the
+	  configuration).
+
+2012-09-26	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml,
+	  doc/conf/artifacts/manualpoints.xml,
+	  doc/conf/themes.xml,
+	  src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java,
+	  src/main/java/de/intevation/flys/artifacts/FixationArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java,
+	  src/main/java/de/intevation/flys/artifacts/states/ManualPointsSingleState.java:
+	  Rename fix_derivate facet to enable manual points in the derived curve chart.
+
+2012-09-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/manualpoints.xml: Re-enable manualpoints
+	  compatibility.
+
+2012-09-24	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Fix for #825 ?
+
+2012-09-24  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadOverview.java:
+	  Fixed SQL statement. Exclude data where km is null.
+
+2012-09-24	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java:
+	  Fixing analysis longitudinal section chart has now initially
+	  deactivated A1/B facets. W/Q and W(t) has activated facets. (#874)
+
+2012-09-24	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Remove info-url from gauge and river in the response and add official
+	  number to the river.
+
+2012-09-23	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/default-themes.xml,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  W(Q) chart: q sectors are now black and labeled by default (#875).
+
+2012-09-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeInfoService.java:
+	  Cosmetics.
+
+2012-09-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java:
+	  Removed trailing whitespace.
+
+2012-09-23	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Themes and i18n of Delta W/t's A1/B facets (#876).
+
+2012-09-23	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml,
+	  doc/conf/themes.xml,
+	  doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml,
+	  src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java,
+	  src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Add reference period facet to delta W/t chart (#877).
+
+2012-09-22	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Longitudinal section chart does now respect the bounds of the drawn
+	  areas, so that no clipping occurs (#878).
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  i18n corrections.
+
+2012-09-22	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDerivedCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java:
+	  Cosmetics, doc.
+
+2012-09-22	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java:
+	  Prevent ArrayIndexOutOfBounds.
+
+2012-09-22	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Document issue880 (extrapolation of wkms).
+
+	* src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java:
+	  Do not extrapolate, mention further issues with the code.
+
+2012-09-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java:
+	  Removed trailing whitespace.
+
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings for bedheight difference charts.
+
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* doc/conf/themes.xml,
+	  doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml:
+	  Added themes for bedheight difference charts.
+
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* doc/conf/meta-data.xml:
+	  Add river annotations to bedheight difference charts.
+
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDiffEpochInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDiffYearInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java:
+	  New. Chart generators for bedheight diff calculation charts.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java:
+	  Add facets to generate outputs.
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java:
+	  Extract calculation relevant data.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java:
+	  Updated result set data fields.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java:
+	  Updated the bedheight difference calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Added new facet types.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearFacet.java:
+	  New facets for bedheight differences.
+
+	* doc/conf/conf.xml:
+	  Added ouput generators.
+
+	* doc/conf/artifacts/minfo.xml:
+	  Added facets to outputmodes.
+
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeight.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightSingle.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightEpoch.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFactory.java:
+	  Updated data fields to fit the needs of bedheight difference calculation.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Return also the gauge official number in a service response.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Use Gauge and River fetchInfoURL instead of getInfoURL until the URLs are
+	  fetched from the db.
+
+2012-09-21	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue887 (HYKs in New Chart).
+
+	* src/main/java/de/intevation/flys/artifacts/HYKArtifact.java:
+	  Lower the Casting requirement to FLYSArtifact instead of
+	  WINFOArtifact.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Return also the gauge and river info-url in a service response.
+
+2012-09-20	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue886 (do not show waterline if out of range).
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
+	  Do not extrapolate waterlines.
+
+2012-09-21	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Better Partial issue880 (diverse DC).
+
+	* doc/conf/meta-data.xml: Remove double entry for annotations in
+	  longitudinal section case but keep recommending it.
+
+2012-09-20	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Partial issue880 (diverse DC).
+
+	* doc/conf/meta-data.xml: Remove double entry for annotations in
+	  longitudinal section case.
+
+2012-09-20	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml,
+	  src/main/java/de/intevation/flys/utils/ThemeUtil.java,
+	  src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java,
+	  src/main/java/de/intevation/flys/jfree/StyledDomainMarker.java:
+	  Theme area transparency fixed for longitudinal section chart (#879).
+
+2012-09-20	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Improvements for manual points in fixation diags.
+
+	* doc/conf/artifacts/fixanalysis.xml: Add LS-manual points.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Add missing ChartTypes.
+
+2012-09-20  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java:
+	  New. Calcuation for bed height differences.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java:
+	  New. Bed height calculation results.
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java:
+	  New. Access object to get bed height difference parameters from artifact.
+
+2012-09-20  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFactory.java:
+	  Create separate objects for bed height epochs and single bed heights.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeight.java:
+	  Added morph. width.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightEpoch.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightSingle.java:
+	  New. Separate classes for bed height epochs and single bed heights.
+
+2012-09-20  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityExporter.java:
+	  Add dates to csv header.
+
+2012-09-20  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n string for bed quality CSV export.
+
+2012-09-20	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml,
+	  doc/conf/artifacts/manualpoints.xml,
+	  src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java,
+	  src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java,
+	  src/main/java/de/intevation/flys/artifacts/states/ManualPointsSingleState.java:
+	  Work on manual points in fix analysis charts (not yet working).
+
+2012-09-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityExporter.java:
+	  Removed superfluous imports.
+
+2012-09-19  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityExporter.java:
+	  New. CSV exporter for bed quality calculation result.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedParametersResult.java:
+	  Added getter with km as parameter.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Added facet for csv export.
+
+	* doc/conf/artifacts/minfo.xml:
+	  Added output mode.
+
+	* doc/conf/conf.xml:
+	  Added export generator.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Return also the station in a service response.
+
+2012-09-18	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FunctionSelect.java:
+	  Cosmetics.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java:
+	  A and B facets of fix analysis are now deactivated by default (#717).
+
+2012-09-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeCalculation.java:
+	  Extract parameters needed for calculation from access.
+
+	* src/main/java/de/intevation/flys/utils/DoubleUtil.java(isValid):
+	  Added method to check if 2d double array is valid.
+
+2012-09-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java,
+	  src/main/java/de/intevation/flys/artifacts/model/AnnotationsFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
+	  Use generics aware Collections.emptyList().
+
+2012-09-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java,
+	  src/main/java/de/intevation/flys/exports/OutputHelper.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/themes/ThemeFactory.java,
+	  src/main/java/de/intevation/flys/themes/ThemeMapping.java,
+	  src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java:
+	  The usual whitespace and import cleanups.
+
+2012-09-18  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java:
+	  Avoid loading empty data sets.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java:
+	  Load bedload data sets...
+
+2012-09-18  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/CharDiameter.java:
+	  Removed incorrect characteristic diameter.
+
+2012-09-18	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/default-themes.xml:
+	  Update point themes of fixing W/Q chart to show point descriptions
+	  per default (#685).
+
+2012-09-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	i18n for area label (fix issue487).
+
+	* src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java:
+	  Get internationalized label and numberformat, pass it to renderer,
+	  where its used.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: Area label translations.
+
+2012-09-18	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java,
+	  src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Add robustness checks to prevent NPEs (#859).
+
+2012-09-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Brought showarea-theme setting back (fix issue865).
+
+	* doc/conf/default-themes.xml, doc/conf/second-themes.xml:
+	  Define showarea theme prop where its needed.
+
+2012-09-17  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java:
+	  Added setter for date range.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java
+	  Set correct date range for result.
+
+2012-09-17  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Refactor MINFO bed quality resultsets and facets.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedLoadBedQualityResult.java,
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedBedQualityResult.java:
+	  Removed.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java:
+	  Container wrapping the single calculation results.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityDiameterResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedParametersResult.java:
+	  New. Results containing calculated average diameter, porosity and density.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedPorosityFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDensityFacet.java:
+	  Facets now return the concrete datatype using the facet index.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Create a facet for each resultset.
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java:
+	  Use the classes containing the results.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java:
+	  Use new classes for results and calculate porosity and density once
+	  each period.
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged RELEASE 2.9.1
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: Added still missing
+	  translations for state.
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: Added missing translations
+	  for state to select soundings.
+
+	* src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java:
+	  Added more debug output to find out how many single and epochs where
+	  found.
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml: Defined initial colors.
+
+	* src/main/java/de/intevation/flys/exports/OutputHelper.java,
+	  src/main/java/de/intevation/flys/themes/ThemeFactory.java,
+	  src/main/java/de/intevation/flys/themes/ThemeMapping.java: Added more
+	  debug output to understand why theme mappings don't match to facets.
+
+2012-09-17  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java:
+	  Extract characteristic diameter only if the user selected a diameter.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java:
+	  Calculate for selected diameter only.
+
+2012-09-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadOverview.java,
+	  src/main/java/de/intevation/flys/artifacts/model/SQOverview.java,
+	  src/main/java/de/intevation/flys/exports/DurationCurveExporter.java,
+	  src/main/java/de/intevation/flys/exports/fixings/ParametersExporter.java:
+	  Fixed wrong assigned loggers.
+
+2012-09-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java:
+	  Please _DO NOT_ use FLYSUtils in new code based on Access*!
+	  Now the river name is fetch via access.getRiver().
+
+	* src/main/java/de/intevation/flys/artifacts/access/RiverAccess.java:
+	  New. Almost all calculations need accessing the river name.
+
+	* src/main/java/de/intevation/flys/artifacts/access/SQRelationAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/access/FixAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/access/FlowVelocityAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/access/ExtremeAccess.java:
+	  Now extend RiverAccess.
+
+2012-09-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/ExtremeAccess.java:
+	  Implemented the access methods needed for
+	  "Auslagerung extremer Wasserspiegellagen".
+
+	* src/main/java/de/intevation/flys/artifacts/model/Segment.java:
+	  Move segment parsing to DoubleUtil to be usable with more data types.
+	  The wire protocol should be the same for:
+	  - "WINFO: W fuer ungleichwertige Abfluesse",
+	  - "WINFO: Auslagerung extremer Wasserspiegellagen"
+	  - "Fixierungsanalyse: Auslagerung von Wasserspiegellagen"
+
+	* src/main/java/de/intevation/flys/utils/DoubleUtil.java:
+	  Now contains the the code to parse segments. Found segments
+	  are propagated back with a callback.
+
+	* src/main/java/de/intevation/flys/artifacts/model/RangeWithValues.java:
+	  Added toString() method.
+
+2012-09-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	More infrastructure stuff for the "Auslagerung extremer Wasserspiegellagen".
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeCalculation.java:
+	  New. Stub for "Auslagerung extremer Wasserspiegellagen" calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeResult.java:
+	  New. Stub for the cacheable results of the calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/states/extreme/ExtremeCompute.java:
+	  New. Stub compute state for the calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/access/ExtremeAccess.java:
+	  New. Sub access to the artifact to extract the relevant data.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  A little code reordering to keep related stuff together more closely.
+
+2012-09-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/BedHeightsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/model/AreaFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/QSectorArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/FixationArtifact.java:
+	  Removed some superfluous implementations of FacetTypes.
+	  TODO: FacetTypes should be broken into smaller pieces.
+	  ATM a lof of class implement it and share a lot of unnecessary
+	  stuff.
+
+2012-09-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java,
+	  src/main/java/de/intevation/flys/artifacts/geom/VectorUtils.java:
+	  Deleted. Some nice code from the early days of the cross sections
+	  but its unused nowadays.
+
+2012-09-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedBedQualityResult.java:
+	  Removed superfluous imports.
+
+	* src/main/java/de/intevation/flys/jfree/JFreeUtil.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedLoadBedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDensityFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedPorosityFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedQualityInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java:
+	  Removed trailing whitespace.
+
+2012-09-15	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/resources/Resources.java,
+	  src/main/java/de/intevation/flys/utils/Formatter.java,
+	  src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java:
+	  i18n messages are now formatted with correct (client) locale, not
+	  server VM locale (#852)..
+
+2012-09-15	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml,
+	  doc/conf/artifacts/manualpoints.xml,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java:
+	  Try to add support for ManualPoints in fixing charts (not working yet).  
+
+2012-09-14  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java:
+	  Fixed SQL-statement.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurements.java:
+	  Added getter for all kms.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java:
+	  Implemented the bed quality calculation. There are still some fixes to do,
+	  e.g. extract a single result object for porosity and density.
+
+2012-09-14  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java:
+	  Getter for characteristic diameter.
+
+2012-09-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Create i18n facet descriptions.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: New i18n strings for facets
+	  in bed quality calculation.
+
+2012-09-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml: Splitted facets for diameter of bed into
+	  two facets: diameter for sublayer and toplayer.
+
+	* doc/conf/themes.xml,
+	  doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml: Splitted themes for diameter of bed into
+	  two themes.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Splitted facets for diameter of bed into two facets.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java:
+	  New method to retrieve the diameter data.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedBedQualityResult.java:
+	  New methods to retrieve the porosity, density and diameter data.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Create two facets for bed diameter instead of a single one.
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java:
+	  Insert data supported by facets into chart.
+
+2012-09-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/jfree/JFreeUtil.java: Added function to
+	  generate a randomized line.
+
+2012-09-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/themes.xml: Defined new mappings for the six bed quality
+	  facets.
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml: Added themes for new mappings in
+	  themes.xml. The themes in second-themes are the same as in
+	  default-themss.
+
+2012-09-14  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedBedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedLoadBedQualityResult.java:
+	  Updated bed quality result objects.
+
+2012-09-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml: Splitted porosity and density facets into
+	  two facets: a toplayer and a sublayer facet for each.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java: Added
+	  the new facets for toplayer and sublayer for porosity and density.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Create Facets based on the calculation results.
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java:
+	  Use concrete result types in doXXXOut().
+
+2012-09-13	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml,
+	  doc/conf/themes.xml,
+	  src/main/java/de/intevation/flys/artifacts/ManualPointsArtifact.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDerivedCurveGenerator.java:
+	  Work on ManualPoints integration in fix analysis charts (wip).
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Fix missing import.
+
+2012-09-13  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java:
+	  Added getter for calculation parameters.
+
+	* src/main/java/de/intevation/flys/artifacts/model/BedQualityCalculation.java:
+	  Removed. Moved to package de.intevation.flys.artifacts.model.minfo.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedLoadBedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedBedQualityResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java:
+	  New. Calculation results and some more calculation stub.
+
+2012-09-13  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml,
+	  src/main/java/de/intevation/flys/artifacts/access/FlowVelocityAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/states/DischargeState.java,
+	  src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: Renamed MINFO parameter
+	  'main.channel' -> 'main_channel' and 'total.channel' -> 'total_channel'.
+
+2012-09-13  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurement.java:
+	  Added depth parameter to bed quality data.
+
+2012-09-13  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/conf.xml: Registered new OutGenerators BedQualityGenerator and
+	  BedQualityInfoGenerator.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedPorosityFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDensityFacet.java:
+	  New Facets for serving data for bed quality exports/charts.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Add some dummy Facets to force chart creation.
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedQualityInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java:
+	  New OutGenerators for bed quality charts.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: New I18N strings for bed
+	  quality charts.
+
+2012-09-13  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java:
+	  The factory can load bedload and bed data from seddb now.
+
+2012-09-13  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Objects and factory for minfo bedquality calculation data.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurements.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurement.java:
+	  New. Data objects and factory for minfo bed quality calculation.
+
+2012-09-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Added missing images for datacage config manual doc.
+
+	* doc/datacage-config-manual/figures/bsh_logo.png,
+	  doc/datacage-config-manual/figures/intevation-logo.eps,
+	  doc/datacage-config-manual/figures/intevation-logo.pdf:
+	  Logos for DC conf doc.
+
+2012-09-13	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Add also min and max q values to the river info.
+
+2012-09-12	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/BedloadKMChartService.java,
+	  src/main/java/de/intevation/flys/artifacts/services/BedKMChartService.java:
+	  Removed trailing whitespace.
+
+2012-09-12  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/BedloadKMChartService.java,
+	  src/main/java/de/intevation/flys/artifacts/services/BedKMChartService.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedOverview.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadOverview.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedOverviewFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadOverviewFactory.java:
+	  New. Services, data structures and factories for overview charts in minfo
+	  bed quality calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityPeriodsSelect.java:
+	  New. State for period input in minfo bed quality that displays the overview
+	  charts.
+
+	* doc/conf/artifacts/minfo.xml:
+	  Added states and transitions for minfo bed quality calculation.
+
+	* doc/conf/conf.xml:
+	  Added services.
+
+2012-09-12	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/BedQualityCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java,
+	  src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Removed trailing whitespace.
+
+2012-09-12  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml: Defined facets for bed quality chart.
+
+	* src/main/java/de/intevation/flys/artifacts/model/BedQualityCalculation.java:
+	  Calculation stub for bed quality.
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java:
+	  Access stub for bed quality data.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java: Added
+	  facets defined in minfo.xml.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java:
+	  Override computeAdvance; no calculation and facet creation takes place
+	  yet.
+
+2012-09-11	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Made AEo and datum attributes NPE proof.
+
+2012-09-11	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Use getGaugeValue method also for aeo and datum. Also add some javadoc for
+	  the getGaugeValue method.
+
+2012-09-11	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Fix for line text annotations in Delta W(t) charts (#837).
+
+2012-09-10	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/GaugeTimerangeState.java:
+	  Add additional check to prevent NPE (fix for #844)
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/RangeWithValues.java:
+	  Extends Range now.
+
+	* src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java:
+	  Adjusted to use slightly different method names of Range.
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Range.java:
+	  Added disjoint method.
+
+	* src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java:
+	  Find a list of segments intersecting a given range.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java:
+	  Generate a list of ranges needed for the input of Qs
+	  in the "Auslagerung extremer Wasserspiegellagen.".
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java:
+	  Added type safety.
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* pom.xml: Java 1.5 -> 1.6
+
+2012-09-10	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml:
+	  Remove unnecessary attributes for fixation derived curve (#836).
+
+2012-09-10	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* doc/conf/conf.xml,
+	  src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java:
+	  Add new artifact service for the gauge overview
+
+2012-09-09	Christian Lins 	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml,
+	  doc/conf/virtual-themes.xml,
+	  src/main/java/de/intevation/flys/utils/ThemeUtil.java,
+	  src/main/java/de/intevation/flys/jfree/StyledDomainMarker.java:
+	  Theme transparency attribute support (part of #840).
+
+2012-09-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java:
+	  Store Ws and Qs in double arrays instead of WQ objects (as
+	  they are return from WstValueTable.interpolateTabular()).
+	  This simplifies the code and should be more memory effective.
+
+2012-09-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/math/Linear.java:
+	  Added a vectorwise weighting.
+
+	  src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java:
+	  Added methods to interpolate tabulated values only.
+	  Need in "Auslagerung extremer Wasserspiegellagen".
+
+2012-09-09	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml,
+	  doc/conf/virtual-themes.xml:
+	  Updating themes for issue #840 (wip).
+
+2012-09-09	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/second-themes.xml:
+	  Modify every theme to differ from default theme (#835).
+
+	* src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java:
+	  Use gauge.getMainValues() instead of gauge.fetchMainValues() which fixes
+	  a compiling issue on my setup.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Some models for representing results for the upcoming
+	"Auslagerung extremer Wasserspiegellagen". Work im progress.
+
+	* src/main/java/de/intevation/flys/artifacts/math/NaNFunction.java:
+	  New. Function always return NaNs.
+
+	* src/main/java/de/intevation/flys/artifacts/math/UnivariateRealFunctionFunction.java:
+	  New. Adapter to bridge between our Functions and UnivariateRealFunctions
+	  of Apache Common Math.
+
+	* src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java:
+	  New. Part of the result model of "Auslagerung extremer Wasserspiegellagen".
+	  Its a function for a given km that uses a spline interpolation
+	  for the tabulated Q range (which is effectively the same as the
+	  calculated discharge curve for this km) and an extrapolated
+	  function beyond the tabulated values.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/DefaultState.java,
+	  src/main/java/de/intevation/flys/themes/DefaultTheme.java:
+	  More iterator code simplification.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/themes/DefaultThemeField.java:
+	  Simplified code.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java:
+	  Simplified code.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisResult.java:
+	  Improved robustness and performance.
+	  Only expose date events as Collections not TreeSets.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/QW.java:
+	  New. a pure model for discharge and waterlevel. No extras.
+
+	  Makes reuse in upcoming "Auslagerung extremer Wasserspiegellagen"
+	  a lot easier.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/QW.java:
+	  Removed.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/QWI.java:
+	  Re-inserted here. Extends the new QW and adds all the extra bells
+	  and whistles needed in the fixings analysis.
+
+	* src/main/java/de/intevation/flys/artifacts/services/FixingsKMChartService.java,
+	  src/main/java/de/intevation/flys/artifacts/services/QWSeriesCollection.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/Fitting.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixOutlierFacet.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Adjusted QW to QWI.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/MainValuesFactory.java;
+	  Removed because code is found in backend already.
+
+	* src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java:
+	  Simplified. Please _DO_NOT_ use NullPointerExceptions for regular flow control!
+	  This hides unintended errors.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Removed code duplication.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	   Removed trailing whitespace.
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/CharDiameter.java:
+	  Removed superfluous imports.
+
+2012-09-08	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/datacage/DatacageBackendListener.java,
+	  src/main/java/de/intevation/flys/artifacts/datacage/Datacage.java,
+	  src/main/java/de/intevation/flys/artifacts/ChartArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java,
+	  src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixATExport.java,
+	  src/main/java/de/intevation/flys/exports/XYChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/TypeSection.java,
+	  src/main/java/de/intevation/flys/jfree/DoubleBounds.java,
+	  src/main/java/de/intevation/flys/jfree/Bounds.java:
+	  Cosmetics, docs.
+
+2012-09-07  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml:
+	  Add data fields for characteristic bed and bedload diameter.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/CharDiameter.java:
+	  Use parametermatrix as UI provider and set the correct data.
+
+	* src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java,
+	  src/main/java/de/intevation/flys/artifacts/states/MultiStringArrayState.java:
+	  Updated method parameter.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings.
+
+2012-09-07  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 791.
+
+	* src/main/java/de/intevation/flys/artifacts/states/EnterMultipleLocationsState.java:
+	  Add start km to data to compare reference and target km in next state.
+
+2012-09-07  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged RELEASE 2.9
+
+2012-09-07	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/model/MainValuesFactory.java:
+	  Removed superfluous imports.
+
+2012-09-07	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/MainValuesFactory.java:
+	  Removed the deprecated method.
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
+	  Call the new Gauge model method fetchDurationCurveData().
+
+2012-09-06	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/MainValuesFactory.java:
+	  Mark getDurationCurveData as deprecated. The instance method of Gauge with
+	  the same name should be used instead.
+
+2012-09-06	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Revert accidentally committed experiment.
+
+2012-09-06	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Comments, changed order of columns as requested in issue825.
+
+2012-09-05	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java:
+	  Only goto down to Q = 0.0001 to circumvent some numerial issues
+	  with steep functions around zero.
+
+2012-09-05	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java:
+	  Increase Q max about 5% (as it should be).
+
+2012-09-04	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Fix for issue687
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java:
+	  Rewrote AT export to fix it.
+
+2012-09-03	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix for issue820.
+
+	* src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java:
+	  Changed label for middle height/depth.
+
+2012-09-03	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/ChartGenerator.java:
+	  Default horizontal and vertical placement of logo to "center" and
+	  "top" instead of "none."
+
+2012-09-03	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Improved comment regarding image placement.
+
+2012-09-03  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	  Fixed URLs for logos.
+
+2012-09-02	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue744 (wrong ranges for w/q input).
+
+	* src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java:
+	  Do not add items for gauges that do not intersect with given range.
+
+2012-09-01	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue829 (wrong fixation names).
+
+	* src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java:
+	  Fix check, column indices start with 0.
+
+2012-09-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeight.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java,
+	  src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/XYChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChoiceStringAttribute.java:
+	  Removed trailing whitespace.
+
+2012-08-31	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	  Fix cast.
+
+2012-08-31  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings for minfo bed quality parameters.
+
+2012-08-31	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/ModuleService.java,
+	  src/main/java/de/intevation/flys/artifacts/model/Module.java,
+	  src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java,
+	  src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java,
+	  src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties,
+	  doc/conf/conf.xml:
+	  Add a module service. It's now possible to configure the modules which are
+	  available for a client. With the selected attribute it is possible to give
+	  a hint for the client which module should be pre selected by default.
+
+2012-08-31  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/CharDiameter.java:
+	  New. States for minfo bed quality calculation.
+
+	* doc/conf/artifacts/minfo.xml:
+	  Added states and transitions for minfo bed quality calculation.
+
+2012-08-31  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/LocationDistanceSelect.java:
+	  Refactored state to use FLYSArtifact instead of WINFOArtifact.
+
+2012-08-31	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue817 (double datacage entries).
+
+	* doc/conf/meta-data.xml: removed double entries.
+
+2012-08-30	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	issue729, default line labels for waterlines in cross sections.
+
+	* doc/conf/default-themes.xml: Default line label and level label
+	  to true for lines in crossections..
+
+2012-08-30	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	issue814, line labels do not follow zoom.
+
+	* src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java:
+	  Move line label into visible area if otherwise outside.
+
+2012-08-30	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	issue695, show waterlevel as line label.
+
+	* src/main/java/de/intevation/flys/utils/ThemeUtil.java:
+	  Fix path to showlevel style property.
+
+2012-08-30	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	  Mention how/where to change predefined logos in comment.
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Mention how/where to change predefined logos in comment,
+	  Use resource for images.
+
+	* src/main/resources/images/bfg_logo.gif,
+	  src/main/resources/images/intevation.png:
+	  Added sample logos of intevation and bfg.
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	  Copy and slightly modified XYChartGenerators logo mechanism.
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  (getLeftX, getRightX): New and overridden to deal with inverted axis
+	  for logo placement in longitudinalsection charts.
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Use RectangleAnchor to set anchor of logo.
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java:
+	  Add Logo settings to CrossSection ChartSettings.
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Split logo-placement property in two, one for horizontal, one for
+	vertical placement.
+
+	* src/main/java/de/intevation/flys/exports/ChartSettings.java,
+	  src/main/java/de/intevation/flys/exports/ChartSection.java:
+	  Accessors for split property.
+        
+	* src/main/java/de/intevation/flys/exports/ChartGenerator.java
+	  (logoHPlace,logoVPlace,logoPlace): Use split properties for vertical
+	                                     and horizontal placement of logo.
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Use split properties, respect in placement.
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Sloppy logo placement property implementation.
+
+	* src/main/java/de/intevation/flys/exports/ChartSettings.java:
+	  Parse and set logo placement property value.
+	  
+	* src/main/java/de/intevation/flys/exports/ChartSection.java:
+	  Accessors for Logo placement property.
+	  
+	* src/main/java/de/intevation/flys/exports/ChartGenerator.java
+	  (logoPlace): New, get logo placement property value.
+	  (showLogo): Default to "none".
+	  
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Sloppy interpretation of the logo placement property.
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  (addLogo): New, add an image annotation to plot, very stubby,
+	             use hard-coded paths for now.
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Preparations for logo-inclusion in charts.
+
+	* src/main/java/de/intevation/flys/exports/ChoiceStringAttribute.java:
+	  New string attribute type to trigger different UI (selectboxes)
+	  in client.
+	  
+	* src/main/java/de/intevation/flys/exports/TypeSection.java
+	  (setChoiceStringValue): Create new ChoiceStringAttribute.
+	  
+	  
+	* src/main/java/de/intevation/flys/exports/ChartSection.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartSettings.java:
+	  Accessors to show logo-property.
+
+2012-08-28  Raimund Renkert <raimund.renkert@intevation.de>
+
+	MINFO: Implemented UI and facet/artifact stack for bed height differences.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeight.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/model/StaticBedHeightCacheKey.java:
+	  New. Facet and data object incl. factory for bed heights.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/YearEpochSelect.java,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/DifferenceSelect.java,
+	  src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java,
+	  src/main/java/de/intevation/flys/artifacts/BedHeightsArtifact.java:
+	  New. States for difference calculation mode and new artifact for difference
+	  selection.
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedHeightAccess.java:
+	  Added getter for time (year or epoch).
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Added new facet type.
+
+	* doc/conf/meta-data.xml:
+	  Datacage config for minfo bed heights.
+
+	* doc/conf/artifacts/minfo.xml:
+	  Added transitions and states for minfo difference calculation.
+
+	* doc/conf/conf.xml:
+	  Added artifact factory.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings.
+
+2012-08-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartSettings.java:
+	  (setDisplayGird, setDisplayGrid): Fixed typos.
+
+2012-08-23  Raimund Renkert <raimund.renkert@intevation.de>
+
+	FixA: Changed sector average form point to line in delta W(t) chart.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Add data points for sector average and changed time unit for analysis period
+	  from month to day.
+
+	* doc/conf/default-themes.xml:
+	  Changed theme for sector average to color line.
+
+2012-08-23  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 716. FixA: Spilt reference and analysis period themes into one theme for each event.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java:
+	  Create a facet for each event and use new facet for sector average in
+	  longitudinal section chart.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixReferenceEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAnalysisFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalReferenceFacet.java:
+	  The facets now return data for a single event.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAvSectorFacet.java:
+	  New. This facet returns an analysis period containing the calculated
+	  average.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisResult.java:
+	  Added methods to get the dates for all reference and analysis period events.
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	  Fixed range combining.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java:
+	  Adjusted generators to use the data returned by the facets.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings.
+
+2012-08-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Using trove to map int->int instead of bloated generics.
+
+2012-08-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Prevent another NPE. Removed dead code.
+
+2012-08-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Each analysis period has its own index scheme now.
+
+2012-08-22	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Fix for NullPointerException.
+
+2012-08-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Made indices of analysis periods QWs zero based.
+
+2012-08-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/QW.java:
+	  Store index, too.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java:
+	  Adjusted to keep constructors in sync.
+
+	* src/main/java/de/intevation/flys/artifacts/services/FixingsKMChartService.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Set QD index to the values of the column cache columns.
+
+2012-08-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Use the column cache to establish a consistent index scheme.
+	TODO: Store the index values in the created QWDs.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  doFitting() fetches the columns from column cache, too.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Reuse same column cache from fitting to have the same index scheme.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	  Adjusted to use the column cache.
+
+2012-08-22	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/HYKFacet.java,
+	  src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java:
+	  Fix NullPointerExceptions in cross section diagrams that occurred when
+	  no HYKs are available for the selected kms.
+
+	* src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_de.properties:
+	  Typo, see issue #806
+
+2012-08-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATExport.java:
+	  Removed superfluous import. s/Double.valueOf/Double.parseDouble/.
+
+2012-08-17  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATExport.java:
+	  Removed debug outputs.
+
+2012-08-17  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATExport.java:
+	  New. Exporter for FixAnaylsis AT files.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java:
+	  Add facet for AT export.
+
+	* doc/conf/conf.xml:
+	  Added out generator for fix AT export.
+
+	* doc/conf/artifacts/fixanalysis.xml:
+	  Added outputmode for AT export.
+
+2012-08-16	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Add more facets to
+	  compat list, removed doubled wq output.
+
+2012-08-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/WaterlevelFacet.java:
+	  Shorten overlong lines. Simplified code.
+
+2012-08-16	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/WaterlevelFacet.java:
+	  Interpolate and reduce WQKms if currentKm found in context.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Handle WQKms in WQOuts.
+
+2012-08-16	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Add longitudinal section
+	  facet type to compatibility list of W/Q diags.
+
+2012-08-16  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FunctionSelect.java:
+	  Added getter for ui provider.
+
+2012-08-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  BasicStroke constructor takes an float as first argument
+	  so there is no need to blow up an 'int' to an Integer
+	  which is auto-unboxed to int which is implicitly cast to float.
+
+2012-08-15	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: Do not hard-recommend gauge-dis. for fixwq.
+
+2012-08-15	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/GaugeDischargeArtifact.java:
+	  Fail more gracefully.
+
+2012-08-14	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: More former calculations in fixA (dwt) DC.
+
+2012-08-14	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: More former calculations in fixA DC.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Add discharge curve facet to
+	  compat. list.
+
+	* doc/conf/meta-data.xml: Show discharge curves for FixA WQ DC.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Handle discharge curve data.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Add more facets to compat. list.
+
+	* doc/conf/meta-data.xml: Show more additional data in FixA w/q-diag.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Handle new, annotation-type facets.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Added wqkms facets to comp. list.
+
+	* doc/conf/meta-data.xml: Add wq-basedata and other stubs to fixA dc.
+
+	* src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java
+	  (getWQAtKm): Adjusted behaviour such that passed km can be
+	  respected.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Handle WQFacets.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WQFacet.java:
+	  Pass contexts current_km if available.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Added deltawt-out.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: Show former calculations in FixA WQ-DC.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: Show more former calculations in DeltaWTs
+	  and fix query (and/or/() precedences).
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: Show more former calculations in fixA LS.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/conf.xml: Renamed qsector(s) factory.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: Load annotations for fixA long.sections.
+	  Add stubs for "old calculations"-dc-conf for various FixA outs.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java:
+	  Handle annotation outs.
+
+2012-08-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/themes.xml, doc/conf/default-themes.xml:
+	  Added theme fields for qsectors label.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Add markers for the qsectors.
+
+2012-08-10	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/themes.xml, doc/conf/default-themes.xml:
+	  Fix some typos, correct defaults and add mapping for qsector-theme.
+
+	* src/main/java/de/intevation/flys/artifacts/services/FixingsKMChartService.java:
+	  Cosmetics.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Add accidentally omitted change, stub for style-handling.
+
+2012-08-10	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/QSectorFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/states/QSectorSingleState.java,
+	  src/main/java/de/intevation/flys/artifacts/QSectorArtifact.java:
+	  Wording and i18n of qsectors.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Add Markers to plot for qsectors.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  i18n for qsectors.
+
+2012-08-10	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/QSectorSingleState.java:
+	  New, accidentally omitted single state of a qsector-artifact.
+
+2012-08-10	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Add qsectors-facet to
+	  compatibility list.
+
+	* doc/conf/conf.xml: Register qsector artifact and its factory.
+
+	* doc/conf/meta-data.xml: Recommend qsectors in fix w/q settings.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Add qsector facet type.
+
+2012-08-10	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/qsector.xml:
+	  Trivial state model for qsector artifact.
+
+	* src/main/java/de/intevation/flys/artifacts/model/QSectorFacet.java:
+	  Rather trivial facet to get QSectors from QSectorArtifact.
+
+	* src/main/java/de/intevation/flys/artifacts/QSectorArtifact.java:
+	  New QSectorArtifact.
+
+2012-08-09	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/FixingsKMChartService.java,
+	  src/main/java/de/intevation/flys/artifacts/datacage/templating/Builder.java:
+	  Cosmetics.
+
+2012-08-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java,
+	  src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java:
+	  Removed superfluous imports.
+
+2012-08-08	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/meta-data.xml: Set info attribute (will evaluate as tooltip
+	  in GUI.
+
+2012-08-07	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Reflect fact that there can be only one reference station.
+
+2012-08-07	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix issue798.
+
+	* src/main/java/de/intevation/flys/exports/ReferenceCurveGenerator.java:
+	  Set Tick Units dependant on cm/m scale on X axis.
+
+2012-08-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Fix for flys/issue748
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java,
+	  src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java:
+	  Only remove one data point per outlier removal iteration.
+
+2012-07-31	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/math/Outlier.java:
+	  Only evict only one(!) data point as outlier.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/Fitting.java:
+	  Recalculate the function when one point is removed.
+
+2012-07-31	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/math/Outlier.java:
+	  Corrected the formulas of Grubbs' test for outliers.
+	  TODO: Remove only one(!) data point. Currently it removes
+	  more than on point without recalculating the fitting curve.
+	  This leads to too much removed points.
+
+2012-07-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/SQRelation.java:
+	  Setup better initial activity for the facets of the S/Q results.
+
+2012-07-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Use getCurrentKmFromRequest().doubleValue() in i18n formatting.
+
+2012-07-29	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  getCurrentKmFromRequest returns Double(!) not double.
+
+	* src/main/java/de/intevation/flys/utils/ThemeUtil.java:
+	  Use Double.parseDouble() instead od Double.valueOf().
+
+2012-07-29	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/SQRelation.java:
+	  Initially activate/deactivate facets.
+
+2012-07-29	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/collections/AttributeWriter.java,
+	  src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java:
+	  Refactored to use the new Chain-of-responsibility pattern in facet
+	  activation.
+
+2012-07-29	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/GaugeInfoService.java:
+	  Made expensive XMLUtils.toString() debug output conditional.
+
+2012-07-29	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Use the new infrastructure to figure out if a facet should
+	be initially active or not.
+
+	* src/main/java/de/intevation/flys/collections/AttributeWriter.java:
+	  Uses the FacetActivity.Registry to look up the initial acitiviy.
+
+	* src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java:
+	  Do not use sub classing any more.
+
+	* src/main/java/de/intevation/flys/artifacts/WaterlevelArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/ManualPointsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/GaugeDischargeArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/HYKArtifact.java:
+	  Register to FacetActivity.Registry now. TODO: Make it configurable.
+
+2012-07-28	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/themes/ThemeFactory.java,
+	  src/main/java/de/intevation/flys/collections/CollectionAttribute.java,
+	  src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java,
+	  src/main/java/de/intevation/flys/artifacts/AnnotationArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/ChartArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java,
+	  src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/MapArtifact.java:
+	  s/container.size() == 0/container.isEmpty()/
+
+2012-07-28	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java:
+	  Lowered logging output level from info to debug.
+	  Made some more debug outputs conditional.
+
+2012-07-28	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java:
+	  Some code simplifications.
+
+2012-07-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Extented the result data model of the S/Q calculation to
+	store the curve coefficients for each iteration step
+	of the outlier elimination. The starting data set of S/Qs
+	is stored as well.
+
+	TODOs:
+	- Create the new facets as inactive.
+	- Repair the facet to style mapping.
+
+	* doc/conf/themes.xml: Added mappings for new facets.
+
+	* doc/conf/artifacts/minfo.xml: Configured the new facets.
+
+	* src/main/java/de/intevation/flys/exports/sq/SQRelationExporter.java:
+	  Adjusted to new data model.
+
+	* src/main/java/de/intevation/flys/artifacts/states/SQRelation.java:
+	  Generate facets for outlier curves and measurements. Simplified code.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  New facet types for outlier curves and meassurements.
+
+	* src/main/java/de/intevation/flys/artifacts/model/Parameters.java:
+	  New set() method to set an array of values by their names.
+
+	* src/main/java/de/intevation/flys/artifacts/model/Segment.java:
+	  Removed trailing whitespace.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/sq/SQCurveFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/sq/SQMeasurementFacet.java:
+	  Adjusted to new data model. Curves are drawn over the whole length of the
+	  starting S/Q dataset.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierCurveFacet.java:
+	  New. Facet for the curves of the outlier test iterations.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierMeasurementFacet.java
+	  New. Facet for the meassurement data remainind after outlier test iteration.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java:
+	  Now creates the new data model.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java,
+	  src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java:
+	  Refactorted to have more control over the data structures to be generated.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQFractionResult.java:
+	  The new data model to represnt a fraction result. Each outlier test iteration
+	  results in a different iteration object.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings for new facets.
+
+2012-07-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/QWDDateRange.java:
+	  Added method getQWD() to retrieve the QWD property.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Avoid class cast exceptions; a QWDDateRange object is returned by WQ
+	  sector average Facet - not a QWD object. Use new getter method to
+	  retrieve the required data object.
+
+2012-07-27  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged module as '2.8.1'.
+
+2012-07-26	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/QWDDateRange.java:
+	  New class. QWD and a DateRange.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAvSectorFacet.java:
+	  Produce QWDDateRanges in state, consume in generator.
+
+2012-07-26  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Registered new Output
+	  'fix_vollmer_wq_curve'.
+
+	* doc/conf/conf.xml: Registered new FixWQCurveGenerator for
+	  'fix_vollmer_wq_curve'.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: Added new names for Facets
+	  used in 'fix_vollmer_wq_curve' Output.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixWQCurveFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixReferenceEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixOutlierFacet.java:
+	  Make use of FitResult (parent of FixAnalysisResult) which is enough for
+	  these Facets instead of casting the calculation result to
+	  FixAnalysisResult.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixAnalysisAccess.java:
+	  Fixed potential NullpointerException.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Create new Facets for WQ curve, fix events and outliers.
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Add subtitles only if the required data (date period and referenence
+	  period) are existing. Otherwise do not add a subtitle.
+
+2012-07-26	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Adjusted i18n strings (vollmer).
+
+2012-07-26	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/virtual-themes.xml,
+	  src/main/java/de/intevation/flys/utils/ThemeUtil.java,
+	  src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/themes/ThemeAccess.java,
+	  src/main/java/de/intevation/flys/themes/TextStyle.java,
+	  src/main/java/de/intevation/flys/themes/LineStyle.java,
+	  src/main/java/de/intevation/flys/themes/ThemeFactory.java,
+	  src/main/java/de/intevation/flys/themes/PointStyle.java,
+	  src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java,
+	  src/main/java/de/intevation/flys/jfree/XYStyle.java,
+	  src/main/java/de/intevation/flys/jfree/StyledDomainMarker.java:
+	  Line labels and point labels share same styles and code.
+	  Point labels can have a background color.
+
+2012-07-26	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Adjusted i18n strings (vollmer).
+
+2012-07-26  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/fixanalysis.xml: Registered new Output
+	  'fix_waterlevel_export' for FixRealizingCompute State.
+
+	* doc/conf/conf.xml: Registered new WaterlevelExport Generator for
+	  'fix_waterlevel_export'.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Create proper CSV, WST and PDF Facets with hash and State id.
+
+	* src/main/java/de/intevation/flys/exports/WaterlevelExporter.java: Made
+	  WaterlevelExporter support FixRealizingResult objects.
+
+2012-07-25	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixWaterlevelFacet.java:
+	  Removed instanceof hack to fetch the WQKms of the fix realizations.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixWaterlevelFacet.java:
+	  New. Subclass of WaterlevelFacet. Used to fetch the WQKms the fix realization way.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Create the subclassed waterlevel facets.
+
+2012-07-25  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Create proper facets for Ws and Qs.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Also add Q-Facet.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Add WaterlevelFacet.
+
+	* doc/conf/artifacts/fixanalysis.xml:
+	  Add output and facet compability.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixRealizingAccess.java:
+	  Fix data names in FixRealizingAccess.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/WaterlevelFacet.java:
+	  Handle slightly different access to Fixation-WQKms.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/WaterlevelFacet.java:
+	  Handle slightly different access to Fixation-WQKms.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixationSelect.java:
+	  Fix (last?) vol(l)mer naming issue.
+
+2012-07-24	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/StateFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/states/ManualPointsSingleState.java
+	  src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java
+	  src/main/java/de/intevation/flys/themes/ThemeMapping.java:
+	  s/.equals("")/.length() == 0/
+
+2012-07-24	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Calculation6.java,
+	  src/main/java/de/intevation/flys/artifacts/model/WQTimerange.java,
+	  src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java,
+	  src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java,
+	  src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Removed some superfluous casts.
+
+2012-07-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  Removed some inner whitespace.
+
+2012-07-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixResult.java:
+	  New base class for fixing analysis results.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingResult.java:
+	  Inherits from FixResult.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	  Calculation returns FixRealizingResult.
+
+	* src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java:
+	  Remove superfluous import.
+
+	* src/main/java/de/intevation/flys/artifacts/model/Calculation4.java:
+	  Cosmetics.
+
+2012-07-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
+	  Broke over long line.
+
+	* src/main/java/de/intevation/flys/artifacts/model/Segment.java:
+	  Added some getters.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	  Calculated the Q -> Ws. TODO: Produce result.
+
+2012-07-23	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Adjusted i18n strings (vollmer).
+
+2012-07-23	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/LocationSelect.java:
+	  Set ld_mode so that FLYSUtils can use it.
+
+2012-07-23	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Adjusted i18n strings (vollmer).
+
+2012-07-23	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java:
+	  Handle FixationArtifacts with as much care as WINFOArtifacts,
+	  by using refactore FLYSUtils.
+
+2012-07-23	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Towards per-Gauge-input of W/Q values for FixationArtifact.
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java,
+	  src/main/java/de/intevation/flys/utils/FLYSUtils.java:
+	  (getGauges): Refactored, moved from WINFOArtifact to FLYSUtils.
+	
+	* src/main/java/de/intevation/flys/utils/FLYSUtils.java:
+	  Handle unlucky differences in names of data for
+	  WINFOArtifact/FixationArtifact.
+	
+	* doc/conf/artifacts/fixanalysis.xml:
+	  (Re-)use WQAdapted State for fix.analysis.
+
+2012-07-23	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/artifacts/winfo.xml,
+	  src/main/java/de/intevation/flys/artifacts/model/WKmsFactory.java,
+	  src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/HYKFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/RelativePointFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/states/fixation/QSelect.java,
+	  src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java,
+	  src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java,
+	  src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Cosmetics, docs.
+
+2012-07-23	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Segment.java,
+	  src/main/java/de/intevation/flys/artifacts/model/Calculation4.java:
+	  Moved code to convert W to Q at gauge to segments to be reusable.
+
+2012-07-23	Christian Lins	<christian.lins@intevation.de>
+
+	* doc/conf/themes.xml,
+	  doc/conf/second-themes.xml,
+	  doc/conf/default-themes.xml:
+	  Remove line style attributes from FixingReferenceEvents theme.
+
+2012-07-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Calculation4.java
+	  src/main/java/de/intevation/flys/artifacts/model/Segment.java:
+	  Moved reference point comparator to segment class be be reusable
+	  in FixA 'ausgelagerte Wasserspiegellagen'.
+
+2012-07-23	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Simplify annotation code.
+
+2012-07-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  Made abstract. Sub classes have to overwrite innerCalculate()
+	  calculate() now figures out the fixings overview and the function
+	  to fit and passes it to innerCalculate()
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	  Overrides innerCalculate() now.
+
+2012-07-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java:
+	  Prevent NPE in getOutputForState(). Why does this happen?
+
+2012-07-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  Made curve fitting over the given calculation range reusable. Removed dead code.
+
+2012-07-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Moved more common code into base class.
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* contrib/fixoverview2html.xsl: Clip the displayed from/to ranges
+	  of the gauges to the max extent of the events.
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* contrib/fixoverview2html.xsl: Embed german and english translations
+	  into the stylesheet. This should be better done by importing
+	  an external resource depending on the choosen locale!
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* contrib/fixoverview2html.xsl: Introduced i18n to transformation.
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
+	  Wrong epsilon was taken so sector aggregation was not working
+	  leading to too large result documents and wrong range display
+	  on client side.
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* contrib/fixoverview2html.xsl: Render the names of the gauges into
+	  the header line. Full name and spread is displayed as a tooltip.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml: Use SQPeriodSelect state for the input of
+	  a time range. The difference to PeriodSelect is the UI provider desired
+	  by this state.
+
+	* src/main/java/de/intevation/flys/artifacts/states/sq/SQPeriodSelect.java:
+	  New subclass of PeriodSelect; this state wants to be rendered in a
+	  'sq.period.select' UI provider.
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* contrib/fixoverview2html.xsl: To help developing the 
+	  HTML overview stylsheet more quickly bring back in sync with
+	  version of the flys-client.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/conf/artifacts/minfo.xml: Changed the parameters for SQ relation
+	  period selection; only a single period is allowed now.
+
+	* src/main/java/de/intevation/flys/artifacts/states/PeriodSelect.java: New
+	  class that allows the selection of a time period.
+
+	* src/main/java/de/intevation/flys/artifacts/access/SQRelationAccess.java:
+	  Reduced support of time periods to a single period.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java:
+	  Adapted the usage of SQRelationAccess which method signature has
+	  changed; it returns a single DateRange instance only.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties: Modified the keys of the
+	  state for SQ relation time period input.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/sq/SQOverviewGenerator.java:
+	  Disabled legends in this overview.
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/sq/SQOverviewGenerator.java:
+	  Removed superfluous imports.
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/resources/messages_de.properties,
+	  src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties:
+	  Fixed anomalies.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/ReportGenerator.java,
+	  src/main/java/de/intevation/flys/exports/AbstractExporter.java,
+	  src/main/java/de/intevation/flys/exports/ATExporter.java,
+	  src/main/java/de/intevation/flys/exports/sq/SQOverviewGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/MapGenerator.java,
+	  src/main/java/de/intevation/flys/exports/OutGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java:
+	  Added a setCollection() method that allows the caller of OutGenerators
+	  to set a reference to a FLYSArtifactCollection.
+
+	* src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
+	  Use setCollection() to set the reference to the current
+	  FLYSArtifactCollection before using OutGenerators.
+
+	* doc/conf/conf.xml: Registered the SQOverviewGenerator.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
+	  Add a list of gauges which intersect the range of the selected columns:
+
+	    <fixings>
+	      <gauges from="..." to="..." name="..."/>
+	      ...
+	      <gauges from="..." to="..." name="..."/>
+	    </fixings>
+
+	* src/main/java/de/intevation/flys/artifacts/model/GaugeRange.java:
+	  Store the name of the gauge, too.
+
+	* src/main/java/de/intevation/flys/artifacts/model/GaugeFinderFactory.java:
+	  Load the names of the gauges from database, too.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Some minor refactoring.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	  Call super constructor to retrieve the common data from the artifact.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  New. Common base class for Fix*Calculations.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Moved common stuff to base class FixCalculation.
+
+	 * src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	   Inherit from FixCalculation.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixRealizingAccess.java:
+	  Extract parameters that are only relevant for the
+	  'Ausgelagerte Wasserspiegellagen' calculation.
+
+	  isQ():         Must we convert the given values from W to Q first?
+	                 Used data field: 'fix_isq'
+	  getSegments(): Segments same semantics as WINFO's 
+	                 'W fuer ungleichwertige Abfluesse.'
+	                 Used data field: 'fix_segments'
+
+	* src/main/java/de/intevation/flys/artifacts/model/Segment.java,
+	  src/main/java/de/intevation/flys/artifacts/access/FixAccess.java:
+	  Cosmetics.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixAccess.java:
+	  New. Common base class for the Fix*Access.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixAnalysisAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/access/FixRealizingAccess.java:
+	  Now inherit from FixAccess.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/ParametersExporter.java:
+	  Prevent NPE.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixFacetUtils.java:
+	  Use constant to lookup column instead of dynamically allocated array.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixResult.java:
+	  Removed.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisResult.java:
+	  Re-added here.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAvSectorFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalDeviationFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixWQCurveFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAnalysisFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixDerivateFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalReferenceFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisPeriodsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixDeviationFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixOutlierFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixReferenceEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java,
+	  src/main/java/de/intevation/flys/exports/fixings/ParametersExporter.java,
+	  src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Adjusted.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java:
+	  New. Stub for 'Ausgelagerte Wasserspiegellagen' calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixRealizingAccess.java:
+	  New. Stub for accessing the artifact to extract the relevant parameters
+	  for the 'ausgelagerte Wasserspiegellagen' calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Call the calculation if the state is reached.
+
+	* src/main/java/de/intevation/flys/artifacts/states/DefaultState.java:
+	  Removed trailing whitespace.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixationVolmerCompute.java:
+	  Deleted.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java:
+	  Re-added here.
+
+	* doc/conf/artifacts/fixanalysis.xml: Adjusted. BTW: Vollmer is spelled with two 'l's.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixationCompute.java:
+	  Removed.
+
+	* src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java:
+	  Re-added.
+
+	* doc/conf/artifacts/fixanalysis.xml: Adjusted.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  Deleted
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java:
+	  Re-added.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixAnalysisAccess.java,
+	  src/main/java/de/intevation/flys/artifacts/states/fixation/FixationCompute.java:
+	  Adjusted class name usage.
+
+2012-07-19	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java,
+	  src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  native2ascii with properties files.
+	  Show analysis periods as subtitle in W/Q chart.
+
+2012-07-19	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/HistoricalDischargeCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ReferenceCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/WDifferencesCurveGenerator.java,
+	  src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Add subtitle to Fix W/Q chart.
+	  Move addSubtitle() code from generators up to ChartGenerate which saves 
+	  a lot of duplicate code.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixationArtifactAccess.java:
+	  Deleted.
+
+	* src/main/java/de/intevation/flys/artifacts/access/FixAnalysisAccess.java:
+	  Re-added.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixAvSectorFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalDeviationFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixWQCurveFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAnalysisFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixDerivateFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalReferenceFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisPeriodsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixDeviationFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixOutlierFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/fixings/FixReferenceEventsFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/states/fixation/FixationCompute.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java:
+	  Adjusted class name usage.
+
+2012-07-19  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/DefaultState.java:
+	  Sourced code to set default values of a parameter to an own method.
+	  Subclasses should override this method.
+
+	* src/main/java/de/intevation/flys/artifacts/states/OutliersInput.java:
+	  Set default value for outliers to "3".
+
+2012-07-19	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixDerivedCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java,
+	  src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Add kilometer info to chart titles.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSQPSArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSKmArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSHwsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSCatchmentArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSDBArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/RiverAxisArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSFloodplainArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/WMSLineArtifact.java,
+	  src/main/java/de/intevation/flys/utils/ThemeUtil.java,
+	  src/main/java/de/intevation/flys/utils/FLYSUtils.java,
+	  src/main/java/de/intevation/flys/exports/ChartSettings.java,
+	  src/main/java/de/intevation/flys/jfree/XYStyle.java:
+	  Use Integer.parseInt() instead of Integer.valueOf() + Autounboxing.
+	
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java:
+	  Replaced "string -> object -> native -> object" by simple "string -> object".
+	  Removed stupid duplicate XPathing.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/QWSeriesCollection.java:
+	  Use only blue as point color.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Adjusted Delta W(t) CSV exporter to customers wishes.
+
+	* src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Reordered columns, removed description, added W and formatted date
+	  via i18n.
+
+	* src/main/java/de/intevation/flys/utils/Formatter.java:
+	  Added method to get a formatter based on pattern and locale.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Adjusted i18n strings.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
+	  Classify each discharge range by the gauges which intersect it.
+
+	* src/main/java/de/intevation/flys/artifacts/model/Range.java:
+	  Added convinience constructor.
+
+	* src/main/java/de/intevation/flys/artifacts/model/GaugeFinder.java:
+	  Added method to return all gauges.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
+	  Use bandwidth parameter for width of band, adjusted name to be
+	  displayed in legend.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* doc/conf/default-themes.xml,
+	  src/main/java/de/intevation/flys/utils/ThemeUtil.java,
+	  src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
+	  Change bandwidth type to double (still bugged, round integers still
+	  work, though).
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Added column for time range.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties
+	  src/main/resources/messages_en.properties
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings.
+
+	* src/main/java/de/intevation/flys/artifacts/resources/Resources.java:
+	  Fixed stupid formatting bug.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java:
+	  Added discharge column.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added missing strings.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java:
+	  Removed trailing whitespace.
+
+2012-07-17	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/utils/ThemeUtil.java,
+	  src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/StyledSeriesBuilder.java,
+	  src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java,
+	  src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java,
+	  src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java,
+	  src/main/java/de/intevation/flys/collections/CollectionAttribute.java:
+	  Cosmetics, doc.
+
+2012-07-17	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Partial implementation of issue720 (bandwith for curves), in
+	longitudinal section ws only, no styling, integer-based.
+
+	* doc/conf/default-themes.xml: Add bandwidth to fields of longitudinal
+	  section facets.
+
+	* src/main/java/de/intevation/flys/utils/ThemeUtil.java: Add bandwidth
+	  theme parsing.
+
+	* src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
+	  If bandwidth is set, add an area data series with datapoints
+	  above/under the actual data points.
+
+	* src/main/java/de/intevation/flys/exports/StyledSeriesBuilder.java:
+	  Helper for adding points with offset.
+
+2012-07-17	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Measurement.java:
+	  Use Q_BPEGEL as symbolic name for Q
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java:
+	  Out commented the LEFT JOINs which produce a lot of empty and
+	  redundant data. Bring them back in when we treat subsamples right.
+
+2012-07-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Parameters.java:
+	  Added getValue() method.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java:
+	  Store location of calculation in result, too.
+	  
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQFractionResult.java:
+	  Added method getTotalCount() to return the number of used S/Q pairs.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQResult.java:
+	  Store location of result, too.
+
+	* src/main/java/de/intevation/flys/exports/sq/SQRelationExporter.java:
+	  Write parameters as export result.
+
+2012-07-16	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/datacage/Recommendations.java:
+	  Bit of doc.
+
+	* src/main/java/de/intevation/flys/artifacts/CollectionMonitor.java:
+	  TODO for automatic official lines added.
+
+2012-07-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java:
+	  Out commented debug output which caused OOM errors.
+
+2012-07-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/SQOverview.java,
+	  src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java:
+	  Q is not taken from MESSUNG.Q but from MESSUNG.Q_BPEGEL
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/Measurement.java:
+	  Fixed indentation. More macros.
+
+	* src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java:
+	  Removed trailing whitespace.
+
+2012-07-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* Tagged module as '2.8'.
+
 2012-07-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/jfree/StyledXYSeries.java,
@@ -16711,7 +19606,7 @@
 	  Made getExplodedValues static.
 
 	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
-	  Use new logic to calculate "W für ungleichwertige Abfluesse".
+	  Use new logic to calculate "W fuer ungleichwertige Abfluesse".
 	  Not working, yet.
 
 	* ChangeLog: Fixed former entry.
--- a/flys-artifacts/contrib/fixoverview2html.xsl	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/contrib/fixoverview2html.xsl	Fri Sep 28 12:15:40 2012 +0200
@@ -9,51 +9,212 @@
 
   <xsl:param name="project-uuid">de3f3307-3429-4ff9-8f43-3fb2fcf21b27</xsl:param>
   <xsl:param name="render-checkboxes" select="true()"/>
+  <xsl:param name="callback"/>
+
+  <xsl:param name="locale">de</xsl:param>
+
+  <xsl:decimal-format name="de" decimal-separator=',' grouping-separator='.'/>
+  <xsl:decimal-format name="en" decimal-separator='.' grouping-separator=','/>
+
+  <!-- XXX: This kind of i18n is cheesy.
+            It should be better done in an external resource. -->
+
+  <xsl:variable name="km-pattern">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">0,##</xsl:when>
+      <xsl:otherwise>0.##</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-event">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Ereignis</xsl:when>
+      <xsl:otherwise>Event</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-legend">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Legende</xsl:when>
+      <xsl:otherwise>Caption</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-color">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Farbe</xsl:when>
+      <xsl:otherwise>Color</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-meaning">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Bedeutung</xsl:when>
+      <xsl:otherwise>Meaning</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-around-mnq">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">um MNQ</xsl:when>
+      <xsl:otherwise>around MNQ</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-around-mq">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">um MQ</xsl:when>
+      <xsl:otherwise>around MQ</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-around-mhq">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">um MHQ</xsl:when>
+      <xsl:otherwise>around MHQ</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-above-hq5">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">über HQ5</xsl:when>
+      <xsl:otherwise>above HQ5</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- TODO: Format dates according locale. -->
+
+  <xsl:template match="@*" mode="min">
+    <xsl:if test="position() = 1">
+      <xsl:value-of select="number(.)"/>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="@*" mode="max">
+    <xsl:if test="position() = last()">
+      <xsl:value-of select="number(.)"/>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:variable name="global-min">
+    <xsl:choose>
+      <xsl:when test="count(/fixings/events/event/sector) &gt; 0">
+        <xsl:apply-templates mode="min" select="/fixings/events/event/sector/@from">
+          <xsl:sort data-type="number" select="."/>
+        </xsl:apply-templates>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="number(/fixings/river/@from)"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="global-max">
+    <xsl:choose>
+      <xsl:when test="count(/fixings/events/event/sector) &gt; 0">
+        <xsl:apply-templates mode="max" select="/fixings/events/event/sector/@to">
+          <xsl:sort data-type="number" select="."/>
+        </xsl:apply-templates>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="number(/fixings/river/@to)"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
 
   <xsl:template name="percent">
     <xsl:param name="sector"/>
-    <xsl:variable name="rfrom" select="number(/fixings/river/@from)"/>
-    <xsl:variable name="rto" select="number(/fixings/river/@to)"/>
-    <xsl:variable name="rlength" select="$rto - $rfrom"/>
 
-    <xsl:variable name="sfrom" select="number($sector/@from)"/>
-    <xsl:variable name="sto" select="number($sector/@to)"/>
-    <xsl:variable name="slength" select="$sto - $sfrom"/>
-    <xsl:value-of select="100.0 * ($slength div $rlength)"/>
+    <xsl:variable name="start">
+      <xsl:choose>
+        <xsl:when test="number($sector/@from) &lt; $global-min">
+          <xsl:value-of select="$global-min"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="number($sector/@from)"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="end">
+      <xsl:choose>
+        <xsl:when test="number($sector/@to) &gt; $global-max">
+          <xsl:value-of select="$global-max"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="number($sector/@to)"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$end &lt; $start">
+        <xsl:value-of select="number(0)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="100.0 * (($end - $start) div ($global-max - $global-min))"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="emit-gap-gauge">
+    <xsl:param name="gauge"/>
+    <xsl:call-template name="internal-emit-gap">
+      <xsl:with-param name="sector" select="$gauge"/>
+      <xsl:with-param name="preds" select="$gauge/preceding-sibling::gauge"/>
+    </xsl:call-template>
   </xsl:template>
 
   <xsl:template name="emit-gap">
     <xsl:param name="sector"/>
-    <xsl:variable name="preds" select="$sector/preceding-sibling::sector"/>
-    <xsl:variable name="num-preds" select="count($preds)"/>
-    <xsl:variable name="glength">
+    <xsl:call-template name="internal-emit-gap">
+      <xsl:with-param name="sector" select="$sector"/>
+      <xsl:with-param name="preds" select="$sector/preceding-sibling::sector"/>
+    </xsl:call-template>
+  </xsl:template>
+
+  <xsl:template name="internal-emit-gap">
+    <xsl:param name="sector"/>
+    <xsl:param name="preds"/>
+
+    <xsl:variable name="start">
       <xsl:choose>
-        <xsl:when test="$num-preds &lt; 1">
-          <xsl:variable name="rfrom" select="number(/fixings/river/@from)"/>
-          <xsl:value-of select="number($sector/@from) - $rfrom"/>
+        <xsl:when test="number($sector/@from) &lt; $global-min">
+          <xsl:value-of select="$global-min"/>
         </xsl:when>
         <xsl:otherwise>
-          <xsl:variable name="bend" select="number($preds[last()]/@to)"/>
-          <xsl:value-of select="number($sector/@from) - $bend"/>
+          <xsl:value-of select="$sector/@from"/>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:variable>
-    <xsl:choose>
-      <xsl:when test="number($glength) &lt; 0.05 "/>
-      <xsl:otherwise>
-        <div>
-          <xsl:attribute name="style">
-            <xsl:text>width:</xsl:text>
-              <xsl:variable name="rfrom" select="number(/fixings/river/@from)"/>
-              <xsl:variable name="rto" select="number(/fixings/river/@to)"/>
-              <xsl:variable name="rlength" select="$rto - $rfrom"/>
-              <xsl:value-of select="100.0 * ($glength div $rlength)"/>
-            <xsl:text>%;float:left</xsl:text>
-          </xsl:attribute>
-          <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
-        </div>
-      </xsl:otherwise>
-    </xsl:choose>
+
+    <xsl:if test="$start &lt; $global-max">
+      <xsl:variable name="num-preds" select="count($preds)"/>
+      <xsl:variable name="prev-end">
+        <xsl:choose>
+          <xsl:when test="count($preds) &lt; 1">
+            <xsl:value-of select="$global-min"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="number($preds[last()]/@to)"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:if test="$prev-end &lt; $global-max">
+        <xsl:variable name="gap-len" select="$start - $prev-end"/>
+        <xsl:if test="$gap-len &gt; 0.005">
+          <div>
+            <xsl:attribute name="style">
+              <xsl:text>width:</xsl:text>
+                <xsl:value-of select="100.0 * ($gap-len div ($global-max - $global-min))"/>
+              <xsl:text>%;float:left</xsl:text>
+            </xsl:attribute>
+            <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
+          </div>
+        </xsl:if>
+      </xsl:if>
+    </xsl:if>
   </xsl:template>
 
   <xsl:template match="sector" mode="sectors">
@@ -79,19 +240,25 @@
       </xsl:attribute>
       <xsl:attribute name="title">
         <xsl:text>km </xsl:text>
-        <xsl:value-of select="@from"/>
+        <xsl:value-of select="format-number(@from, $km-pattern, $locale)"/>
         <xsl:text> - </xsl:text>
-        <xsl:value-of select="@to"/>
+        <xsl:value-of select="format-number(@to, $km-pattern, $locale)"/>
+        <xsl:choose>
+          <xsl:when test="@class = '0'"> / Q <xsl:value-of select="$i18n-around-mnq"/></xsl:when>
+          <xsl:when test="@class = '1'"> / Q <xsl:value-of select="$i18n-around-mq"/></xsl:when>
+          <xsl:when test="@class = '2'"> / Q <xsl:value-of select="$i18n-around-mhq"/></xsl:when>
+          <xsl:when test="@class = '3'"> / Q <xsl:value-of select="$i18n-above-hq5"/></xsl:when>
+        </xsl:choose>
       </xsl:attribute>
       <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
     </div>
   </xsl:template>
 
   <xsl:template match="event">
-    <tr>
+    <tr id="{@cid}">
       <xsl:if test="$render-checkboxes">
         <td>
-          <input type="checkbox" name="{$project-uuid}:{@cid}"/>
+          <input type="checkbox" name="{$project-uuid}:{@cid}" checked="true" onclick="{$callback}"/>
         </td>
       </xsl:if>
       <td>
@@ -104,15 +271,74 @@
     </tr>
   </xsl:template>
 
+  <xsl:template match="gauge" mode="gauges">
+    <xsl:call-template name="emit-gap-gauge">
+      <xsl:with-param name="gauge" select="."/>
+    </xsl:call-template>
+    <div>
+      <xsl:variable name="start">
+        <xsl:choose>
+          <xsl:when test="number(@from) &lt; $global-min">
+            <xsl:value-of select="$global-min"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="number(@from)"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:variable name="end">
+        <xsl:choose>
+          <xsl:when test="number(@to) &gt; $global-max">
+            <xsl:value-of select="$global-max"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="number(@to)"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:attribute name="style">
+        <xsl:text>overflow:hidden;background:</xsl:text>
+        <xsl:choose>
+          <xsl:when test="(count(preceding::*) mod 2) = 0">#ada96e</xsl:when>
+          <xsl:otherwise>silver</xsl:otherwise>
+        </xsl:choose>
+        <xsl:text>;width:</xsl:text>
+        <xsl:call-template name="percent">
+          <xsl:with-param name="sector" select="."/>
+        </xsl:call-template>
+        <xsl:text>%</xsl:text>
+        <xsl:text>;float:left</xsl:text>
+      </xsl:attribute>
+      <xsl:attribute name="title">
+        <xsl:value-of select="@name"/>
+        <xsl:text>: km </xsl:text>
+        <xsl:value-of select="format-number($start, $km-pattern, $locale)"/>
+        <xsl:text> - </xsl:text>
+        <xsl:value-of select="format-number($end, $km-pattern, $locale)"/>
+      </xsl:attribute>
+      <nobr><xsl:value-of select="@name"/></nobr>
+    </div>
+  </xsl:template>
+
   <xsl:template match="events">
-    <table width="95%" border="1" cellspacing="0" cellpadding="0" style="font-size: 11pt;font-family:Arial;Verdana,sans-serif">
+    <table width="97%" border="1" cellspacing="0" cellpadding="0"
+           style="font-size: 10pt;font-family:Arial;Verdana,sans-serif">
       <colgroup>
         <xsl:if test="$render-checkboxes">
-            <col width="1em"/>
+            <col width="20px"/>
         </xsl:if>
         <col width="*"/>
-        <col width="11em"/>
+        <col width="75px"/>
       </colgroup>
+      <tr>
+        <xsl:if test="$render-checkboxes">
+          <th>&#160;</th>
+        </xsl:if>
+        <th><xsl:apply-templates mode="gauges" select="/fixings/gauges"/></th>
+        <th><xsl:value-of select="$i18n-event"/></th>
+      </tr>
       <xsl:apply-templates/>
     </table>
   </xsl:template>
@@ -124,11 +350,48 @@
       </head>
       <body>
         <xsl:apply-templates/>
+        <hr/>
+        <table border="1" cellspacing="0" cellpadding="0">
+          <caption><xsl:value-of select="$i18n-legend"/></caption>
+          <tr>
+            <th><xsl:value-of select="$i18n-color"/></th>
+            <th colspan="2"><xsl:value-of select="$i18n-meaning"/></th>
+          </tr>
+          <xsl:if test="count(/fixings/events/event/sector[@class = '0']) &gt; 0">
+          <tr>
+            <td style="background: green">&#160;</td>
+            <td><xsl:value-of select="$i18n-around-mnq"/></td>
+            <td>Q &#8712; [0, (MNQ+MQ)/2)</td>
+          </tr>
+          </xsl:if>
+          <xsl:if test="count(/fixings/events/event/sector[@class = '1']) &gt; 0">
+          <tr>
+            <td style="background: blue">&#160;</td>
+            <td><xsl:value-of select="$i18n-around-mq"/></td>
+            <td>Q &#8712; [(MNQ+MQ)/2, (MQ+MHQ)/2)</td>
+          </tr>
+          </xsl:if>
+          <xsl:if test="count(/fixings/events/event/sector[@class = '2']) &gt; 0">
+          <tr>
+            <td style="background: magenta">&#160;</td>
+            <td><xsl:value-of select="$i18n-around-mhq"/></td>
+            <td>Q &#8712; [(MQ+MHQ)/2, HQ5)</td>
+          </tr>
+          </xsl:if>
+          <xsl:if test="count(/fixings/events/event/sector[@class = '3']) &gt; 0">
+          <tr>
+            <td style="background: red">&#160;</td>
+            <td><xsl:value-of select="$i18n-above-hq5"/></td>
+            <td>Q &#8712; [HQ5, &#8734;)</td>
+          </tr>
+          </xsl:if>
+        </table>
       </body>
     </html>
   </xsl:template>
 
   <xsl:template match="text()"/>
   <xsl:template match="text()" mode="sectors"/>
+  <xsl:template match="text()" mode="gauges"/>
 
 </xsl:stylesheet>
--- a/flys-artifacts/doc/conf/artifacts/fixanalysis.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/artifacts/fixanalysis.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -70,8 +70,8 @@
 
         <transition transition="de.intevation.flys.artifacts.transitions.ValueCompareTransition">
             <from state="state.fix.eventselect"/>
-            <to state="state.fix.volmer.function"/>
-            <condition data="calculation.mode" value="calculation.volmer"
+            <to state="state.fix.vollmer.function"/>
+            <condition data="calculation.mode" value="calculation.vollmer"
                 operator="equal"/>
         </transition>
 
@@ -122,7 +122,7 @@
 
         <state id="state.fix.analysis.compute"
             description="state.fix.analysis.compute"
-            state="de.intevation.flys.artifacts.states.fixation.FixationCompute">
+            state="de.intevation.flys.artifacts.states.fixation.FixAnalysisCompute">
             <outputmodes>
                 <outputmode name="fix_deltawt_export" description="output.fix_deltawt_export" mine-type="text/plain" type="export">
                     <facets>
@@ -134,6 +134,11 @@
                         <facet name="fix_parameters" description="facet.fix_parameters.csv" />
                     </facets>
                 </outputmode>
+                <outputmode name="fix_wq_curve_at_export" description="output.fix_wq_curve_at_export" mime-type="text/plain" type="export">
+                    <facets>
+                        <facet name="at" description="facet.fix_wq_curve_export.at"/>
+                    </facets>
+                </outputmode>
                 <outputmode name="fix_wq_curve" description="output.fix_wq_curve" mine-type="image/png" type="chart">
                     <facets>
                         <facet name="fix_sector_average_wq_0" description="Average values for Ws in Q sectors."/>
@@ -143,7 +148,17 @@
                         <facet name="fix_analysis_events_wq" description="Raw event values used in the calculation"/>
                         <facet name="fix_reference_events_wq" description="Raw event values used in the calculation"/>
                         <facet name="fix_wq_curve" description="WQ curve"/>
+                        <facet name="qsectors" description="qsectors."/>
                         <facet name="fix_outlier" description="The outliers"/>
+                        <facet name="other.wqkms.q"          description="W-Type of data" />
+                        <facet name="other.wqkms.w"          description="W-Type of data" />
+                        <facet name="other.wkms" description="facet.other.wqkms"/>
+                        <facet name="other.wqkms" description="facet.other.wqkms"/>
+                        <facet name="longitudinal_section.w" description="facet.longitudinal_section.w"/>
+                        <facet name="other.wq"    description="Point-like data like fixations"/>
+                        <facet name="heightmarks_points" description="facet.other.wkms.heightmarks_points"/>
+                        <facet name="discharge_curve.curve" description="facet.discharge_curve.curve"/>
+                        <facet name="fix_wq_curve.manualpoints" description="Manual points"/>
                     </facets>
                 </outputmode>
                 <outputmode name="fix_deltawt_curve" description="output.fix_deltawt_curve" mine-type="image/png" type="chart">
@@ -156,6 +171,8 @@
                         <facet name="fix_reference_events_dwt" description="Raw event values used in the calculation"/>
                         <facet name="fix_analysis_periods_dwt" description="Dateranges of analysis periods."/>
                         <facet name="fix_deviation_dwt" description="The standard variance"/>
+                        <facet name="fix_deltawt_curve.manualpoints" description="Manual points"/>
+                        <facet name="fix_reference_period_dwt" description="Reference period"/>
                     </facets>
                 </outputmode>
                 <outputmode name="fix_longitudinal_section_curve" description="output.fix_longitudinal_section_curve" mine-type="image/png" type="chart">
@@ -172,11 +189,13 @@
                         <facet name="fix_deviation_ls" description="The standard variance"/>
                         <facet name="fix_analysis_events_ls" description="Average values for Ws in Q sectors."/>
                         <facet name="fix_reference_events_ls" description="Average values for Ws in Q sectors."/>
+                        <facet name="fix_longitudinal_section_curve.manualpoints" description="Manual points"/>
                     </facets>
                 </outputmode>
                 <outputmode name="fix_derivate_curve" description="output.fix_derivate_curve" mine-type="image/png" type="chart">
                     <facets>
-                        <facet name="fix_derivate" description="Derivate curve"/>
+                        <facet name="fix_derivate_curve" description="Derivate curve"/>
+                        <facet name="fix_derivate_curve.manualpoints" description="Manual points"/>
                     </facets>
                 </outputmode>
                 <outputmode name="fix_report" description="output.fix_report.report" mime-type="text/plain" type="report">
@@ -187,45 +206,82 @@
             </outputmodes>
         </state>
 
-        <state id="state.fix.volmer.function"
-            description="state.fix.volmer.function"
+        <state id="state.fix.vollmer.function"
+            description="state.fix.vollmer.function"
             state="de.intevation.flys.artifacts.states.fixation.FunctionSelect">
             <data name="function" type="String"/>
         </state>
 
         <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
-            <from state="state.fix.volmer.function"/>
-            <to state="state.fix.volmer.preprocessing"/>
+            <from state="state.fix.vollmer.function"/>
+            <to state="state.fix.vollmer.preprocessing"/>
         </transition>
 
-        <state id="state.fix.volmer.preprocessing"
-            description="state.fix.volmer.preprocessing"
+        <state id="state.fix.vollmer.preprocessing"
+            description="state.fix.vollmer.preprocessing"
             state="de.intevation.flys.artifacts.states.fixation.PreprocessingSelect">
             <data name="preprocessing" type="Boolean"/>
         </state>
 
         <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
-            <from state="state.fix.volmer.preprocessing"/>
-            <to state="state.fix.volmer.qs"/>
+            <from state="state.fix.vollmer.preprocessing"/>
+            <to state="state.fix.vollmer.qs"/>
         </transition>
 
-        <state id="state.fix.volmer.qs" description="state.fix.volmer.qs"
-            state="de.intevation.flys.artifacts.states.fixation.QSelect">
-            <data name="qs" type="Double[]"/>
+        <state id="state.fix.vollmer.qs" description="state.fix.vollmer.qs"
+            state="de.intevation.flys.artifacts.states.WQAdapted">
+            <data name="wq_isq"   type="String" />
+            <data name="wq_values" type="WQTriple" />
         </state>
 
         <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
-            <from state="state.fix.volmer.qs"/>
-            <to state="state.fix.volmer.compute"/>
+            <from state="state.fix.vollmer.qs"/>
+            <to state="state.fix.vollmer.compute"/>
         </transition>
 
-        <state id="state.fix.volmer.compute"
-            description="state.fix.volmer.compute"
-            state="de.intevation.flys.artifacts.states.fixation.FixationVolmerCompute">
+        <state id="state.fix.vollmer.compute"
+            description="state.fix.vollmer.compute"
+            state="de.intevation.flys.artifacts.states.fixation.FixRealizingCompute">
             <outputmodes>
-                <outputmode>
+                <outputmode name="longitudinal_section" description="output.longitudinal_section" mime-type="image/png" type="chart">
                     <facets>
-                        <facet/>
+                    	<facet name="longitudinal_section.w" description="facet.longitudinal_section.w"/>
+                    	<facet name="longitudinal_section.q" description="facet.longitudinal_section.q"/>
+                        <facet name="w_differences" description="facet.w_differences"/>
+                        <facet name="other.wkms" description="facet.other.wkms"/>
+                        <facet name="other.wqkms" description="facet.other.wqkms"/>
+                        <facet name="heightmarks_points" description="facet.other.wkms.heightmarks_points"/>
+                        <facet name="w_differences.manualpoints" description="Manuelle Punkte"/>
+                        <facet name="longitudinal_section.manualpoints" description="Manuelle Punkte"/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                    </facets>
+                </outputmode>
+                <outputmode name="fix_wq_curve" description="output.fix_wq_curve" mine-type="image/png" type="chart">
+                    <facets>
+                        <facet name="fix_sector_average_wq_0" description="Average values for Ws in Q sectors."/>
+                        <facet name="fix_sector_average_wq_1" description="Average values for Ws in Q sectors."/>
+                        <facet name="fix_sector_average_wq_2" description="Average values for Ws in Q sectors."/>
+                        <facet name="fix_sector_average_wq_3" description="Average values for Ws in Q sectors."/>
+                        <facet name="fix_analysis_events_wq" description="Raw event values used in the calculation"/>
+                        <facet name="fix_reference_events_wq" description="Raw event values used in the calculation"/>
+                        <facet name="fix_wq_curve" description="WQ curve"/>
+                        <facet name="fix_outlier" description="The outliers"/>
+                        <facet name="qsectors" description="qsectors."/>
+                        <facet name="other.wqkms.q"          description="W-Type of data" />
+                        <facet name="other.wqkms.w"          description="W-Type of data" />
+                        <facet name="other.wkms" description="facet.other.wqkms"/>
+                        <facet name="other.wqkms" description="facet.other.wqkms"/>
+                        <facet name="longitudinal_section.w" description="facet.longitudinal_section.w"/>
+                        <facet name="other.wq"    description="Point-like data like fixations"/>
+                        <facet name="heightmarks_points" description="facet.other.wkms.heightmarks_points"/>
+                        <facet name="discharge_curve.curve" description="facet.discharge_curve.curve"/>
+                    </facets>
+                </outputmode>
+                <outputmode name="fix_waterlevel_export" description="output.fix_waterlevel_export" mine-type="text/plain" type="export">
+                    <facets>
+                        <facet name="csv" description="facet.waterlevel_export.csv" />
+                        <facet name="wst" description="facet.waterlevel_export.wst" />
+                        <facet name="pdf" description="facet.waterlevel_export.pdf" />
                     </facets>
                 </outputmode>
             </outputmodes>
--- a/flys-artifacts/doc/conf/artifacts/manualpoints.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/artifacts/manualpoints.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -18,6 +18,10 @@
             <facet name="reference_curve_normalized.manualpoints" description="points"/>
             <facet name="historical_discharge.manualpoints" description="Points provided by user." />
             <facet name="cross_section.manualline" description="Lines provided by user." />
+            <facet name="fix_wq_curve.manualpoints" description="Points provided by user." />
+            <facet name="fix_deltawt_curve.manualpoints" description="Points provided by user." />
+            <facet name="fix_longitudinal_section_curve.manualpoints" description="Points provided by user." />
+            <facet name="fix_derivate_curve.manualpoints" description="Points provided by user." />
           </facets>
         </outputmode>
       </outputmodes>
--- a/flys-artifacts/doc/conf/artifacts/minfo.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/artifacts/minfo.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -33,15 +33,36 @@
             <condition data="calculation_mode" value="calc.sq.relation" operator="equal"/>
         </transition>
 
+        <transition transition="de.intevation.flys.artifacts.transitions.ValueCompareTransition">
+            <from state="state.minfo.calculation_mode"/>
+            <to state="state.minfo.bed.year_epoch"/>
+            <condition data="calculation_mode" value="calc.bed.diff" operator="equal"/>
+        </transition>
+
+        <transition transition="de.intevation.flys.artifacts.transitions.ValueCompareTransition">
+            <from state="state.minfo.calculation_mode"/>
+            <to state="state.minfo.bed.location"/>
+            <condition data="calculation_mode" value="calc.bed.quality" operator="equal"/>
+        </transition>
+
         <state id="state.minfo.distance_only" description="state.minfo.distance_only" state="de.intevation.flys.artifacts.states.DistanceOnlySelect" helpText="help.minfo.distance">
             <data name="ld_from" type="Double" />
             <data name="ld_to"   type="Double" />
         </state>
 
+        <state id="state.minfo.bed.year_epoch" description="state.minfo.bed.year_epoch" state="de.intevation.flys.artifacts.states.minfo.YearEpochSelect" helpText="help.minfo.year_epoch">
+            <data name="ye_select" type="String" />
+        </state>
+
         <state id="state.minfo.sq.location" description="state.minfo.sq.location" state="de.intevation.flys.artifacts.states.LocationSelect" helpText="help.minfo.sq.loaction">
             <data name="ld_locations" type="double"/>
         </state>
 
+        <state id="state.minfo.bed.location" description="state.minfo.bed.location" state="de.intevation.flys.artifacts.states.DistanceOnlySelect" helpText="help.minfo.bed.loaction">
+            <data name="ld_from" type="Double" />
+            <data name="ld_to" type="Double" />
+        </state>
+
         <transition transition="de.intevation.flys.artifacts.transitions.ValueCompareTransition">
             <from state="state.minfo.distance_only"/>
             <to state="state.minfo.dischargestate"/>
@@ -56,19 +77,38 @@
 
         <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
             <from state="state.minfo.sq.location"/>
-            <to state="state.minfo.sq.periods"/>
+            <to state="state.minfo.sq.period"/>
+        </transition>
+
+        <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
+            <from state="state.minfo.bed.year_epoch"/>
+            <to state="state.minfo.bed.difference_select"/>
+        </transition>
+
+        <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
+            <from state="state.minfo.bed.location"/>
+            <to state="state.minfo.bed.periods"/>
         </transition>
 
         <state id="state.minfo.dischargestate" description="state.minfo.dischargestate" state="de.intevation.flys.artifacts.states.DischargeState" helpText="help.minfo.dischargestate">
-            <data name="total.channel" type="intoptions"/>
-            <data name="main.channel"  type="intoptions"/>
+            <data name="total_channel" type="intoptions"/>
+            <data name="main_channel"  type="intoptions"/>
         </state>
 
         <state id="state.minfo.soundings" description="state.minfo.soundingsstate" state="de.intevation.flys.artifacts.states.SoundingsSelect" helpText="help.minfo.soundingsstate">
             <data name="soundings" type="options"/>
         </state>
 
-        <state id="state.minfo.sq.periods" description="state.minfo.sq.periods" state="de.intevation.flys.artifacts.states.PeriodsSelect">
+        <state id="state.minfo.sq.period" description="state.minfo.sq.period" state="de.intevation.flys.artifacts.states.sq.SQPeriodSelect">
+            <data name="start" type="Long"/>
+            <data name="end"   type="Long"/>
+        </state>
+
+        <state id="state.minfo.bed.difference_select" description="state.minfo.bed.difference_select" state="de.intevation.flys.artifacts.states.minfo.DifferenceSelect" helpText="help.minfo.diff_select">
+            <data name="diffids" type="String" />
+        </state>
+
+        <state id="state.minfo.bed.periods" description="state.minfo.bed.periods" state="de.intevation.flys.artifacts.states.minfo.BedQualityPeriodsSelect">
             <data name="periods" type="String"/>
         </state>
 
@@ -83,10 +123,20 @@
         </transition>
 
         <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
-            <from state="state.minfo.sq.periods"/>
+            <from state="state.minfo.sq.period"/>
             <to state="state.minfo.sq.outliers"/>
         </transition>
 
+        <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
+            <from state="state.minfo.bed.difference_select"/>
+            <to state="state.minfo.bed.differences"/>
+        </transition>
+
+        <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
+            <from state="state.minfo.bed.periods"/>
+            <to state="state.minfo.bed.char_diameter"/>
+        </transition>
+
         <state id="state.minfo.flow_velocity" description="state.minfo.flow_velocity" state="de.intevation.flys.artifacts.states.FlowVelocityState" helpText="help.minfo.flowvelocity">
             <outputmodes>
                 <outputmode name="flow_velocity" description="output.flow_velocity" mime-type="image/png" type="chart">
@@ -130,11 +180,49 @@
             <data name="outliers" type="Double"/>
         </state>
 
+        <state id="state.minfo.bed.differences" description="state.minfo.bed.differences" state="de.intevation.flys.artifacts.states.minfo.DifferencesState" helpText="help.minfo.bed.differences">
+            <outputmodes>
+                <outputmode name="bed_difference_height_year" description="output.absolute_height" mime-type="image/png" type="chart">
+                    <facets>
+                        <facet name="bedheight_difference.height_year" description="A facet for absolute heights"/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                    </facets>
+                </outputmode>
+                <outputmode name="bed_difference_year" description="output.difference_year" mime-type="img/png" type="chart">
+                    <facets>
+                        <facet name="bedheight_difference.year" description="A facet for bed height differences"/>
+                        <facet name="bedheight_difference.morph_width" description="A facet for morphologic width"/>
+                        <facet name="bedheight_difference.year.height1" description="A facet for raw heights."/>
+                        <facet name="bedheight_difference.year.height2" description="A facet for raw heights."/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                    </facets>
+                </outputmode>
+                <outputmode name="bed_difference_epoch" description="output.difference_epoch" mime-type="img/png" type="chart">
+                    <facets>
+                        <facet name="bedheight_difference.epoch" description="A facet for bed height differences"/>
+                        <facet name="bedheight_difference.epoch.height1" description="A facet for raw heights."/>
+                        <facet name="bedheight_difference.epoch.height2" description="A facet for raw heights."/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                    </facets>
+                </outputmode>
+            </outputmodes>
+        </state>
+
+        <state id="state.minfo.bed.char_diameter" description="state.minfo.bed.char_diameter" state="de.intevation.flys.artifacts.states.minfo.CharDiameter">
+            <data name="bed_diameter" type="options"/>
+            <data name="load_diameter" type="options"/>
+        </state>
+
         <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
             <from state="state.minfo.sq.outliers"/>
             <to state="state.minfo.sq.relation"/>
         </transition>
 
+        <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
+            <from state="state.minfo.bed.char_diameter"/>
+            <to state="state.minfo.bed.bed_quality"/>
+        </transition>
+
         <state id="state.minfo.sq.relation" description="state.minfo.sq.relation" state="de.intevation.flys.artifacts.states.SQRelation">
             <outputmodes>
                 <outputmode name="sq_relation_a" description="output.sq_relation" type="chart">
@@ -142,6 +230,8 @@
                         <facet name="sq_a_measurement" description="A facet for sq measurements"/>
                         <facet name="sq_a_outlier" description="A facet fo sq outliers"/>
                         <facet name="sq_a_curve" description="A facet for sq curve"/>
+                        <facet name="sq_a_outlier_curve" description="A facet for sq outlier curve"/>
+                        <facet name="sq_a_outlier_measurement" description="A facet for sq outlier measurement"/>
                     </facets>
                 </outputmode>
                 <outputmode name="sq_relation_b" description="output.sq_relation" type="chart">
@@ -149,6 +239,8 @@
                         <facet name="sq_b_measurement" description="A facet for sq measurements"/>
                         <facet name="sq_b_outlier" description="A facet fo sq outliers"/>
                         <facet name="sq_b_curve" description="A facet for sq curve"/>
+                        <facet name="sq_b_outlier_curve" description="A facet for sq outlier curve"/>
+                        <facet name="sq_b_outlier_measurement" description="A facet for sq outlier measurement"/>
                     </facets>
                 </outputmode>
                 <outputmode name="sq_relation_c" description="output.sq_relation" type="chart">
@@ -156,6 +248,8 @@
                         <facet name="sq_c_measurement" description="A facet for sq measurements"/>
                         <facet name="sq_c_outlier" description="A facet fo sq outliers"/>
                         <facet name="sq_c_curve" description="A facet for sq curve"/>
+                        <facet name="sq_c_outlier_curve" description="A facet for sq outlier curve"/>
+                        <facet name="sq_c_outlier_measurement" description="A facet for sq outlier measurement"/>
                     </facets>
                 </outputmode>
                 <outputmode name="sq_relation_d" description="output.sq_relation" type="chart">
@@ -163,6 +257,8 @@
                         <facet name="sq_d_measurement" description="A facet for sq measurements"/>
                         <facet name="sq_d_outlier" description="A facet fo sq outliers"/>
                         <facet name="sq_d_curve" description="A facet for sq curve"/>
+                        <facet name="sq_d_outlier_curve" description="A facet for sq outlier curve"/>
+                        <facet name="sq_d_outlier_measurement" description="A facet for sq outlier measurement"/>
                     </facets>
                 </outputmode>
                 <outputmode name="sq_relation_e" description="output.sq_relation" type="chart">
@@ -170,6 +266,8 @@
                         <facet name="sq_e_measurement" description="A facet for sq measurements"/>
                         <facet name="sq_e_outlier" description="A facet fo sq outliers"/>
                         <facet name="sq_e_curve" description="A facet for sq curve"/>
+                        <facet name="sq_e_outlier_curve" description="A facet for sq outlier curve"/>
+                        <facet name="sq_e_outlier_measurement" description="A facet for sq outlier measurement"/>
                     </facets>
                 </outputmode>
                 <outputmode name="sq_relation_f" description="output.sq_relation" type="chart">
@@ -177,6 +275,8 @@
                         <facet name="sq_f_measurement" description="A facet for sq measurements"/>
                         <facet name="sq_f_outlier" description="A facet fo sq outliers"/>
                         <facet name="sq_f_curve" description="A facet for sq curve"/>
+                        <facet name="sq_f_outlier_curve" description="A facet for sq outlier curve"/>
+                        <facet name="sq_f_outlier_measurement" description="A facet for sq outlier measurement"/>
                     </facets>
                 </outputmode>
                 <outputmode name="sq_overview" description="output.sq_overview" type="overview">
@@ -192,6 +292,27 @@
                 </outputmode>
             </outputmodes>
         </state>
+
+        <state id="state.minfo.bed.bed_quality" description="state.minfo.bed.bed_quality" state="de.intevation.flys.artifacts.states.minfo.BedQualityState" helpText="help.minfo.bed.bed_quality">
+            <outputmodes>
+                <outputmode name="bed_longitudinal_section" description="output.bed_longitudinal_section" mime-type="image/png" type="chart">
+                    <facets>
+                    	<facet name="bed_longitudinal_section.porosity_toplayer"/>
+                    	<facet name="bed_longitudinal_section.porosity_sublayer"/>
+                    	<facet name="bed_longitudinal_section.sediment_density_toplayer"/>
+                    	<facet name="bed_longitudinal_section.sediment_density_sublayer"/>
+                    	<facet name="bed_longitudinal_section.bed_diameter_toplayer"/>
+                    	<facet name="bed_longitudinal_section.bed_diameter_sublayer"/>
+                    	<facet name="bed_longitudinal_section.bedload_diameter"/>
+                    </facets>
+                </outputmode>
+                <outputmode name="bed_quality_export" description="output.bed_quality_export" type="export">
+                    <facets>
+                        <facet name="csv" description="facet.bed_quality_export.csv" />
+                    </facets>
+                </outputmode>
+            </outputmodes>
+        </state>
     </states>
 
 </artifact>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/doc/conf/artifacts/qsector.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<artifact name="qsector">
+  <states>
+    <state id="state.qsector.static"
+               description="state.qsector.static"
+               state="de.intevation.flys.artifacts.states.QSectorSingleState">
+      <outputmodes>
+        <outputmode name="fix_wq_curve" description="output.fix_wq_curve" mime-type="image/png" type="chart">
+          <facets>
+            <facet name="qsectors" description="qsectors."/>
+          </facets>
+        </outputmode>
+      </outputmodes>
+    </state>
+  </states>
+</artifact>
--- a/flys-artifacts/doc/conf/artifacts/winfo.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/artifacts/winfo.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -167,7 +167,8 @@
             <data name="wq_single" type="Double[]" />
         </state>
 
-        <state id="state.winfo.wq_adapted" description="state.winfo.wq_adapted" state="de.intevation.flys.artifacts.states.WQAdapted" helpText="help.winfo.discharge.longitudinal.wq">
+        <state id="state.winfo.wq_adapted" description="state.winfo.wq_adapted"
+               state="de.intevation.flys.artifacts.states.WQAdapted" helpText="help.winfo.discharge.longitudinal.wq">
             <!-- TODO Add data objects -->
             <data name="wq_isq"   type="String" />
             <data name="wq_values" type="WQTriple" />
--- a/flys-artifacts/doc/conf/conf.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/conf.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -110,11 +110,21 @@
             <artifact-factory name="gaugedischarge" description="Factory to create an artifact to host historical qs."
                 ttl="3600000"
                 artifact="de.intevation.flys.artifacts.GaugeDischargeArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
+            <artifact-factory name="qsectors" description="Factory to create an artifact to host qsectors."
+                ttl="3600000"
+                artifact="de.intevation.flys.artifacts.QSectorArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
 
             <!-- MINFO specific Artifacts -->
             <artifact-factory name="minfo" description="Factory to create an artifact to be used in module minfo."
                 ttl="3600000"
                 artifact="de.intevation.flys.artifacts.MINFOArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
+            <artifact-factory name="bedheight" description="Factory to create an artifact used in minfo datacage."
+                ttl="3600000"
+                artifact="de.intevation.flys.artifacts.BedHeightsArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
+
+            <artifact-factory name="gaugedischargecurve" description="Factory to create an artifact to show a discharge curve for a gauge."
+                ttl="3600000"
+                artifact="de.intevation.flys.artifacts.GaugeDischargeCurveArtifact">de.intevation.artifactdatabase.DefaultArtifactFactory</artifact-factory>
         </artifact-factories>
 
         <user-factory name="default" description="Factory to create new users">de.intevation.artifactdatabase.DefaultUserFactory</user-factory>
@@ -176,6 +186,22 @@
                 name="sq-km-chart"
                 service="de.intevation.flys.artifacts.services.SQKMChartService"
                 description="Returns a chart of km and date of meassuring points of a given river.">de.intevation.artifactdatabase.DefaultServiceFactory</service-factory>
+            <service-factory
+                name="modules"
+                service="de.intevation.flys.artifacts.services.ModuleService"
+                description="Returns a list of available modules.">de.intevation.artifactdatabase.DefaultServiceFactory</service-factory>
+            <service-factory
+                name="bed-km-chart"
+                service="de.intevation.flys.artifacts.services.BedKMChartService"
+                description="Returns a chart of km and date of meassuring points of a given river.">de.intevation.artifactdatabase.DefaultServiceFactory</service-factory>
+            <service-factory
+                name="bedload-km-chart"
+                service="de.intevation.flys.artifacts.services.BedloadKMChartService"
+                description="Returns a chart of km and date of meassuring points of a given river.">de.intevation.artifactdatabase.DefaultServiceFactory</service-factory>
+            <service-factory
+                name="gaugeoverviewinfo"
+                service="de.intevation.flys.artifacts.services.GaugeOverviewInfoService"
+                description="Returns an overview of the fixings of a given river.">de.intevation.artifactdatabase.DefaultServiceFactory</service-factory>
         </service-factories>
 
     </factories>
@@ -206,8 +232,16 @@
         <artifact name="staticwqkms" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${artifacts.config.dir}/artifacts/staticwqkms.xml" />
         <artifact name="fixanalysis" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${artifacts.config.dir}/artifacts/fixanalysis.xml" />
         <artifact name="gaugedischarge" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${artifacts.config.dir}/artifacts/gaugedischarge.xml" />
+        <artifact name="qsector" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="${artifacts.config.dir}/artifacts/qsector.xml" />
     </artifacts>
 
+    <modules>
+        <module name="winfo" selected="true"/>
+        <module name="minfo"/>
+        <module name="new_map"/>
+        <module name="new_chart"/>
+        <module name="fixanalysis"/>
+    </modules>
 
     <hooks>
         <hook
@@ -256,6 +290,15 @@
         <output-generator name="bedheight_middle">de.intevation.flys.exports.MiddleBedHeightGenerator</output-generator>
         <output-generator name="bedheight_middle_chartinfo">de.intevation.flys.exports.MiddleBedHeightInfoGenerator</output-generator>
         <output-generator name="bedheight_middle_export">de.intevation.flys.exports.MiddleBedHeightExporter</output-generator>
+        <output-generator name="bed_longitudinal_section">de.intevation.flys.exports.minfo.BedQualityGenerator</output-generator>
+        <output-generator name="bed_longitudinal_section_chartinfo">de.intevation.flys.exports.minfo.BedQualityInfoGenerator</output-generator>
+        <output-generator name="bed_quality_export">de.intevation.flys.exports.minfo.BedQualityExporter</output-generator>
+        <output-generator name="bed_difference_year">de.intevation.flys.exports.minfo.BedDifferenceYearGenerator</output-generator>
+        <output-generator name="bed_difference_year_chartinfo">de.intevation.flys.exports.minfo.BedDiffYearInfoGenerator</output-generator>
+        <output-generator name="bed_difference_epoch">de.intevation.flys.exports.minfo.BedDifferenceEpochGenerator</output-generator>
+        <output-generator name="bed_difference_epoch_chartinfo">de.intevation.flys.exports.minfo.BedDiffEpochInfoGenerator</output-generator>
+        <output-generator name="bed_difference_height_year">de.intevation.flys.exports.minfo.BedDiffHeightYearGenerator</output-generator>
+        <output-generator name="bed_difference_height_year_chartinfo">de.intevation.flys.exports.minfo.BedDiffHeightYearInfoGenerator</output-generator>
         <output-generator name="sq_relation_a">de.intevation.flys.exports.sq.SQRelationGeneratorA</output-generator>
         <output-generator name="sq_relation_b">de.intevation.flys.exports.sq.SQRelationGeneratorB</output-generator>
         <output-generator name="sq_relation_c">de.intevation.flys.exports.sq.SQRelationGeneratorC</output-generator>
@@ -269,6 +312,7 @@
         <output-generator name="sq_relation_e_chartinfo">de.intevation.flys.exports.sq.SQRelationInfoGenerator</output-generator>
         <output-generator name="sq_relation_f_chartinfo">de.intevation.flys.exports.sq.SQRelationInfoGenerator</output-generator>
         <output-generator name="sq_relation_export">de.intevation.flys.exports.sq.SQRelationExporter</output-generator>
+        <output-generator name="sq_overview">de.intevation.flys.exports.sq.SQOverviewGenerator</output-generator>
         <output-generator name="fix_parameters_export">de.intevation.flys.exports.fixings.ParametersExporter</output-generator>
         <output-generator name="fix_deltawt_export">de.intevation.flys.exports.fixings.DeltaWtExporter</output-generator>
         <output-generator name="fix_deltawt_curve">de.intevation.flys.exports.fixings.FixDeltaWtGenerator</output-generator>
@@ -277,6 +321,9 @@
         <output-generator name="fix_longitudinal_section_curve_chartinfo">de.intevation.flys.exports.fixings.FixLongitudinalSectionInfoGenerator</output-generator>
         <output-generator name="fix_derivate_curve">de.intevation.flys.exports.fixings.FixDerivedCurveGenerator</output-generator>
         <output-generator name="fix_derivate_curve_chartinfo">de.intevation.flys.exports.fixings.FixDerivedCurveInfoGenerator</output-generator>
+        <output-generator name="fix_waterlevel_export">de.intevation.flys.exports.WaterlevelExporter</output-generator>
+        <output-generator name="fix_vollmer_wq_curve">de.intevation.flys.exports.fixings.FixWQCurveGenerator</output-generator>
+        <output-generator name="fix_vollmer_wq_curve_chartinfo">de.intevation.flys.exports.fixings.FixWQCurveInfoGenerator</output-generator>
         <!-- Error report generators. -->
         <output-generator name="discharge_longitudinal_section_report">de.intevation.flys.exports.ReportGenerator</output-generator>
         <output-generator name="waterlevel_report">de.intevation.flys.exports.ReportGenerator</output-generator>
@@ -288,6 +335,7 @@
         <output-generator name="fix_report">de.intevation.flys.exports.ReportGenerator</output-generator>
         <!-- AT exporter. -->
         <output-generator name="computed_dischargecurve_at_export">de.intevation.flys.exports.ATExporter</output-generator>
+        <output-generator name="fix_wq_curve_at_export">de.intevation.flys.exports.fixings.FixATExport</output-generator>
     </output-generators>
 
     <!-- Path to the template file of the meta data. -->
--- a/flys-artifacts/doc/conf/default-themes.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/default-themes.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -48,6 +48,11 @@
             <inherit from="MinMaxPoints" />
         </inherits>
         <fields>
+            <field name="bandwidth" type="double" display="Bandbreite"
+                default="0"/>
+            <field name="fillcolor" type="Color" display="Bandbreitenfarbe"
+                default="104, 104, 104"/> 
+    	    <field name="transparency" type="int" default="20" display="Transparenz"/>
             <field name="linecolor" type="Color" display="Linienfarbe"
                 default="204, 204, 204" />
         </fields>
@@ -727,7 +732,9 @@
             <field name="showwidth" type="boolean" display="Breite anzeigen"
                 default="false" />
             <field name="showlevel" type="boolean" display="Wasserstand anzeigen"
-                default="false" />
+                default="true" />
+            <field name="showlinelabel" type="boolean" default="true"
+                display="Beschriftung anzeigen" />
             <field name="showmiddleheight" type="boolean"
                 display="Wasserstand anzeigen" default="false" />
         </fields>
@@ -748,7 +755,7 @@
         <inherits>
             <inherit from="LongitudinalSectionPoints" />
         </inherits>
-        <!--fields> <field name="linecolor" type="Color" display="Linienfarbe" 
+        <!--fields> <field name="linecolor" type="Color" display="Linienfarbe"
             default="0, 0, 0"/> </fields -->
     </theme>
 
@@ -942,7 +949,11 @@
     <theme name="Area">
         <inherits>
             <inherit from="Areas" />
-        </inherits>
+         </inherits>
+         <fields>
+            <field name="showarea" type="boolean" display="Show Area"
+                default="true"/>
+         </fields>
     </theme>
 
     <!-- Map -->
@@ -1054,6 +1065,151 @@
                 default="0, 0, 102" />
         </fields>
     </theme>
+    
+    <!-- Bed Quality -->
+    <theme name="PorosityTopLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="0, 0, 0" />
+        </fields>
+    </theme>
+    
+    <theme name="PorositySubLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="0, 0, 0" />
+        </fields>
+    </theme>
+    
+    <theme name="DensityTopLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#996366" />
+        </fields>
+    </theme>
+    
+    <theme name="DensitySubLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#996366" />
+        </fields>
+    </theme>
+    
+    <theme name="BedDiameterTopLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#FF0000" />
+        </fields>
+    </theme>
+    
+    <theme name="BedDiameterSubLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#FF0000" />
+        </fields>
+    </theme>
+    
+    <theme name="BedLoadDiameter">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#00FF00" />
+        </fields>
+    </theme>
+
+    <!-- Bedheight differences -->
+    <theme name="BedheightDiffYear">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="0, 204, 204" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffMorphWidth">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 204, 0" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffEpoch">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 0, 204" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffAbsHeight1">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 0, 204" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffAbsHeight2">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="255, 100, 100" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffHeightYear">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 0, 0" />
+        </fields>
+    </theme>
 
 
     <!-- FLOW VELOCITY -->
@@ -1130,13 +1286,17 @@
             <field name="linecolor" type="Color" default="227, 27, 162" />
         </fields>
     </theme>
-    
+
     <theme name="FixingDerivedCurve">
         <inherits>
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
             <field name="linecolor" type="Color" default="227, 27, 162" />
+            <field name="showpoints" type="boolean" display="Datenpunkte anzeigen"
+                default="false" hints="h" hidden="true" />
+            <field name="pointsize" type="int" display="Punktdicke"
+                default="5" hints="h" hidden="true" />
         </fields>
     </theme>
 
@@ -1145,7 +1305,7 @@
             <inherit from="ColorPoints" />
         </inherits>
         <fields>
-            <field name="showlines" type="boolean" default="false" />
+            <field name="showlines" type="boolean" default="true" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
             <field name="pointsize" type="int" display="Punktdicke"
@@ -1153,7 +1313,7 @@
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="0, 128, 0" />
             <field name="showpointlabel" type="boolean"
-                display="Punktbeschriftung anzeigen" default="false"/>
+                display="Punktbeschriftung anzeigen" default="true"/>
         </fields>
     </theme>
     <theme name="FixingSectorAverageWQ1">
@@ -1163,13 +1323,13 @@
         <fields>
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="showlines" type="boolean" default="false" />
+            <field name="showlines" type="boolean" default="true" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="0, 0, 255" />
             <field name="showpointlabel" type="boolean"
-                display="Punktbeschriftung anzeigen" default="false"/>
+                display="Punktbeschriftung anzeigen" default="true"/>
         </fields>
     </theme>
     <theme name="FixingSectorAverageWQ2">
@@ -1179,13 +1339,13 @@
         <fields>
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="showlines" type="boolean" default="false" />
+            <field name="showlines" type="boolean" default="true" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="255, 0, 255" />
             <field name="showpointlabel" type="boolean"
-                display="Punktbeschriftung anzeigen" default="false"/>
+                display="Punktbeschriftung anzeigen" default="true"/>
         </fields>
     </theme>
     <theme name="FixingSectorAverageWQ3">
@@ -1195,13 +1355,13 @@
         <fields>
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="showlines" type="boolean" default="false" />
+            <field name="showlines" type="boolean" default="true" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="255, 0, 0" />
             <field name="showpointlabel" type="boolean"
-                display="Punktbeschriftung anzeigen" default="false"/>
+                display="Punktbeschriftung anzeigen" default="true"/>
         </fields>
     </theme>
 
@@ -1216,15 +1376,23 @@
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="0, 255, 0" />
             <field name="showpointlabel" type="boolean"
-                display="Punktbeschriftung anzeigen" default="false"/>
+                display="Punktbeschriftung anzeigen" default="true"/>
         </fields>
     </theme>
 
-    <theme name="FixingReferenceEventsWQ">
+    <theme name="FixingReferenceEvents">
         <inherits>
             <inherit from="ColorPoints" />
         </inherits>
         <fields>
+            <field name="showlines" type="boolean" default="false"
+                hidden="true" />
+            <field name="showlinelabel" type="boolean" default="false"
+                hidden="true" />
+            <field name="linetype" type="Dash" display="Linienart"
+                default="10" hidden="true" />
+            <field name="linesize" type="int" display="Liniendicke"
+                default="1" hidden="true" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
@@ -1246,58 +1414,53 @@
 
     <theme name="FixingDeltaWtAverage0">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
                 default="0, 128, 0" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
     <theme name="FixingDeltaWtAverage1">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
                 default="0, 0, 255" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
     <theme name="FixingDeltaWtAverage2">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
                 default="255, 0, 255" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
     <theme name="FixingDeltaWtAverage3">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
                 default="255, 0, 0" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
 
-
     <theme name="FixingDeltaWtAnalysis">
         <inherits>
             <inherit from="ColorPoints" />
@@ -1305,6 +1468,8 @@
         <fields>
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="true"/>
             <field name="showlines" type="boolean" default="false" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
@@ -1314,20 +1479,6 @@
         </fields>
     </theme>
 
-    <theme name="FixingDeltaWtReference">
-        <inherits>
-            <inherit from="ColorPoints" />
-        </inherits>
-        <fields>
-            <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="showlines" type="boolean" default="false" />
-            <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 80, 160" />
-        </fields>
-    </theme>
     <theme name="FixingLSAverage0">
         <inherits>
             <inherit from="HiddenColorLines" />
@@ -1374,10 +1525,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
                 default="0, 128, 0" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
         </fields>
     </theme>
     <theme name="FixingSectorDeviationLS1">
@@ -1385,10 +1534,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
                 default="0, 0, 255" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
         </fields>
     </theme>
     <theme name="FixingSectorDeviationLS2">
@@ -1396,10 +1543,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
                 default="255, 0, 255" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
         </fields>
     </theme>
     <theme name="FixingSectorDeviationLS3">
@@ -1407,10 +1552,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
                 default="255, 0, 0" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
         </fields>
     </theme>
     <theme name="FixLSDeviation">
@@ -1418,10 +1561,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
                 default="100, 100, 100" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
         </fields>
     </theme>
     <theme name="FixLSAnalysis">
@@ -1449,8 +1590,8 @@
     		<inherit from="Areas"/>
     	</inherits>
     	<fields>
-    		<field name="alpha" type="int" default="50" disply="Alpha-Transparenz"/>
-    		<field name="fillcolor" type="Color" default="0, 0, 0" display="Füllfarbe"/>
+    		<field name="transparency" type="int" default="80" display="Transparenz"/>
+    		<field name="backgroundcolor" type="Color" default="0, 0, 0" display="Füllfarbe"/>
     	</fields>
     </theme>
     <theme name="FixingDeltaWtAnalysisPeriods">
@@ -1458,10 +1599,39 @@
     		<inherit from="Areas"/>
     	</inherits>
     	<fields>
-    		<field name="alpha" type="int" default="80" disply="Alpha-Transparenz"/>
-    		<field name="fillcolor" type="Color" default="255, 0, 0" display="Hauptfarbe"/>
-    		<field name="backgroundcolor" type="Color" default="0, 0, 255" display="Wechselfarbe"/>
+    		<field name="transparency" type="int" default="80" display="Transparenz"/>
+            <field name="backgroundcolor" type="Color" default="255, 0, 0" display="Füllfarbe" />
+    	</fields>
+    </theme>
+    
+    <theme name="FixingReferencePeriod">
+        <inherits>
+    		<inherit from="Areas"/>
+    	</inherits>
+    	<fields>
+    		<field name="transparency" type="int" default="80" display="Transparenz"/>
+            <field name="backgroundcolor" type="Color" default="0, 0, 255" display="Füllfarbe" />
     	</fields>
     </theme>
 
+    <theme name="QSectors">
+        <fields>
+            <field name="linecolor" type="Color" default="0, 0, 0" />
+            <field name="showlinelabel" type="boolean"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linetype" type="Dash" display="Linienart"
+                default="10" hidden="true" />
+            <field name="linesize" type="int" display="Liniendicke"
+                default="1" hidden="true" />
+            <field name="labelfontface" type="Font"
+                display="Beschriftung: Schriftart" default="arial" />
+            <field name="labelfontcolor" type="Color"
+                display="Beschriftung: Schriftfarbe" default="0, 0, 0" />
+            <field name="labelfontsize" type="int"
+                display="Beschriftung: Schriftgröße" default="10" />
+            <field name="labelfontstyle" type="Style"
+                display="Beschriftung: Schriftstil" default="standard" />
+        </fields>
+    </theme>
+
 </themegroup>
--- a/flys-artifacts/doc/conf/mapserver/db_layer.vm	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/mapserver/db_layer.vm	Fri Sep 28 12:15:40 2012 +0200
@@ -22,7 +22,7 @@
     #end
 
     PROJECTION
-        "init=epsg:$LAYER.getSrid()"
+        "init=epsg:31467"
     END
 
     METADATA
--- a/flys-artifacts/doc/conf/mapserver/mapfile.vm	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/mapserver/mapfile.vm	Fri Sep 28 12:15:40 2012 +0200
@@ -3,14 +3,14 @@
     STATUS ON
     SIZE 600 400
     MAXSIZE 4000
-    EXTENT -90 -180 90 180
+    EXTENT 3233232.55407617 5303455.37850183 3421524.44644752 5585825.50888523
     UNITS DD
     SHAPEPATH "$SHAPEFILEPATH"
     FONTSET "$CONFIGDIR/mapserver/fontset.txt"
     SYMBOLSET "$CONFIGDIR/mapserver/symbols.sym"
     IMAGECOLOR 255 255 255
     PROJECTION
-        "init=epsg:31466"
+        "init=epsg:31467"
     END
 
     DEBUG 5
--- a/flys-artifacts/doc/conf/meta-data.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/meta-data.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -27,7 +27,8 @@
                       <dc:statement>
                         SELECT id       AS prot_column_id,
                                name     AS prot_column_name,
-                               position AS prot_rel_pos
+                               position AS prot_rel_pos,
+                               description AS info
                         FROM wst_columns WHERE wst_id = ${prot_id}
                         ORDER by position
                       </dc:statement>
@@ -36,6 +37,7 @@
                           <dc:attribute name="name" value="${prot_column_name}"/>
                           <dc:attribute name="ids" value="base_data-wstv-${prot_rel_pos}-${prot_id}"/>
                           <dc:attribute name="factory" value="staticwkms"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </column>
                       </dc:elements>
                     </dc:context>
@@ -60,7 +62,8 @@
                       <dc:statement>
                         SELECT id       AS prot_column_id,
                                name     AS prot_column_name,
-                               position AS prot_rel_pos
+                               position AS prot_rel_pos,
+                               description AS info
                         FROM wst_columns WHERE wst_id = ${prot_id}
                         ORDER by position
                       </dc:statement>
@@ -69,6 +72,7 @@
                           <dc:attribute name="name" value="${prot_column_name}"/>
                           <dc:attribute name="ids" value="base_data-wstv-${prot_rel_pos}-${prot_id}"/>
                           <dc:attribute name="factory" value="wqinterpol"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </column>
                       </dc:elements>
                     </dc:context>
@@ -94,7 +98,8 @@
                       <dc:statement>
                         SELECT id       AS prot_column_id,
                                name     AS prot_column_name,
-                               position AS prot_rel_pos
+                               position AS prot_rel_pos,
+                               description AS info
                         FROM wst_columns WHERE wst_id = ${prot_id}
                         ORDER by position
                       </dc:statement>
@@ -103,6 +108,7 @@
                           <dc:attribute name="name" value="${prot_column_name}"/>
                           <dc:attribute name="ids" value="additionals-wstv-${prot_rel_pos}-${prot_id}"/>
                           <dc:attribute name="factory" value="staticwkms"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </column>
                       </dc:elements>
                     </dc:context>
@@ -128,7 +134,8 @@
                       <dc:statement>
                         SELECT id       AS prot_column_id,
                                name     AS prot_column_name,
-                               position AS prot_rel_pos
+                               position AS prot_rel_pos,
+                               description AS info
                         FROM wst_columns WHERE wst_id = ${prot_id}
                         ORDER by position
                       </dc:statement>
@@ -137,6 +144,7 @@
                           <dc:attribute name="name" value="${prot_column_name}"/>
                           <dc:attribute name="ids" value="additionals-wstv-${prot_rel_pos}-${prot_id}"/>
                           <dc:attribute name="factory" value="staticwkms"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </column>
                       </dc:elements>
                     </dc:context>
@@ -162,7 +170,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             description AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -171,6 +180,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="fixations-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="wqinterpol"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -195,7 +205,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             desciption AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -204,6 +215,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="fixations-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="wqinterpol"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -228,7 +240,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             description AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -237,6 +250,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="fixations-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="staticwkms"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -261,7 +275,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             description AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -270,6 +285,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="fixations-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="staticwkms"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -295,7 +311,8 @@
                       <dc:statement>
                         SELECT id       AS prot_column_id,
                                name     AS prot_column_name,
-                               position AS prot_rel_pos
+                               position AS prot_rel_pos,
+                               description AS info
                         FROM wst_columns WHERE wst_id = ${prot_id}
                         ORDER by position
                       </dc:statement>
@@ -304,6 +321,7 @@
                           <dc:attribute name="name" value="${prot_column_name}"/>
                           <dc:attribute name="ids" value="additionals-wstv-${prot_rel_pos}-${prot_id}"/>
                           <dc:attribute name="factory" value="staticwkms"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </column>
                       </dc:elements>
                     </dc:context>
@@ -328,7 +346,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             description AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -337,6 +356,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="heightmarks_points-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="staticwkms"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -361,7 +381,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             description AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -370,6 +391,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="heightmarks_points-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="staticwkms"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -394,7 +416,8 @@
                     <dc:statement>
                       SELECT id       AS prot_column_id,
                              name     AS prot_column_name,
-                             position AS prot_rel_pos
+                             position AS prot_rel_pos,
+                             description AS info
                       FROM wst_columns WHERE wst_id = ${prot_id}
                       ORDER by position
                     </dc:statement>
@@ -403,6 +426,7 @@
                         <dc:attribute name="name" value="${prot_column_name}"/>
                         <dc:attribute name="ids" value="heightmarks_annotations-wstv-${prot_rel_pos}-${prot_id}"/>
                         <dc:attribute name="factory" value="wqinterpol"/>
+                        <dc:attribute name="info" value="${info}"/>
                       </column>
                     </dc:elements>
                   </dc:context>
@@ -431,7 +455,8 @@
                       <dc:statement>
                         SELECT id       AS prot_column_id,
                                name     AS prot_column_name,
-                               position AS prot_rel_pos
+                               position AS prot_rel_pos,
+                               description AS info
                         FROM wst_columns WHERE wst_id = ${prot_id}
                         ORDER by position
                       </dc:statement>
@@ -440,6 +465,7 @@
                           <dc:attribute name="name" value="${prot_column_name}"/>
                           <dc:attribute name="ids" value="flood_protection-wstv-${prot_rel_pos}-${prot_id}"/>
                           <dc:attribute name="factory" value="staticwkms"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </column>
                       </dc:elements>
                     </dc:context>
@@ -495,6 +521,13 @@
           </mainvalue>
         </dc:macro>
 
+        <dc:macro name="qsectors">
+          <qsector>
+            <dc:attribute name="factory" value="qsectors"/>
+            <dc:attribute name="ids"     value="${river_id}"/>
+          </qsector>
+        </dc:macro>
+
         <dc:macro name="annotations">
           <annotation>
             <dc:attribute name="factory" value="annotations"/>
@@ -567,6 +600,21 @@
                  <dc:call-macro name="annotations"/>
                  <dc:call-macro name="mainvalues"/>
                </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'fix_wq_curve')">
+                 <dc:call-macro name="qsectors"/>
+               </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'fix_longitudinal_section_curve')">
+                 <dc:call-macro name="annotations"/>
+               </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'bed_difference_epoch')">
+                 <dc:call-macro name="annotations"/>
+               </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'bed_difference_year')">
+                 <dc:call-macro name="annotations"/>
+               </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'bed_difference_height_year')">
+                 <dc:call-macro name="annotations"/>
+               </dc:if>
             </dc:when>
             <dc:otherwise>
               <dc:comment>
@@ -576,6 +624,7 @@
                  <dc:call-macro name="basedata_0"/>
                  <dc:call-macro name="basedata_1_additionals"/>
                  <dc:call-macro name="basedata_2_fixations"/>
+                 <dc:call-macro name="basedata_3_officials"/>
                  <dc:call-macro name="basedata_4_heightmarks-points"/>
                  <dc:call-macro name="cross_sections"/>
                  <dc:call-macro name="hyks"/>
@@ -588,10 +637,10 @@
                  <dc:call-macro name="basedata_4_heightmarks-points"/>
                  <dc:call-macro name="basedata_5_flood-protections"/>
               </dc:if>
-              <dc:if test="dc:contains($artifact-outs, 'computed_discharge_curve')">
+              <!--dc:if test="dc:contains($artifact-outs, 'computed_discharge_curve')">
                  <dc:call-macro name="basedata_0_wq"/>
                  <dc:call-macro name="basedata_4_heightmarks-wq"/>
-              </dc:if>
+              </dc:if-->
               <dc:if test="dc:contains($artifact-outs, 'longitudinal_section') or (dc:contains($artifact-outs, 'w_differences'))">
                  <dc:call-macro name="basedata_0"/>
                  <dc:call-macro name="basedata_1_additionals"/>
@@ -601,7 +650,6 @@
                  <dc:call-macro name="basedata_4_heightmarks-points"/>
                  <dc:comment comment=" AMTL LINIEN  ---------------------------"/>
                  <dc:call-macro name="basedata_3_officials"/>
-                 <dc:call-macro name="annotations"/>
               </dc:if>
                <dc:if test="dc:contains($artifact-outs, 'reference_curve')">
                  <dc:call-macro name="annotations"/>
@@ -613,6 +661,19 @@
                  <dc:call-macro name="basedata_4_heightmarks-points-relative_points"/>
                  <dc:call-macro name="basedata_5_flood-protections_relative_points"/>
                </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'fix_wq_curve')">
+                 <dc:call-macro name="basedata_0_wq"/>
+                 <dc:call-macro name="basedata_1_additionals"/>
+                 <dc:call-macro name="basedata_2_fixations"/>
+                 <dc:call-macro name="basedata_3_officials"/>
+                 <dc:call-macro name="basedata_4_heightmarks-points"/>
+                 <dc:call-macro name="basedata_5_flood-protections_relative_points"/>
+               </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'fix_deltawt_curve')">
+               </dc:if>
+               <dc:if test="dc:contains($artifact-outs, 'fix_longitudinal_section_curve')">
+                 <dc:call-macro name="annotations"/>
+               </dc:if>
              <dc:comment comment="--- non-recommendations---"/>
             </dc:otherwise>
           </dc:choose>
@@ -701,13 +762,9 @@
 
             <!-- former flood-water-marks -->
             <dc:call-macro name="basedata_4_heightmarks-points"/>
-          </dc:if>
-          <dc:if test="dc:contains($artifact-outs, 'computed_discharge_curve')"><!-- or (dc:contains($artifact-outs, 'discharge_curve'))"-->
-              <!-- && parameter contains recommended/ation -->
               <computed_discharge_curve>
                 <dc:call-macro name="mainvalues"/>
               </computed_discharge_curve>
-              <dc:call-macro name="basedata_2_fixations_wst"/>
           </dc:if>
 
           <dc:if test="dc:contains($artifact-outs, 'duration_curve')">
@@ -724,11 +781,37 @@
             </dc:choose>
           </dc:if>
 
-          <dc:if test="dc:contains($artifact-outs, 'longitudinal_section')">
-              <longitudinal_section>
-                <dc:call-macro name="annotations"/>
-              </longitudinal_section>
+          <dc:if test="dc:contains($artifact-outs, 'fix_wq_curve') and not (dc:contains($parameters, 'recommended'))">
+              <discharge_table_nn>
+                <discharge_table_gauge>
+                  <dc:context>
+                    <dc:statement>
+                      SELECT id   AS gauge_id,
+                             name AS gauge_name
+                      FROM gauges WHERE river_id = ${river_id}
+                    </dc:statement>
+                    <dc:elements>
+                      <gauge>
+                        <dc:attribute name="name" value="${gauge_name}"/>
+                        <dc:attribute name="db-id" value="${gauge_id}"/>
+                        <dc:attribute name="factory" value="gaugedischarge"/>
+                        <dc:attribute name="from" value="${g_start}"/>
+                        <dc:attribute name="to" value="${g_stop}"/>
+                        <dc:attribute name="ids" value="${gauge_name}"/>
+                      </gauge>
+                    </dc:elements>
+                  </dc:context>
+                </discharge_table_gauge>
+              </discharge_table_nn>
           </dc:if>
+
+          <dc:if test="dc:contains($artifact-outs, 'longitudinal_section')">
+
+              <longitudinal_section>
+                <dc:call-macro name="annotations"/>
+              </longitudinal_section>
+          </dc:if>
+
           <dc:if test="dc:contains($artifact-outs, 'map')">
               <map>
               <dc:choose>
@@ -777,14 +860,17 @@
                     <dc:statement>
                       SELECT id    AS dem_id,
                              lower AS dem_lower,
-                             upper AS dem_upper
+                             upper AS dem_upper,
+                             name AS name,
+                             projection || ' | ' || year_from || ' - ' || year_to AS info
                       FROM dem WHERE river_id = ${river_id}
                     </dc:statement>
                     <dc:elements>
                         <dem>
                           <dc:attribute name="factory" value="demfactory"/>
                           <dc:attribute name="ids" value="${dem_id}"/>
-                          <dc:attribute name="description" value="${dem_lower}-${dem_upper}"/>
+                          <dc:attribute name="name" value="${name}"/>
+                          <dc:attribute name="info" value="${info}"/>
                         </dem>
                     </dc:elements>
                   </dc:context>
@@ -1146,6 +1232,58 @@
                   </rastermap>
               </dc:macro>
           </dc:if>
+          <dc:if test="dc:contains($artifact-outs, 'minfo-heights')">
+            <dc:call-macro name="minfo-heights"/>
+            <dc:macro name="minfo-heights">
+              <bedheights>
+                <dc:call-macro name="bed-heights-single"/>
+                <dc:call-macro name="bed-heights-epoch"/>
+              </bedheights>
+            </dc:macro>
+          </dc:if>
+          <dc:if test="dc:contains($artifact-outs, 'minfo-heights-epoch')">
+            <bedheights>
+              <dc:call-macro name="bed-heights-epoch"/>
+            </bedheights>
+          </dc:if>
+          <dc:macro name="bed-heights-single">
+            <single>
+              <dc:context>
+                <dc:statement>
+                    SELECT id          AS bedh_id,
+                           year        AS bedh_year,
+                           description AS bedh_descr
+                    FROM bed_height_single WHERE river_id = ${river_id}
+                </dc:statement>
+                <dc:elements>
+                  <height>
+                    <dc:attribute name="factory" value="bedheight"/>
+                    <dc:attribute name="ids" value="bedheight-single-${bedh_id}-${bedh_year}"/>
+                    <dc:attribute name="description" value="${bedh_descr}"/>
+                  </height>
+                </dc:elements>
+              </dc:context>
+            </single>
+          </dc:macro>
+          <dc:macro name="bed-heights-epoch">
+            <epoch>
+              <dc:context>
+                <dc:statement>
+                  SELECT id               AS bedh_id,
+                         time_interval_id AS bedh_interval_id,
+                         description      AS bedh_descr
+                  FROM bed_height_epoch WHERE river_id = ${river_id}
+                </dc:statement>
+                <dc:elements>
+                  <height>
+                    <dc:attribute name="factory" value="bedheight"/>
+                    <dc:attribute name="ids" value="bedheight-epoch-${bedh_id}-${bedh_interval_id}"/>
+                    <dc:attribute name="description" value="${bedh_descr}"/>
+                  </height>
+                </dc:elements>
+              </dc:context>
+            </epoch>
+          </dc:macro>
         </river>
       </dc:elements>
     </dc:context>
@@ -1204,6 +1342,7 @@
           </dc:elements>
           </officiallines>
         </dc:if>
+        <!-- END OFFICIAL LINES -->
 
         <dc:comment>
           SHOW W-DIFFERENCES
@@ -1418,6 +1557,199 @@
           </waterlevels>
         </dc:if>
 
+        <dc:if test="dc:contains($artifact-outs, 'fix_longitudinal_section_curve')">
+          <waterlevels>
+            <dc:elements>
+              <dc:context>
+                 <dc:statement>
+                   SELECT m.id AS a_id, m.state AS a_state, m.gid AS a_gid, m.creation AS a_creation
+                   FROM   master_artifacts m
+                   WHERE  m.collection_id = ${collection_id} AND m.gid &lt;&gt; CAST(${artifact-id} AS uuid)
+                   AND EXISTS (
+                       SELECT id FROM artifact_data ad WHERE ad.artifact_id = m.id AND k = 'river' AND v = ${river})
+                 </dc:statement>
+                 <dc:elements>
+
+                   <dc:context>
+                   <dc:statement>
+                     SELECT id AS out_id
+                     FROM outs
+                     WHERE artifact_id = ${a_id} AND name = 'fix_longitudinal_section_curve'
+                   </dc:statement>
+                   <dc:elements>
+                     <dc:context>
+                     <!-- average und deviation ls_0 . ls_1 ...-->
+                       <dc:statement>
+                         SELECT name AS facet_name, num as facet_num, description AS facet_description
+                         FROM facets
+                         WHERE out_id = ${out_id} AND ( name LIKE 'fix_deviation_ls%' OR name LIKE 'fix_sector_average_ls%' OR name LIKE 'fix_analysis_events_ls%' OR name LIKE 'fix_reference_events_ls%' )
+                         ORDER BY num ASC, name DESC
+                       </dc:statement>
+                       <waterlevels>
+                         <dc:attribute name="description" value="${river} ${a_creation} ${collection_name}"/>
+                         <dc:elements>
+                           <dc:element name="${facet_name}">
+                             <dc:attribute name="description" value="${facet_description}"/>
+                             <dc:attribute name="ids"         value="${facet_num}"/>
+                             <dc:attribute name="factory"     value="fixanalysis"/>
+                             <dc:attribute name="artifact-id" value="${a_gid}"/>
+                             <dc:attribute name="out"         value="fix_longitudinal_section_curve"/>
+                           </dc:element>
+                         </dc:elements>
+                       </waterlevels>
+                     </dc:context>
+                   </dc:elements>
+                  </dc:context>
+                 </dc:elements>
+                </dc:context>
+             </dc:elements>
+          </waterlevels>
+        </dc:if>
+
+        <dc:if test="dc:contains($artifact-outs, 'fix_deltawt_curve')">
+          <waterlevels>
+            <dc:elements>
+              <dc:context>
+                 <dc:statement>
+                   SELECT m.id AS a_id, m.state AS a_state, m.gid AS a_gid, m.creation AS a_creation
+                   FROM   master_artifacts m
+                   WHERE  m.collection_id = ${collection_id} AND m.gid &lt;&gt; CAST(${artifact-id} AS uuid)
+                   AND EXISTS (
+                       SELECT id FROM artifact_data ad WHERE ad.artifact_id = m.id AND k = 'river' AND v = ${river})
+                 </dc:statement>
+                 <dc:elements>
+
+                   <dc:context>
+                   <dc:statement>
+                     SELECT id AS out_id
+                     FROM outs
+                     WHERE artifact_id = ${a_id} AND name = 'fix_deltawt_curve'
+                   </dc:statement>
+                   <dc:elements>
+                     <dc:context>
+                       <dc:statement>
+                         SELECT name AS facet_name, num as facet_num, description AS facet_description
+                         FROM facets
+                         WHERE out_id = ${out_id} and ( name LIKE 'fix_sector_average_dwt%' OR name LIKE 'fix_deviation_dwt%' OR name = 'fix_analysis_events_dwt' OR name = 'fix_reference_events_dwt' OR name = 'fix_analysis_periods_dwt' )
+                         ORDER BY num ASC, name DESC
+                       </dc:statement>
+                       <waterlevels>
+                         <dc:attribute name="description" value="${river} ${a_creation} ${collection_name}"/>
+                         <dc:elements>
+                           <dc:element name="${facet_name}">
+                             <dc:attribute name="description" value="${facet_description}"/>
+                             <dc:attribute name="ids"         value="${facet_num}"/>
+                             <dc:attribute name="factory"     value="fixanalysis"/>
+                             <dc:attribute name="artifact-id" value="${a_gid}"/>
+                             <dc:attribute name="out"         value="fix_deltawt_curve"/>
+                           </dc:element>
+                         </dc:elements>
+                       </waterlevels>
+                     </dc:context>
+                   </dc:elements>
+                  </dc:context>
+                 </dc:elements>
+                </dc:context>
+             </dc:elements>
+          </waterlevels>
+        </dc:if>
+
+        <dc:if test="dc:contains($artifact-outs, 'fix_derivate_curve')">
+          <waterlevels>
+            <dc:elements>
+              <dc:context>
+                 <dc:statement>
+                   SELECT m.id AS a_id, m.state AS a_state, m.gid AS a_gid, m.creation AS a_creation
+                   FROM   master_artifacts m
+                   WHERE  m.collection_id = ${collection_id} AND m.gid &lt;&gt; CAST(${artifact-id} AS uuid)
+                   AND EXISTS (
+                       SELECT id FROM artifact_data ad WHERE ad.artifact_id = m.id AND k = 'river' AND v = ${river})
+                 </dc:statement>
+                 <dc:elements>
+
+                   <dc:context>
+                   <dc:statement>
+                     SELECT id AS out_id
+                     FROM outs
+                     WHERE artifact_id = ${a_id} AND name = 'fix_derivate_curve'
+                   </dc:statement>
+                   <dc:elements>
+                     <dc:context>
+                       <dc:statement>
+                         SELECT name AS facet_name, num as facet_num, description AS facet_description
+                         FROM facets
+                         WHERE out_id = ${out_id} and name = 'fix_derivate'
+                         ORDER BY num ASC, name DESC
+                       </dc:statement>
+                       <waterlevels>
+                         <dc:attribute name="description" value="${river} ${a_creation} ${collection_name}"/>
+                         <dc:elements>
+                           <dc:element name="${facet_name}">
+                             <dc:attribute name="description" value="${facet_description}"/>
+                             <dc:attribute name="ids"         value="${facet_num}"/>
+                             <dc:attribute name="factory"     value="fixanalysis"/>
+                             <dc:attribute name="artifact-id" value="${a_gid}"/>
+                             <dc:attribute name="out"         value="fix_derivate_curve"/>
+                           </dc:element>
+                         </dc:elements>
+                       </waterlevels>
+                     </dc:context>
+                   </dc:elements>
+                  </dc:context>
+                 </dc:elements>
+                </dc:context>
+             </dc:elements>
+          </waterlevels>
+        </dc:if>
+
+        <dc:if test="dc:contains($artifact-outs, 'fix_wq_curve')">
+          <waterlevels>
+            <dc:elements>
+              <dc:context>
+                 <dc:statement>
+                   SELECT m.id AS a_id, m.state AS a_state, m.gid AS a_gid, m.creation AS a_creation
+                   FROM   master_artifacts m
+                   WHERE  m.collection_id = ${collection_id} AND m.gid &lt;&gt; CAST(${artifact-id} AS uuid)
+                   AND EXISTS (
+                       SELECT id FROM artifact_data ad WHERE ad.artifact_id = m.id AND k = 'river' AND v = ${river})
+                 </dc:statement>
+                 <dc:elements>
+
+                   <dc:context>
+                   <dc:statement>
+                     SELECT id AS out_id
+                     FROM outs
+                     WHERE artifact_id = ${a_id} AND name = 'fix_wq_curve'
+                   </dc:statement>
+                   <dc:elements>
+                     <dc:context>
+                       <dc:statement>
+                         SELECT name AS facet_name, num as facet_num, description AS facet_description
+                         FROM facets
+                         WHERE out_id = ${out_id} and ( name LIKE 'fix_sector_average_wq%' OR name = 'fix_wq_curve' OR name LIKE 'fix_analysis_events_wq%' OR name LIKE 'fix_reference_events_wq%' )
+                         ORDER BY num ASC, name DESC
+                       </dc:statement>
+                       <waterlevels>
+                         <dc:attribute name="description" value="${river} ${a_creation} ${collection_name}"/>
+                         <dc:elements>
+                           <dc:element name="${facet_name}">
+                             <dc:attribute name="description" value="${facet_description}"/>
+                             <dc:attribute name="ids"         value="${facet_num}"/>
+                             <dc:attribute name="factory"     value="fixanalysis"/>
+                             <dc:attribute name="artifact-id" value="${a_gid}"/>
+                             <dc:attribute name="out"         value="fix_wq_curve"/>
+                           </dc:element>
+                         </dc:elements>
+                       </waterlevels>
+                     </dc:context>
+                   </dc:elements>
+                  </dc:context>
+                 </dc:elements>
+                </dc:context>
+             </dc:elements>
+          </waterlevels>
+        </dc:if>
+
         <dc:if test="dc:contains($artifact-outs, 'duration_curve')">
           <computed_discharge_curves>
             <dc:elements>
@@ -1455,7 +1787,8 @@
            WATERLEVELS - ONLY SHOW Ws
         </dc:comment>
 
-        <dc:if test="dc:contains($artifact-outs, 'waterlevels')">
+        <!-- TODO doesnt work nicely for fix/wq-diags. -->
+        <dc:if test="dc:contains($artifact-outs, 'waterlevels') or (dc:contains($artifact-outs, 'fix_wq_curve'))"> 
           <waterlevels>
             <dc:elements>
               <dc:context>
--- a/flys-artifacts/doc/conf/second-themes.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/second-themes.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -7,9 +7,9 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 153" />
+                default="153, 0, 153" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="2" hints="h" />
+                default="1" hints="h" />
         </fields>
     </theme>
 
@@ -21,9 +21,9 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 153" />
+                default="153, 0, 153" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="2" hints="h" />
+                default="1" hints="h" />
         </fields>
     </theme>
 
@@ -34,9 +34,9 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="0, 204, 204" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="2" hints="h" />
+                default="1" hints="h" />
         </fields>
     </theme>
 
@@ -48,8 +48,13 @@
             <inherit from="MinMaxPoints" />
         </inherits>
         <fields>
+            <field name="bandwidth" type="double" display="Bandbreite"
+                default="0"/>
+            <field name="fillcolor" type="Color" display="Bandbreitenfarbe"
+                default="104, 104, 104"/> 
+    	    <field name="transparency" type="int" default="30" display="Transparenz"/>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -59,7 +64,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="102, 0, 102" />
         </fields>
     </theme>
 
@@ -69,7 +74,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="102, 0, 102" />
         </fields>
     </theme>
 
@@ -79,7 +84,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 153, 51" />
+                default="51, 153, 51" />
         </fields>
     </theme>
 
@@ -89,7 +94,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -99,7 +104,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="153, 153, 0" />
+                default="153, 0, 153" />
         </fields>
     </theme>
 
@@ -109,7 +114,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 51, 0" />
+                default="102, 0, 51" />
         </fields>
     </theme>
 
@@ -119,7 +124,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 153, 0" />
+                default="255, 153, 255" />
         </fields>
     </theme>
 
@@ -129,7 +134,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0, 255" />
+                default="255, 128, 255" />
         </fields>
     </theme>
 
@@ -139,7 +144,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0, 255" />
+                default="255, 128, 255" />
         </fields>
     </theme>
 
@@ -149,7 +154,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 0, 102" />
+                default="102, 128, 102" />
         </fields>
     </theme>
 
@@ -159,7 +164,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="0, 128, 0" />
         </fields>
     </theme>
 
@@ -169,7 +174,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 0, 102" />
+                default="102, 128, 102" />
         </fields>
     </theme>
 
@@ -179,7 +184,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="253, 153, 0" />
+                default="253, 153, 128" />
         </fields>
     </theme>
 
@@ -189,7 +194,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 255, 102" />
+                default="102, 0, 102" />
         </fields>
     </theme>
 
@@ -199,7 +204,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 255, 255" />
+                default="255, 0, 255" />
         </fields>
     </theme>
 
@@ -209,7 +214,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 51, 204" />
+                default="204, 51, 204" />
         </fields>
     </theme>
 
@@ -219,7 +224,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="153, 204, 255" />
+                default="153, 204, 0" />
         </fields>
     </theme>
 
@@ -229,7 +234,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="0, 255, 0" />
         </fields>
     </theme>
 
@@ -251,7 +256,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="64, 0, 102" />
         </fields>
     </theme>
 
@@ -261,7 +266,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="64, 0, 102" />
         </fields>
     </theme>
 
@@ -271,7 +276,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 153, 51" />
+                default="64, 153, 51" />
         </fields>
     </theme>
 
@@ -281,7 +286,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 204, 204" />
+                default="64, 204, 204" />
         </fields>
     </theme>
 
@@ -291,7 +296,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="153, 153, 0" />
+                default="153, 153, 64" />
         </fields>
     </theme>
 
@@ -301,7 +306,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 51, 0" />
+                default="102, 51, 64" />
         </fields>
     </theme>
 
@@ -311,7 +316,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 153, 153" />
+                default="255, 0, 153" />
         </fields>
     </theme>
 
@@ -321,7 +326,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0, 51" />
+                default="255, 10, 0" />
         </fields>
     </theme>
 
@@ -331,7 +336,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0, 255" />
+                default="255, 64, 255" />
         </fields>
     </theme>
 
@@ -341,7 +346,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 0, 102" />
+                default="102, 64, 102" />
         </fields>
     </theme>
 
@@ -351,7 +356,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="0, 0, 255" />
         </fields>
     </theme>
 
@@ -361,7 +366,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 0, 102" />
+                default="102, 64, 102" />
         </fields>
     </theme>
 
@@ -371,7 +376,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="253, 153, 0" />
+                default="253, 153, 64" />
         </fields>
     </theme>
 
@@ -381,7 +386,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 255, 102" />
+                default="102, 128, 102" />
         </fields>
     </theme>
 
@@ -391,7 +396,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 255, 255" />
+                default="0, 255, 0" />
         </fields>
     </theme>
 
@@ -401,7 +406,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 51, 204" />
+                default="64, 51, 178" />
         </fields>
     </theme>
 
@@ -411,7 +416,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="153, 204, 255" />
+                default="153, 0, 255" />
         </fields>
     </theme>
 
@@ -421,7 +426,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="0, 64, 0" />
         </fields>
     </theme>
 
@@ -434,7 +439,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 64, 204" />
         </fields>
     </theme>
 
@@ -444,7 +449,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="102, 0, 102" />
         </fields>
     </theme>
 
@@ -454,7 +459,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="102, 0, 102" />
         </fields>
     </theme>
 
@@ -464,7 +469,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 153, 51" />
+                default="102, 153, 51" />
         </fields>
     </theme>
 
@@ -474,7 +479,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -484,7 +489,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="153, 153, 0" />
+                default="153, 0, 153" />
         </fields>
     </theme>
 
@@ -494,7 +499,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 51, 0" />
+                default="102, 51, 102" />
         </fields>
     </theme>
 
@@ -504,7 +509,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 153, 153" />
+                default="255, 0, 153" />
         </fields>
     </theme>
 
@@ -514,7 +519,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0, 51" />
+                default="255, 50, 51" />
         </fields>
     </theme>
 
@@ -524,7 +529,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0, 255" />
+                default="255, 255, 0" />
         </fields>
     </theme>
 
@@ -534,7 +539,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 0, 102" />
+                default="102, 102, 64" />
         </fields>
     </theme>
 
@@ -544,7 +549,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="0, 102, 0" />
         </fields>
     </theme>
 
@@ -554,7 +559,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 0, 102" />
+                default="102, 102, 0" />
         </fields>
     </theme>
 
@@ -564,7 +569,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="253, 153, 0" />
+                default="253, 153, 102" />
         </fields>
     </theme>
 
@@ -574,7 +579,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="102, 255, 102" />
+                default="102, 0, 102" />
         </fields>
     </theme>
 
@@ -584,7 +589,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 255, 255" />
+                default="0, 0, 255" />
         </fields>
     </theme>
 
@@ -594,7 +599,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 51, 204" />
+                default="55, 51, 204" />
         </fields>
     </theme>
 
@@ -604,7 +609,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="153, 204, 255" />
+                default="153, 204, 0" />
         </fields>
     </theme>
 
@@ -614,7 +619,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="0, 128, 0" />
         </fields>
     </theme>
 
@@ -626,7 +631,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Farbe"
-                default="200, 0, 15" />
+                default="200, 64, 0" />
             <field name="textcolor" type="Color" display="Farbe"
                 default="200, 0, 15" />
             <field name="showhorizontalline" type="boolean"
@@ -645,7 +650,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Farbe"
-                default="0, 215, 0" />
+                default="0, 0, 215" />
             <field name="textcolor" type="Color" display="Farbe"
                 default="0, 215, 0" />
             <field name="showhorizontalline" type="boolean"
@@ -667,7 +672,7 @@
             <field name="linecolor" type="Color" display="Linienfarbe"
                 default="0, 0, 153" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="2" hints="h" />
+                default="4" hints="h" />
         </fields>
     </theme>
 
@@ -679,7 +684,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Farbe"
-                default="200, 0, 15" />
+                default="200, 255, 15" />
             <field name="textcolor" type="Color" display="Farbe"
                 default="200, 0, 15" />
         </fields>
@@ -693,7 +698,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Farbe"
-                default="0, 215, 0" />
+                default="0, 215, 128" />
             <field name="textcolor" type="Color" display="Farbe"
                 default="0, 215, 0" />
             <field name="textorientation" type="boolean" display="Textausrichtung"
@@ -711,7 +716,7 @@
             <field name="linecolor" type="Color" display="Linienfarbe"
                 default="0,0,0" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="1" hints="h" />
+                default="3" hints="h" />
         </fields>
     </theme>
 
@@ -721,13 +726,15 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0,0,153" />
+                default="255,0,153" />
             <field name="linesize" type="int" display="Liniendicke"
                 default="1" hints="h" />
             <field name="showwidth" type="boolean" display="Breite anzeigen"
                 default="false" />
             <field name="showlevel" type="boolean" display="Wasserstand anzeigen"
-                default="false" />
+                default="true" />
+            <field name="showlinelabel" type="boolean" default="true"
+                display="Beschriftung anzeigen" />
             <field name="showmiddleheight" type="boolean"
                 display="Wasserstand anzeigen" default="false" />
         </fields>
@@ -748,7 +755,7 @@
         <inherits>
             <inherit from="LongitudinalSectionPoints" />
         </inherits>
-        <!--fields> <field name="linecolor" type="Color" display="Linienfarbe" 
+        <!--fields> <field name="linecolor" type="Color" display="Linienfarbe"
             default="0, 0, 0"/> </fields -->
     </theme>
 
@@ -762,7 +769,7 @@
             <field name="linecolor" type="Color" display="Linienfarbe"
                 default="0,51,204" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="2" hints="h" />
+                default="1" hints="h" />
         </fields>
     </theme>
 
@@ -775,7 +782,7 @@
             <field name="linecolor" type="Color" display="Linienfarbe"
                 default="0,204,0" />
             <field name="linesize" type="int" display="Liniendicke"
-                default="2" hints="h" />
+                default="1" hints="h" />
         </fields>
     </theme>
 
@@ -787,7 +794,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -799,7 +806,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -810,7 +817,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -822,7 +829,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -833,7 +840,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -847,7 +854,7 @@
             <field name="showpoints" type="boolean" display="Punkte anzeigen"
                 default="true" />
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 0, 0" />
+                default="204, 0, 200" />
         </fields>
     </theme>
 
@@ -859,7 +866,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -871,7 +878,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="255, 0 , 0" />
+                default="255, 0 , 255" />
         </fields>
     </theme>
 
@@ -882,7 +889,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -896,7 +903,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="99, 99, 99" />
         </fields>
     </theme>
 
@@ -907,7 +914,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="250, 0, 0" />
+                default="250, 255, 0" />
             <field name="font" type="Font" display="Schriftart"
                 default="arial" />
             <field name="textcolor" type="Color" display="Schriftfarbe"
@@ -917,9 +924,9 @@
             <field name="textstyle" type="Style" display="Schriftstil"
                 default="standard" />
             <field name="pointsize" type="int" display="Punktdicke"
-                default="3" hints="h" />
+                default="2" hints="h" />
             <field name="backgroundcolor" type="Color" display="Texthintergrund"
-                default="255, 255, 255" />
+                default="55, 55, 55" />
             <field name="textorientation" type="boolean" display="Textausrichtung"
                 default="true" />
             <field name="showbackground" type="boolean"
@@ -934,7 +941,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 0" />
+                default="330, 33, 33" />
         </fields>
     </theme>
 
@@ -943,6 +950,10 @@
         <inherits>
             <inherit from="Areas" />
         </inherits>
+        <fields>
+            <field name="showarea" type="boolean" display="Show Area"
+                default="true"/>
+        </fields>
     </theme>
 
     <!-- Map -->
@@ -1041,7 +1052,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="128, 128, 128" />
         </fields>
     </theme>
 
@@ -1051,7 +1062,153 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="64, 0, 102" />
+        </fields>
+    </theme>
+    
+    <!-- Bedheight differences -->
+    <theme name="BedheightDiffYear">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="0, 204, 204" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffMorphWidth">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="0, 204, 0" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffEpoch">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 0, 0" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffAbsHeight1">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 0, 0" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffAbsHeight2">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="100, 255, 100" />
+        </fields>
+    </theme>
+
+    <theme name="BedheightDiffHeightYear">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+            <inherit from="MinMaxPoints" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="204, 0, 100" />
+        </fields>
+    </theme>
+
+
+    <!-- Bed Quality -->
+    <theme name="PorosityTopLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="100, 100, 100" />
+        </fields>
+    </theme>
+    
+    <theme name="PorositySubLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="100, 100, 100" />
+        </fields>
+    </theme>
+    
+    <theme name="DensityTopLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#990000" />
+        </fields>
+    </theme>
+    
+    <theme name="DensitySubLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#990000" />
+        </fields>
+    </theme>
+    
+    <theme name="BedDiameterTopLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#FF4444" />
+        </fields>
+    </theme>
+    
+    <theme name="BedDiameterSubLayer">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#FF4444" />
+        </fields>
+    </theme>
+    
+    <theme name="BedLoadDiameter">
+    	<inherits>
+    		<inherit from="HiddenColorLines" />
+    		<inherit from="MinMaxPoints" />
+    	</inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="#33FF11" />
         </fields>
     </theme>
 
@@ -1064,7 +1221,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="204, 204, 204" />
+                default="204, 0, 204" />
         </fields>
     </theme>
 
@@ -1074,7 +1231,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 0, 102" />
+                default="64, 0, 102" />
         </fields>
     </theme>
 
@@ -1085,7 +1242,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" display="Linienfarbe"
-                default="0, 204, 204" />
+                default="0, 204, 0" />
         </fields>
     </theme>
 
@@ -1098,7 +1255,7 @@
         <fields>
             <field name="showlines" type="boolean" display="Linie anzeigen"
                 default="false" hidden="true" />
-            <field name="pointcolor" type="Color" default="#0099FF" />
+            <field name="pointcolor" type="Color" default="0, 99, 255" />
         </fields>
     </theme>
 
@@ -1109,7 +1266,7 @@
         <fields>
             <field name="showlines" type="boolean" display="Linie anzeigen"
                 default="false" hidden="true" />
-            <field name="pointcolor" type="Color" default="#CC0000" />
+            <field name="pointcolor" type="Color" default="0, 99, 0" />
         </fields>
     </theme>
 
@@ -1119,6 +1276,7 @@
         </inherits>
         <fields>
             <field name="linecolor" type="Color" default="#000000" />
+            <field name="linesize" type="int" default="3" />
         </fields>
     </theme>
 
@@ -1127,7 +1285,20 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="227, 27, 162" />
+            <field name="linecolor" type="Color" default="0, 27, 162" />
+        </fields>
+    </theme>
+
+    <theme name="FixingDerivedCurve">
+        <inherits>
+            <inherit from="HiddenColorLines" />
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" default="0, 27, 162" />
+            <field name="showpoints" type="boolean" display="Datenpunkte anzeigen"
+                default="false" hints="h" hidden="true" />
+            <field name="pointsize" type="int" display="Punktdicke"
+                default="5" hints="h" hidden="true" />
         </fields>
     </theme>
 
@@ -1142,9 +1313,9 @@
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 128, 0" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+                default="0, 128, 128" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
         </fields>
     </theme>
     <theme name="FixingSectorAverageWQ1">
@@ -1158,9 +1329,9 @@
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 0, 255" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+                default="0, 64, 255" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
         </fields>
     </theme>
     <theme name="FixingSectorAverageWQ2">
@@ -1172,11 +1343,11 @@
                 display="Beschriftung anzeigen" default="false" hints="h" />
             <field name="showlines" type="boolean" default="false" />
             <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
+                default="2" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="255, 0, 255" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
         </fields>
     </theme>
     <theme name="FixingSectorAverageWQ3">
@@ -1190,9 +1361,9 @@
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="255, 0, 0" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+                default="255, 0, 255" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
         </fields>
     </theme>
 
@@ -1201,32 +1372,35 @@
             <inherit from="ColorPoints" />
         </inherits>
         <fields>
-            <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
             <field name="showlines" type="boolean" default="false" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 255, 0" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+                default="0, 255, 255" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
         </fields>
     </theme>
 
-    <theme name="FixingReferenceEventsWQ">
+    <theme name="FixingReferenceEvents">
         <inherits>
             <inherit from="ColorPoints" />
         </inherits>
         <fields>
-            <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="showlines" type="boolean" default="false" />
+            <field name="showlines" type="boolean" default="false"
+                hidden="true" />
+            <field name="showlinelabel" type="boolean" default="false"
+                hidden="true" />
+            <field name="linetype" type="Dash" display="Linienart"
+                default="10" hidden="true" />
+            <field name="linesize" type="int" display="Liniendicke"
+                default="2" hidden="true" />
             <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
+                default="4" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 80, 160" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+                default="0, 80, 255" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="true"/>
         </fields>
     </theme>
 
@@ -1235,62 +1409,65 @@
             <inherit from="ColorPoints" />
         </inherits>
         <fields>
-            <field name="showlines" type="boolean" default="false" />
-            <field name="textorientation" type="boolean" display="Textausrichtung"
-                default="true" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
         </fields>
     </theme>
 
     <theme name="FixingDeltaWtAverage0">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="0, 128, 128" />
+            <field name="linesize" type="int" display="Liniendicke"
                 default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 128, 0" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
     <theme name="FixingDeltaWtAverage1">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="128, 0, 255" />
+            <field name="linesize" type="int" display="Liniendicke"
                 default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 0, 255" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
     <theme name="FixingDeltaWtAverage2">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="255, 128, 255" />
+            <field name="linesize" type="int" display="Liniendicke"
                 default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="255, 0, 255" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
     <theme name="FixingDeltaWtAverage3">
         <inherits>
-            <inherit from="ColorPoints" />
+            <inherit from="ColorLines" />
         </inherits>
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="pointsize" type="int" display="Punktdicke"
+                display="Beschriftung anzeigen" default="true" hints="h" />
+            <field name="linecolor" type="Color" display="Linienfarbe"
+                default="255, 0, 0" />
+            <field name="linesize" type="int" display="Liniendicke"
                 default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="255, 0, 0" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
 
@@ -1302,26 +1479,14 @@
         <fields>
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="true" />
             <field name="showlines" type="boolean" default="false" />
             <field name="pointsize" type="int" display="Punktdicke"
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="0, 255, 0" />
-        </fields>
-    </theme>
-
-    <theme name="FixingDeltaWtReference">
-        <inherits>
-            <inherit from="ColorPoints" />
-        </inherits>
-        <fields>
-            <field name="showlinelabel" type="boolean"
-                display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="showlines" type="boolean" default="false" />
-            <field name="pointsize" type="int" display="Punktdicke"
-                default="3" />
-            <field name="pointcolor" type="Color" display="Punktfarbe"
-                default="0, 80, 160" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
 
@@ -1330,7 +1495,7 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="0, 128, 0" />
+            <field name="linecolor" type="Color" default="0, 128, 64" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
         </fields>
@@ -1340,7 +1505,7 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="0, 0, 255" />
+            <field name="linecolor" type="Color" default="0, 64, 255" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
         </fields>
@@ -1350,7 +1515,7 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="255, 0, 255" />
+            <field name="linecolor" type="Color" default="255, 64, 255" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
         </fields>
@@ -1360,7 +1525,7 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="255, 0, 0" />
+            <field name="linecolor" type="Color" default="255, 0, 64" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
         </fields>
@@ -1371,10 +1536,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
-                default="0, 128, 0" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
+                default="0, 128, 64" />
         </fields>
     </theme>
     <theme name="FixingSectorDeviationLS1">
@@ -1382,10 +1545,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
-                default="0, 0, 255" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
+                default="64, 0, 255" />
         </fields>
     </theme>
     <theme name="FixingSectorDeviationLS2">
@@ -1393,10 +1554,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
-                default="255, 0, 255" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
+                default="255, 64, 255" />
         </fields>
     </theme>
     <theme name="FixingSectorDeviationLS3">
@@ -1404,10 +1563,8 @@
             <inherit from="Areas" />
         </inherits>
         <fields>
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
-                default="255, 0, 0" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="true" />
+            <field name="backgroundcolor" type="Color" display="Fuellfarbe"
+                default="255, 64, 0" />
         </fields>
     </theme>
     <theme name="FixLSDeviation">
@@ -1416,7 +1573,7 @@
         </inherits>
         <fields>
             <field name="fillcolor" type="Color" display="Fuellfarbe"
-                default="100, 100, 100" />
+                default="200, 200, 200" />
             <field name="transparent" type="boolean" display="Transparenz"
                 default="true" />
         </fields>
@@ -1426,7 +1583,7 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="0, 255, 0" />
+            <field name="linecolor" type="Color" default="0, 0, 255" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
         </fields>
@@ -1436,26 +1593,18 @@
             <inherit from="HiddenColorLines" />
         </inherits>
         <fields>
-            <field name="linecolor" type="Color" default="0, 80, 160" />
+            <field name="linecolor" type="Color" default="160, 80, 160" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
         </fields>
     </theme>
-    <theme name="FixingDerivedCurve">
-        <inherits>
-            <inherit from="HiddenColorLines" />
-        </inherits>
-        <fields>
-            <field name="linecolor" type="Color" default="227, 27, 162" />
-        </fields>
-    </theme>
     <theme name="FixDeltaWtDeviation">
     	<inherits>
     		<inherit from="Areas"/>
     	</inherits>
     	<fields>
-    		<field name="alpha" type="int" default="50" disply="Alpha-Transparenz"/>
-    		<field name="fillcolor" type="Color" default="0, 0, 0" display="Füllfarbe"/>
+    		<field name="transparency" type="int" default="30" display="Transparenz"/>
+    		<field name="backgroundcolor" type="Color" default="0, 0, 0" display="Füllfarbe"/>
     	</fields>
     </theme>
     <theme name="FixingDeltaWtAnalysisPeriods">
@@ -1463,10 +1612,38 @@
     		<inherit from="Areas"/>
     	</inherits>
     	<fields>
-    		<field name="alpha" type="int" default="80" disply="Alpha-Transparenz"/>
-    		<field name="fillcolor" type="Color" default="255, 0, 0" display="Hauptfarbe"/>
-    		<field name="backgroundcolor" type="Color" default="0, 0, 255" display="Wechselfarbe"/>
+    		<field name="transparency" type="int" default="90" display="Transparenz"/>
+    	</fields>
+    </theme>
+    
+    <theme name="FixingReferencePeriod">
+        <inherits>
+    		<inherit from="Areas"/>
+    	</inherits>
+    	<fields>
+    		<field name="transparency" type="int" default="70" display="Transparenz"/>
+            <field name="backgroundcolor" type="Color" default="0, 128, 200" display="Füllfarbe" />
     	</fields>
     </theme>
 
+    <theme name="QSectors">
+        <fields>
+            <field name="linecolor" type="Color" default="32, 27, 162" />
+            <field name="showlinelabel" type="boolean"
+                display="Beschriftung anzeigen" default="false" hints="h" />
+            <field name="linetype" type="Dash" display="Linienart"
+                default="10" hidden="true" />
+            <field name="linesize" type="int" display="Liniendicke"
+                default="2" hidden="true" />
+            <field name="labelfontface" type="Font"
+                display="Beschriftung: Schriftart" default="arial" />
+            <field name="labelfontcolor" type="Color"
+                display="Beschriftung: Schriftfarbe" default="0, 0, 0" />
+            <field name="labelfontsize" type="int"
+                display="Beschriftung: Schriftgröße" default="9" />
+            <field name="labelfontstyle" type="Style"
+                display="Beschriftung: Schriftstil" default="standard" />
+        </fields>
+    </theme>
+
 </themegroup>
--- a/flys-artifacts/doc/conf/themes.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/themes.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -9,179 +9,262 @@
     &second-themes;
     &virtual-themes;
 
-    <!--
-      Mappings are following now. A mapping maps between a name of a facet
-      and a theme.
-      Always the first matching mapping is taken, so consider putting most
-      specific mappings on top of the list.
-    -->
-    <mappings>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ1)(\D.*)*" to="LongitudinalSectionW_HQ1_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ2)(\D.*)*" to="LongitudinalSectionW_HQ2_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ5)(\D.*)*" to="LongitudinalSectionW_HQ5_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ10)(\D.*)*" to="LongitudinalSectionW_HQ10_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ20)(\D.*)*" to="LongitudinalSectionW_HQ20_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ25)(\D.*)*" to="LongitudinalSectionW_HQ25_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ50)(\D.*)*" to="LongitudinalSectionW_HQ50_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ100)(\D.*)*" to="LongitudinalSectionW_HQ100_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ200)(\D.*)*" to="LongitudinalSectionW_HQ200_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ500)(\D.*)*" to="LongitudinalSectionW_HQ500_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQ1000)(\D.*)*" to="LongitudinalSectionW_HQ1000_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQExtrem)(\D.*)*" to="LongitudinalSectionW_HQExtrem_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HQRZ)(\D.*)*" to="LongitudinalSectionW_HQRZ_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(HSQ)(\D.*)*" to="LongitudinalSectionW_HSQ_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(MHQ)(\D.*)*" to="LongitudinalSectionW_MHQ_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(MNQ)(\D.*)*" to="LongitudinalSectionW_MNQ_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(MQ)(\D.*)*" to="LongitudinalSectionW_MQ_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" pattern=".*(NQ)(\D.*)*" to="LongitudinalSectionW_NQ_Points"/>
-        <mapping from="longitudinal_section.w" masterAttr="ld_mode==location" to="LongitudinalSectionPoints"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ1)(\D.*)*" to="LongitudinalSectionW_HQ1"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ2)(\D.*)*" to="LongitudinalSectionW_HQ2"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ5)(\D.*)*" to="LongitudinalSectionW_HQ5"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ10)(\D.*)*" to="LongitudinalSectionW_HQ10"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ20)(\D.*)*" to="LongitudinalSectionW_HQ20"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ25)(\D.*)*" to="LongitudinalSectionW_HQ25"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ50)(\D.*)*" to="LongitudinalSectionW_HQ50"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ100)(\D.*)*" to="LongitudinalSectionW_HQ100"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ200)(\D.*)*" to="LongitudinalSectionW_HQ200"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ500)(\D.*)*" to="LongitudinalSectionW_HQ500"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQ1000)(\D.*)*" to="LongitudinalSectionW_HQ1000"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQExtrem)(\D.*)*" to="LongitudinalSectionW_HQExtrem"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HQRZ)(\D.*)*" to="LongitudinalSectionW_HQRZ"/>
-        <mapping from="longitudinal_section.w" pattern=".*(HSQ)(\D.*)*" to="LongitudinalSectionW_HSQ"/>
-        <mapping from="longitudinal_section.w" pattern=".*(MHQ)(\D.*)*" to="LongitudinalSectionW_MHQ"/>
-        <mapping from="longitudinal_section.w" pattern=".*(MNQ)(\D.*)*" to="LongitudinalSectionW_MNQ"/>
-        <mapping from="longitudinal_section.w" pattern=".*(MQ)(\D.*)*" to="LongitudinalSectionW_MQ"/>
-        <mapping from="longitudinal_section.w" pattern=".*(NQ)(\D.*)*" to="LongitudinalSectionW_NQ"/>
-        <mapping from="longitudinal_section.w" to="LongitudinalSectionW"/>
-
-        <mapping from="longitudinal_section.q" pattern="(HQ1)(\D.*)*" to="LongitudinalSectionQ_HQ1"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ2)(\D.*)*" to="LongitudinalSectionQ_HQ2"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ5)(\D.*)*" to="LongitudinalSectionQ_HQ5"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ10)(\D.*)*" to="LongitudinalSectionQ_HQ10"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ20)(\D.*)*" to="LongitudinalSectionQ_HQ20"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ25)(\D.*)*" to="LongitudinalSectionQ_HQ25"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ50)(\D.*)*" to="LongitudinalSectionQ_HQ50"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ100)(\D.*)*" to="LongitudinalSectionQ_HQ100"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ200)(\D.*)*" to="LongitudinalSectionQ_HQ200"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ500)(\D.*)*" to="LongitudinalSectionQ_HQ500"/>
-        <mapping from="longitudinal_section.q" pattern="(HQ1000)(\D.*)*" to="LongitudinalSectionQ_HQ1000"/>
-        <mapping from="longitudinal_section.q" pattern="(HQExtrem)(\D.*)*" to="LongitudinalSectionQ_HQExtrem"/>
-        <mapping from="longitudinal_section.q" pattern="(HQRZ)(\D.*)*" to="LongitudinalSectionQ_HQRZ"/>
-        <mapping from="longitudinal_section.q" pattern="(HSQ)(\D.*)*" to="LongitudinalSectionQ_HSQ"/>
-        <mapping from="longitudinal_section.q" pattern="(MHQ)(\D.*)*" to="LongitudinalSectionQ_MHQ"/>
-        <mapping from="longitudinal_section.q" pattern="(MNQ)(\D.*)*" to="LongitudinalSectionQ_MNQ"/>
-        <mapping from="longitudinal_section.q" pattern="(MQ)(\D.*)*" to="LongitudinalSectionQ_MQ"/>
-        <mapping from="longitudinal_section.q" pattern="(NQ)(\D.*)*" to="LongitudinalSectionQ_NQ"/>
-        <mapping from="longitudinal_section.q" to="LongitudinalSectionQ"/>
+	<!-- Mappings are following now. A mapping maps between a name of a facet 
+		and a theme. Always the first matching mapping is taken, so consider putting 
+		most specific mappings on top of the list. -->
+	<mappings>
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ1)(\D.*)*" to="LongitudinalSectionW_HQ1_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ2)(\D.*)*" to="LongitudinalSectionW_HQ2_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ5)(\D.*)*" to="LongitudinalSectionW_HQ5_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ10)(\D.*)*" to="LongitudinalSectionW_HQ10_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ20)(\D.*)*" to="LongitudinalSectionW_HQ20_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ25)(\D.*)*" to="LongitudinalSectionW_HQ25_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ50)(\D.*)*" to="LongitudinalSectionW_HQ50_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ100)(\D.*)*" to="LongitudinalSectionW_HQ100_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ200)(\D.*)*" to="LongitudinalSectionW_HQ200_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ500)(\D.*)*" to="LongitudinalSectionW_HQ500_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQ1000)(\D.*)*" to="LongitudinalSectionW_HQ1000_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQExtrem)(\D.*)*" to="LongitudinalSectionW_HQExtrem_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HQRZ)(\D.*)*" to="LongitudinalSectionW_HQRZ_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(HSQ)(\D.*)*" to="LongitudinalSectionW_HSQ_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(MHQ)(\D.*)*" to="LongitudinalSectionW_MHQ_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(MNQ)(\D.*)*" to="LongitudinalSectionW_MNQ_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(MQ)(\D.*)*" to="LongitudinalSectionW_MQ_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			pattern=".*(NQ)(\D.*)*" to="LongitudinalSectionW_NQ_Points" />
+		<mapping from="longitudinal_section.w" masterAttr="ld_mode==location"
+			to="LongitudinalSectionPoints" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ1)(\D.*)*"
+			to="LongitudinalSectionW_HQ1" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ2)(\D.*)*"
+			to="LongitudinalSectionW_HQ2" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ5)(\D.*)*"
+			to="LongitudinalSectionW_HQ5" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ10)(\D.*)*"
+			to="LongitudinalSectionW_HQ10" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ20)(\D.*)*"
+			to="LongitudinalSectionW_HQ20" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ25)(\D.*)*"
+			to="LongitudinalSectionW_HQ25" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ50)(\D.*)*"
+			to="LongitudinalSectionW_HQ50" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ100)(\D.*)*"
+			to="LongitudinalSectionW_HQ100" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ200)(\D.*)*"
+			to="LongitudinalSectionW_HQ200" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ500)(\D.*)*"
+			to="LongitudinalSectionW_HQ500" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQ1000)(\D.*)*"
+			to="LongitudinalSectionW_HQ1000" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQExtrem)(\D.*)*"
+			to="LongitudinalSectionW_HQExtrem" />
+		<mapping from="longitudinal_section.w" pattern=".*(HQRZ)(\D.*)*"
+			to="LongitudinalSectionW_HQRZ" />
+		<mapping from="longitudinal_section.w" pattern=".*(HSQ)(\D.*)*"
+			to="LongitudinalSectionW_HSQ" />
+		<mapping from="longitudinal_section.w" pattern=".*(MHQ)(\D.*)*"
+			to="LongitudinalSectionW_MHQ" />
+		<mapping from="longitudinal_section.w" pattern=".*(MNQ)(\D.*)*"
+			to="LongitudinalSectionW_MNQ" />
+		<mapping from="longitudinal_section.w" pattern=".*(MQ)(\D.*)*"
+			to="LongitudinalSectionW_MQ" />
+		<mapping from="longitudinal_section.w" pattern=".*(NQ)(\D.*)*"
+			to="LongitudinalSectionW_NQ" />
+		<mapping from="longitudinal_section.w" to="LongitudinalSectionW" />
 
-        <mapping from="discharge_curve.curve" to="DischargeCurve"/>
-        <mapping from="historical_discharge.historicalq" to="HistoricalDischargeCurveQ"/>
-        <mapping from="historical_discharge.historicalq.diff" to="HistoricalDischargeCurveQDiff"/>
-        <mapping from="cross_section" to="CrossSection"/>
-        <mapping from="cross_section_water_line" to="CrossSectionWaterLine"/>
-        <mapping from="computed_discharge_curve.q" to="ComputedDischargeCurve"/>
-        <mapping from="duration_curve.w" to="DurationCurveW"/>
-        <mapping from="duration_curve.q" to="DurationCurveQ"/>
-        <mapping from="discharge_longitudinal_section.w" to="DischargeLongitudinalSectionW"/>
-        <mapping from="discharge_longitudinal_section.c" to="DischargeLongitudinalSectionC"/>
-        <mapping from="discharge_longitudinal_section.q" to="DischargeLongitudinalSectionQ"/>
-        <mapping from="computed_discharge_curve.mainvalues.q" to="MainValuesQ"/>
-        <mapping from="computed_discharge_curve.mainvalues.w" to="MainValuesW"/>
-        <mapping from="duration_curve.mainvalues.q" to="MainValuesQ"/>
-        <mapping from="mainvalues.q" to="MainValuesQ"/>
-        <mapping from="mainvalues.w" to="MainValuesW"/>
-        <mapping from="longitudinal_section.annotations" to="Annotations"/>
-        <mapping from="w_differences" to="Differences"/>
-        <mapping from="floodmap.wsplgen" to="WSPLGEN"/>
-        <mapping from="floodmap.riveraxis" to="RiverAxis"/>
-        <mapping from="floodmap.kms" to="Kms"/>
-        <mapping from="floodmap.qps" to="Qps"/>
-        <mapping from="floodmap.hws" to="Hws"/>
-        <mapping from="floodmap.hydr_boundaries" to="HydrBoundariesLines"/>
-        <mapping from="floodmap.hydr_boundaries_poly" to="HydrBoundariesPolys"/>
-        <mapping from="floodmap.catchment" to="Catchment"/>
-        <mapping from="floodmap.floodplain" to="Floodplains"/>
-        <mapping from="floodmap.lines" to="FloodmapLines"/>
-        <mapping from="floodmap.buildings" to="Buildings"/>
-        <mapping from="floodmap.fixpoints" to="Fixpoints"/>
-        <mapping from="floodmap.floodmaps" to="Floodmaps"/>
-        <mapping from="floodmap.gauge_location" to="GaugeLocation"/>
-        <mapping from="other.wq" to="WQPoints"/>
-        <mapping from="other.wkms" to="WKms"/>
-        <mapping from="other.wqkms" to="WQKms"/>
-        <mapping from="other.wqkms.w" to="WQKms"/>
-        <mapping from="other.wqkms.q" to="WQKms"/>
-        <mapping from="heightmarks_points" to="heightmarks_points"/>
-        <mapping from="area" to="Area"/>
-        <mapping from="cross_section.area" to="Area"/>
-        <mapping from="hyk" to="Hyk"/>
-        <mapping from="longitudinal_section.area" to="Area"/>
-        <mapping from="longitudinal_section.manualpoints" to="ManualPoints"/>
-        <mapping from="cross_section.manualpoints" to="ManualPoints"/>
-        <mapping from="cross_section.manualline" to="CrossSectionWaterLine"/>
-        <mapping from="computed_discharge_curve.manualpoints" to="ManualPoints"/>
-        <mapping from="duration_curve.manualpoints" to="ManualPoints"/>
-        <mapping from="wdifferences.manualpoints" to="ManualPoints"/>
-        <mapping from="discharge_longitudinal_section.manualpoints" to="ManualPoints"/>
-        <mapping from="discharge_curve.manualpoints" to="ManualPoints"/>
-        <mapping from="reference_curve.manualpoints" to="ManualPoints"/>
-        <mapping from="reference_curve_normalized.manualpoints" to="ManualPoints"/>
-        <mapping from="historical_discharge.manualpoints" to="ManualPoints"/>
-        <mapping from="manualpoints" to="ManualPoints"/>
-        <mapping from="reference_curve" to="ReferenceCurve"/>
-        <mapping from="reference_curve_normalized" to="ReferenceCurveNormalized"/>
-        <mapping from="flow_velocity.totalchannel" to="FlowVelocityVTotalChannel"/>
-        <mapping from="flow_velocity.mainchannel" to="FlowVelocityVMainChannel"/>
-        <mapping from="flow_velocity.tau" to="FlowVelocityTau"/>
-        <mapping from="bedheight_middle.single" to="MiddleBedHeightSingle"/>
-        <mapping from="bedheight_middle.epoch" to="MiddleBedHeightEpoch"/>
-        <mapping from="relativepoint" to="RelativePoint"/>
-        <mapping from="sq_a_measurement" to="SQMeasurements"/>
-        <mapping from="sq_a_outlier" to="SQOutliers"/>
-        <mapping from="sq_a_curve" to="SQCurve"/>
-        <mapping from="sq_b_measurement" to="SQMeasurements"/>
-        <mapping from="sq_b_outlier" to="SQOutliers"/>
-        <mapping from="sq_b_curve" to="SQCurve"/>
-        <mapping from="sq_c_measurement" to="SQMeasurements"/>
-        <mapping from="sq_c_outlier" to="SQOutliers"/>
-        <mapping from="sq_c_curve" to="SQCurve"/>
-        <mapping from="sq_d_measurement" to="SQMeasurements"/>
-        <mapping from="sq_d_outlier" to="SQOutliers"/>
-        <mapping from="sq_d_curve" to="SQCurve"/>
-        <mapping from="sq_e_measurement" to="SQMeasurements"/>
-        <mapping from="sq_e_outlier" to="SQOutliers"/>
-        <mapping from="sq_e_curve" to="SQCurve"/>
-        <mapping from="sq_f_measurement" to="SQMeasurements"/>
-        <mapping from="sq_f_outlier" to="SQOutliers"/>
-        <mapping from="sq_f_curve" to="SQCurve"/>
-        <mapping from="fix_sector_average_wq_0" to="FixingSectorAverageWQ0"/>
-        <mapping from="fix_sector_average_wq_1" to="FixingSectorAverageWQ1"/>
-        <mapping from="fix_sector_average_wq_2" to="FixingSectorAverageWQ2"/>
-        <mapping from="fix_sector_average_wq_3" to="FixingSectorAverageWQ3"/>
-        <mapping from="fix_analysis_events_wq" to="FixingAnalysisEventsWQ"/>
-        <mapping from="fix_outlier" to="FixingOutlier"/>
-        <mapping from="fix_wq_curve" to="FixingWQCurve"/>
-        <mapping from="fix_reference_events_wq" to="FixingReferenceEventsWQ"/>
-        <mapping from="fix_sector_average_dwt_0" to="FixingDeltaWtAverage0"/>
-        <mapping from="fix_sector_average_dwt_1" to="FixingDeltaWtAverage1"/>
-        <mapping from="fix_sector_average_dwt_2" to="FixingDeltaWtAverage2"/>
-        <mapping from="fix_sector_average_dwt_3" to="FixingDeltaWtAverage3"/>
-        <mapping from="fix_analysis_events_dwt" to="FixingDeltaWtAnalysis"/>
-        <mapping from="fix_analysis_periods_dwt" to="FixingDeltaWtAnalysisPeriods"/>
-        <mapping from="fix_reference_events_dwt" to="FixingDeltaWtReference"/>
-        <mapping from="fix_sector_average_ls_deviation_0" to="FixingSectorDeviationLS0"/>
-        <mapping from="fix_sector_average_ls_deviation_1" to="FixingSectorDeviationLS1"/>
-        <mapping from="fix_sector_average_ls_deviation_2" to="FixingSectorDeviationLS2"/>
-        <mapping from="fix_sector_average_ls_deviation_3" to="FixingSectorDeviationLS3"/>
-        <mapping from="fix_sector_average_ls_0" to="FixingLSAverage0"/>
-        <mapping from="fix_sector_average_ls_1" to="FixingLSAverage1"/>
-        <mapping from="fix_sector_average_ls_2" to="FixingLSAverage2"/>
-        <mapping from="fix_sector_average_ls_3" to="FixingLSAverage3"/>
-        <mapping from="fix_deviation_ls" to="FixLSDeviation"/>
-        <mapping from="fix_deviation_dwt" to="FixDeltaWtDeviation"/>
-        <mapping from="fix_analysis_events_ls" to="FixLSAnalysis"/>
-        <mapping from="fix_reference_events_ls" to="FixLSReference"/>
-        <mapping from="fix_derivate" to="FixingDerivedCurve"/>
-    </mappings>
+		<mapping from="longitudinal_section.q" pattern="(HQ1)(\D.*)*"
+			to="LongitudinalSectionQ_HQ1" />
+		<mapping from="longitudinal_section.q" pattern="(HQ2)(\D.*)*"
+			to="LongitudinalSectionQ_HQ2" />
+		<mapping from="longitudinal_section.q" pattern="(HQ5)(\D.*)*"
+			to="LongitudinalSectionQ_HQ5" />
+		<mapping from="longitudinal_section.q" pattern="(HQ10)(\D.*)*"
+			to="LongitudinalSectionQ_HQ10" />
+		<mapping from="longitudinal_section.q" pattern="(HQ20)(\D.*)*"
+			to="LongitudinalSectionQ_HQ20" />
+		<mapping from="longitudinal_section.q" pattern="(HQ25)(\D.*)*"
+			to="LongitudinalSectionQ_HQ25" />
+		<mapping from="longitudinal_section.q" pattern="(HQ50)(\D.*)*"
+			to="LongitudinalSectionQ_HQ50" />
+		<mapping from="longitudinal_section.q" pattern="(HQ100)(\D.*)*"
+			to="LongitudinalSectionQ_HQ100" />
+		<mapping from="longitudinal_section.q" pattern="(HQ200)(\D.*)*"
+			to="LongitudinalSectionQ_HQ200" />
+		<mapping from="longitudinal_section.q" pattern="(HQ500)(\D.*)*"
+			to="LongitudinalSectionQ_HQ500" />
+		<mapping from="longitudinal_section.q" pattern="(HQ1000)(\D.*)*"
+			to="LongitudinalSectionQ_HQ1000" />
+		<mapping from="longitudinal_section.q" pattern="(HQExtrem)(\D.*)*"
+			to="LongitudinalSectionQ_HQExtrem" />
+		<mapping from="longitudinal_section.q" pattern="(HQRZ)(\D.*)*"
+			to="LongitudinalSectionQ_HQRZ" />
+		<mapping from="longitudinal_section.q" pattern="(HSQ)(\D.*)*"
+			to="LongitudinalSectionQ_HSQ" />
+		<mapping from="longitudinal_section.q" pattern="(MHQ)(\D.*)*"
+			to="LongitudinalSectionQ_MHQ" />
+		<mapping from="longitudinal_section.q" pattern="(MNQ)(\D.*)*"
+			to="LongitudinalSectionQ_MNQ" />
+		<mapping from="longitudinal_section.q" pattern="(MQ)(\D.*)*"
+			to="LongitudinalSectionQ_MQ" />
+		<mapping from="longitudinal_section.q" pattern="(NQ)(\D.*)*"
+			to="LongitudinalSectionQ_NQ" />
+		<mapping from="longitudinal_section.q" to="LongitudinalSectionQ" />
+
+		<mapping from="discharge_curve.curve" to="DischargeCurve" />
+		<mapping from="historical_discharge.historicalq" to="HistoricalDischargeCurveQ" />
+		<mapping from="historical_discharge.historicalq.diff" to="HistoricalDischargeCurveQDiff" />
+		<mapping from="cross_section" to="CrossSection" />
+		<mapping from="cross_section_water_line" to="CrossSectionWaterLine" />
+		<mapping from="computed_discharge_curve.q" to="ComputedDischargeCurve" />
+		<mapping from="duration_curve.w" to="DurationCurveW" />
+		<mapping from="duration_curve.q" to="DurationCurveQ" />
+		<mapping from="discharge_longitudinal_section.w" to="DischargeLongitudinalSectionW" />
+		<mapping from="discharge_longitudinal_section.c" to="DischargeLongitudinalSectionC" />
+		<mapping from="discharge_longitudinal_section.q" to="DischargeLongitudinalSectionQ" />
+		<mapping from="computed_discharge_curve.mainvalues.q" to="MainValuesQ" />
+		<mapping from="computed_discharge_curve.mainvalues.w" to="MainValuesW" />
+		<mapping from="duration_curve.mainvalues.q" to="MainValuesQ" />
+		<mapping from="mainvalues.q" to="MainValuesQ" />
+		<mapping from="mainvalues.w" to="MainValuesW" />
+		<mapping from="longitudinal_section.annotations" to="Annotations" />
+		<mapping from="w_differences" to="Differences" />
+		<mapping from="floodmap.wsplgen" to="WSPLGEN" />
+		<mapping from="floodmap.riveraxis" to="RiverAxis" />
+		<mapping from="floodmap.kms" to="Kms" />
+		<mapping from="floodmap.qps" to="Qps" />
+		<mapping from="floodmap.hws" to="Hws" />
+		<mapping from="floodmap.hydr_boundaries" to="HydrBoundariesLines" />
+		<mapping from="floodmap.hydr_boundaries_poly" to="HydrBoundariesPolys" />
+		<mapping from="floodmap.catchment" to="Catchment" />
+		<mapping from="floodmap.floodplain" to="Floodplains" />
+		<mapping from="floodmap.lines" to="FloodmapLines" />
+		<mapping from="floodmap.buildings" to="Buildings" />
+		<mapping from="floodmap.fixpoints" to="Fixpoints" />
+		<mapping from="floodmap.floodmaps" to="Floodmaps" />
+		<mapping from="floodmap.gauge_location" to="GaugeLocation" />
+		<mapping from="other.wq" to="WQPoints" />
+		<mapping from="other.wkms" to="WKms" />
+		<mapping from="other.wqkms" to="WQKms" />
+		<mapping from="other.wqkms.w" to="WQKms" />
+		<mapping from="other.wqkms.q" to="WQKms" />
+		<mapping from="heightmarks_points" to="heightmarks_points" />
+		<mapping from="area" to="Area" />
+		<mapping from="cross_section.area" to="Area" />
+		<mapping from="hyk" to="Hyk" />
+		<mapping from="longitudinal_section.area" to="Area" />
+		<mapping from="longitudinal_section.manualpoints" to="ManualPoints" />
+		<mapping from="cross_section.manualpoints" to="ManualPoints" />
+		<mapping from="cross_section.manualline" to="CrossSectionWaterLine" />
+		<mapping from="computed_discharge_curve.manualpoints" to="ManualPoints" />
+		<mapping from="duration_curve.manualpoints" to="ManualPoints" />
+		<mapping from="wdifferences.manualpoints" to="ManualPoints" />
+		<mapping from="discharge_longitudinal_section.manualpoints"
+			to="ManualPoints" />
+		<mapping from="discharge_curve.manualpoints" to="ManualPoints" />
+		<mapping from="reference_curve.manualpoints" to="ManualPoints" />
+		<mapping from="reference_curve_normalized.manualpoints" to="ManualPoints" />
+		<mapping from="historical_discharge.manualpoints" to="ManualPoints" />
+		<mapping from="manualpoints" to="ManualPoints" />
+		<mapping from="reference_curve" to="ReferenceCurve" />
+		<mapping from="reference_curve_normalized" to="ReferenceCurveNormalized" />
+		<mapping from="flow_velocity.totalchannel" to="FlowVelocityVTotalChannel" />
+		<mapping from="flow_velocity.mainchannel" to="FlowVelocityVMainChannel" />
+		<mapping from="flow_velocity.tau" to="FlowVelocityTau" />
+		<mapping from="bedheight_middle.single" to="MiddleBedHeightSingle" />
+		<mapping from="bedheight_middle.epoch" to="MiddleBedHeightEpoch" />
+		<mapping from="bed_longitudinal_section.porosity_toplayer" to="PorosityTopLayer" />
+		<mapping from="bed_longitudinal_section.porosity_sublayer" to="PorositySubLayer" />
+		<mapping from="bed_longitudinal_section.sediment_density_toplayer" to="DensityTopLayer" />
+		<mapping from="bed_longitudinal_section.sediment_density_sublayer" to="DensitySublayer" />
+		<mapping from="bed_longitudinal_section.bed_diameter_toplayer" to="BedDiameterTopLayer" />
+		<mapping from="bed_longitudinal_section.bed_diameter_sublayer" to="BedDiameterSubLayer" />
+		<mapping from="bed_longitudinal_section.bedload_diameter" to="BedLoadDiameter" />
+		<mapping from="bedheight_difference.year" to="BedheightDiffYear"/>
+		<mapping from="bedheight_difference.morph_width" to="BedheightDiffMorphWidth"/>
+		<mapping from="bedheight_difference.epoch" to="BedheightDiffEpoch"/>
+		<mapping from="bedheight_difference.year.height1" to="BedheightDiffAbsHeight1"/>
+		<mapping from="bedheight_difference.year.height2" to="BedheightDiffAbsHeight2"/>
+		<mapping from="bedheight_difference.epoch.height1" to="BedheightDiffAbsHeight1"/>
+		<mapping from="bedheight_difference.epoch.height2" to="BedheightDiffAbsHeight2"/>
+		<mapping from="bedheight_difference.height_year" to="BedheightDiffHeightYear"/>
+		<mapping from="relativepoint" to="RelativePoint" />
+		<mapping from="sq_a_measurement" to="SQMeasurements" />
+		<mapping from="sq_a_outlier" to="SQOutliers" />
+		<mapping from="sq_a_curve" to="SQCurve" />
+		<mapping from="sq_a_outlier_curve" to="SQCurve" />
+		<mapping from="sq_a_outlier_measurement" to="SQMeasurements" />
+		<mapping from="sq_b_measurement" to="SQMeasurements" />
+		<mapping from="sq_b_outlier" to="SQOutliers" />
+		<mapping from="sq_b_curve" to="SQCurve" />
+		<mapping from="sq_b_outlier_curve" to="SQCurve" />
+		<mapping from="sq_b_outlier_measurement" to="SQMeasurements" />
+		<mapping from="sq_c_measurement" to="SQMeasurements" />
+		<mapping from="sq_c_outlier" to="SQOutliers" />
+		<mapping from="sq_c_curve" to="SQCurve" />
+		<mapping from="sq_c_outlier_curve" to="SQCurve" />
+		<mapping from="sq_c_outlier_measurement" to="SQMeasurements" />
+		<mapping from="sq_d_measurement" to="SQMeasurements" />
+		<mapping from="sq_d_outlier" to="SQOutliers" />
+		<mapping from="sq_d_curve" to="SQCurve" />
+		<mapping from="sq_d_outlier_curve" to="SQCurve" />
+		<mapping from="sq_d_outlier_measurement" to="SQMeasurements" />
+		<mapping from="sq_e_measurement" to="SQMeasurements" />
+		<mapping from="sq_e_outlier" to="SQOutliers" />
+		<mapping from="sq_e_curve" to="SQCurve" />
+		<mapping from="sq_e_outlier_curve" to="SQCurve" />
+		<mapping from="sq_e_outlier_measurement" to="SQMeasurements" />
+		<mapping from="sq_f_measurement" to="SQMeasurements" />
+		<mapping from="sq_f_outlier" to="SQOutliers" />
+		<mapping from="sq_f_curve" to="SQCurve" />
+		<mapping from="sq_f_outlier_curve" to="SQCurve" />
+		<mapping from="sq_f_outlier_measurement" to="SQMeasurements" />
+		<mapping from="fix_sector_average_wq_0" to="FixingSectorAverageWQ0" />
+		<mapping from="fix_sector_average_wq_1" to="FixingSectorAverageWQ1" />
+		<mapping from="fix_sector_average_wq_2" to="FixingSectorAverageWQ2" />
+		<mapping from="fix_sector_average_wq_3" to="FixingSectorAverageWQ3" />
+		<mapping from="fix_analysis_events_wq" to="FixingAnalysisEventsWQ" />
+		<mapping from="fix_outlier" to="FixingOutlier" />
+		<mapping from="fix_wq_curve" to="FixingWQCurve" />
+		<mapping from="fix_reference_events_wq" to="FixingReferenceEvents" />
+		<mapping from="fix_sector_average_dwt_0" to="FixingDeltaWtAverage0" />
+		<mapping from="fix_sector_average_dwt_1" to="FixingDeltaWtAverage1" />
+		<mapping from="fix_sector_average_dwt_2" to="FixingDeltaWtAverage2" />
+		<mapping from="fix_sector_average_dwt_3" to="FixingDeltaWtAverage3" />
+		<mapping from="fix_analysis_events_dwt" to="FixingDeltaWtAnalysis" />
+		<mapping from="fix_analysis_periods_dwt" to="FixingDeltaWtAnalysisPeriods" />
+		<mapping from="fix_reference_events_dwt" to="FixingReferenceEvents" />
+        <mapping from="fix_reference_period_dwt" to="FixingReferencePeriod" />
+		<mapping from="fix_sector_average_ls_deviation_0" to="FixingSectorDeviationLS0" />
+		<mapping from="fix_sector_average_ls_deviation_1" to="FixingSectorDeviationLS1" />
+		<mapping from="fix_sector_average_ls_deviation_2" to="FixingSectorDeviationLS2" />
+		<mapping from="fix_sector_average_ls_deviation_3" to="FixingSectorDeviationLS3" />
+		<mapping from="fix_sector_average_ls_0" to="FixingLSAverage0" />
+		<mapping from="fix_sector_average_ls_1" to="FixingLSAverage1" />
+		<mapping from="fix_sector_average_ls_2" to="FixingLSAverage2" />
+		<mapping from="fix_sector_average_ls_3" to="FixingLSAverage3" />
+		<mapping from="fix_deviation_ls" to="FixLSDeviation" />
+		<mapping from="fix_deviation_dwt" to="FixDeltaWtDeviation" />
+		<mapping from="fix_analysis_events_ls" to="FixLSAnalysis" />
+		<mapping from="fix_reference_events_ls" to="FixLSReference" />
+		<mapping from="fix_derivate_curve" to="FixingDerivedCurve" />
+		<mapping from="fix_derivate_curve.manualpoints" to="ManualPoints" />
+		<mapping from="qsectors" to="QSectors" />
+	</mappings>
 </themes>
--- a/flys-artifacts/doc/conf/virtual-themes.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/doc/conf/virtual-themes.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <themegroup name="virtual">
-    <!-- Virtual themes are following now! DO NOT USE VIRTUAL THEMES FOR 
+    <!-- Virtual themes are following now! DO NOT USE VIRTUAL THEMES FOR
         FACETS! Please implement concrete themes! -->
     <theme name="Lines" type="virtual">
         <fields>
@@ -12,17 +12,17 @@
                 default="10" />
             <field name="showlinelabel" type="boolean"
                 display="Beschriftung anzeigen" default="false" hints="h" />
-            <field name="linelabelfont" type="Font"
+            <field name="labelfontface" type="Font"
                 display="Beschriftung: Schriftart" default="arial" />
-            <field name="linelabelcolor" type="Color"
+            <field name="labelfontcolor" type="Color"
                 display="Beschriftung: Schriftfarbe" default="0, 0, 0" />
-            <field name="linelabelsize" type="int"
+            <field name="labelfontsize" type="int"
                 display="Beschriftung: Schriftgröße" default="10" />
-            <field name="linelabelstyle" type="Style"
+            <field name="labelfontstyle" type="Style"
                 display="Beschriftung: Schriftstil" default="standard" />
-            <field name="linelabelbgcolor" type="Color"
+            <field name="labelbgcolor" type="Color"
                 display="Beschriftung: Hintergrundfarbe" default="0, 0, 0" />
-            <field name="linelabelshowbg" type="boolean"
+            <field name="labelshowbg" type="boolean"
                 display="Beschriftung: Hintergrund füllen" default="false" />
             <!--orientation? -->
         </fields>
@@ -31,7 +31,9 @@
     <theme name="Points" type="virtual">
         <fields>
             <field name="showlinelabel" type="boolean"
-                display="Linienbeschriftung anzeigen" default="false" hints="h" />
+                display="Linienbeschriftung anzeigen" default="false" />
+            <field name="showpointlabel" type="boolean"
+                display="Punktbeschriftung anzeigen" default="false"/>
             <field name="showlines" type="boolean" default="false" />
             <field name="linesize" type="int" display="Liniendicke"
                 default="1" />
@@ -41,8 +43,16 @@
                 default="true" />
             <field name="textorientation" type="boolean" display="Text horizontal"
                 default="true"/>
-            <field name="showpointlabel" type="boolean"
-                display="Punktbeschriftung anzeigen" default="false"/>
+            <field name="labelfontface" type="Font" default="Arial"
+                display="Beschriftung: Schriftart" />
+            <field name="labelfontcolor" type="Color" default="Color.BLACK"
+                display="Beschriftung: Schriftfarbe" />
+            <field name="labelfontsize" type="int"
+                display="Beschriftung: Schriftgröße" default="10" />
+            <field name="labelshowbg" type="boolean" default="false"
+                display="Beschriftung: Hintergrund anzeigen" />
+            <field name="labelbgcolor" type="Color" default="Color.WHITE"
+                display="Beschriftung: Hintergrundfarbe" />
         </fields>
     </theme>
 
@@ -123,31 +133,14 @@
 
     <!-- Area relevant theme(s) -->
     <theme name="Areas">
-        <inherits>
-            <inherit from="Text" />
-        </inherits>
         <fields>
-            <field name="backgroundcolor" type="Color" display="Texthintergrund"
-                default="255, 255, 255" />
-            <field name="showbackground" type="boolean"
-                display="Hintergrund anzeigen" default="false" />
-            <field name="linecolor" type="Color" display="Linienfarbe"
-                default="Color.BLACK" />
-            <field name="showlines" type="boolean" display="Linie anzeigen"
-                default="true" />
-            <field name="linesize" type="int" display="Liniendicke"
-                default="1" />
-            <field name="linetype" type="Dash" display="Linienart"
-                default="10" />
-            <field name="fillcolor" type="Color" display="Fuellfarbe"
+            <field name="backgroundcolor" type="Color" display="Füllfarbe"
                 default="0, 100, 0" />
-            <field name="showarea" type="boolean" display="Flaeche beschriften"
-                default="false" />
-            <field name="showborder" type="boolean"
-                display="Flaechebegrenzungslinie anzeigen" default="false" />
-            <field name="transparent" type="boolean" display="Transparenz"
-                default="false" />
-            <field name="alpha" type="int" default="255" display="Alpha-Transparenzwert" />
+            <!-- <field name="showbackground" type="boolean"
+                display="Hintergrund anzeigen" default="true" hidden="true" /> //-->
+            <!-- <field name="showborder" type="boolean"
+                display="Flaechebegrenzungslinie anzeigen" default="false" /> //-->
+            <field name="transparency" type="int" default="50" display="Transparenz" />
         </fields>
     </theme>
 
Binary file flys-artifacts/doc/datacage-config-manual/figures/bsh_logo.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/doc/datacage-config-manual/figures/intevation-logo.eps	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,1222 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%For: Frank Koormann,,,
+%%CreationDate: Thu Mar 29 14:37:25 2001
+%%Title: intevation_logo-thin.eps
+%%Creator: Sketch 0.6.8
+%%Pages: 1
+%%BoundingBox: 78 68 132 94
+%%Extensions: CMYK
+%%DocumentSuppliedResources: (atend)
+%%EndComments
+
+%%BeginProlog
+%%BeginResource: procset Linux-Sketch-Procset 1.0 2
+/SketchDict 100 dict def
+SketchDict begin
+/bd { bind def } bind def
+/x { exch } bd
+/xd { exch def } bd
+/PI 3.14159265358979323846264338327 def
+/radgrad { 180 mul PI div } bd
+/skstartmatrix matrix currentmatrix def
+/tmpmat matrix def
+/ISOLatin1Encoding dup where
+{ pop pop }
+{  [/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand
+/quoteright /parenleft /parenright /asterisk /plus /comma /minus /period
+/slash /zero /one /two /three /four /five /six /seven /eight /nine /colon
+/semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J
+/K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash
+/bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i
+/j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright
+/asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /dotlessi /grave /acute /circumflex /tilde /macron /breve
+/dotaccent /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek
+/caron /space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen
+/registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu
+/paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright
+/onequarter /onehalf /threequarters /questiondown /Agrave /Aacute /Acircumflex
+/Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex
+/Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve
+/Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute
+/Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute
+/acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute
+/ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde
+/ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave
+/uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def
+}
+ifelse
+/arct dup where
+{pop pop}
+{
+/arct {arcto pop pop pop pop} bd
+}
+ifelse
+/size 0 def
+/fontname 0 def
+/newfont 0 def
+/sf {
+/size xd
+/fontname xd
+fontname findfont
+dup /Encoding get StandardEncoding eq
+{
+dup
+length dict /newfont xd
+{
+1 index
+/FID ne
+{ newfont 3 1 roll put }
+{ pop pop }
+ifelse
+} forall
+newfont /Encoding ISOLatin1Encoding put
+fontname newfont definefont
+}
+if
+size scalefont setfont
+} bd
+/pusht {matrix currentmatrix} bd
+/popt {setmatrix} bd
+/pushc {gsave} bd
+/popc {grestore} bd
+/rgb {setrgbcolor} bd
+/w { setlinewidth } bd
+/j { setlinejoin } bd
+/J { setlinecap } bd
+/d { setdash } bd
+/F { eofill } bd
+/f { closepath F } bd
+/S {
+pusht
+skstartmatrix setmatrix stroke 
+popt
+} bd
+/s { closepath S } bd
+/m { moveto } bd
+/l { lineto } bd
+/c { curveto } bd
+/txt {
+/tmpmat tmpmat currentmatrix def
+dup type /arraytype eq {concat} {translate} ifelse
+0 0 m
+tmpmat
+} bd
+/T {txt x show popt} bd
+/P {txt x true charpath popt} bd
+/TP {txt x dup show 0 0 m true charpath popt} bd
+/C {newpath 0 360 arc} bd
+/R {
+2 copy m
+x 2 index l
+x 2 index x l
+l
+closepath
+} bd
+/ellipse { 
+dup type /arraytype eq
+{
+pusht x concat
+0 0 1.0 C 
+popt
+}	
+{
+pusht 5 1 roll
+4 -1 roll concat
+newpath
+dup 2 eq {
+0 0 m 
+} if 
+3 1 roll
+radgrad x
+radgrad x
+0 0 1   5 -2 roll
+arc
+0 ne { closepath } if
+popt
+}
+ifelse
+} bd
+/radius1 0 def
+/radius2 0 def
+/factor 0 def
+/rect {
+dup type /arraytype eq
+{
+pusht x concat
+0 0 m  1 0 l  1 1 l  0 1 l  closepath
+popt
+}
+{
+/radius2 xd
+/radius1 xd
+pusht x concat
+radius1 radius2 div  1  scale
+0 radius2 m
+0 1  radius2 1  radius2  arct
+radius2 radius1 div
+dup 1  1 index 0  radius2  arct
+0  0 0  radius2  arct
+0 0  0 1  radius2 arct
+closepath
+popt
+}
+ifelse
+} bd
+/buf 0 def
+/width 0 def
+/height 0 def
+/skcimg {
+/tmpmat tmpmat currentmatrix def
+{ concat } if
+/height xd
+/width xd
+/buf width 3 mul string def
+width height scale
+width height 8
+[width	 0   0	 height neg	  0  height]
+{ currentfile buf readhexstring pop } bind
+false 3 colorimage
+tmpmat setmatrix
+} bd
+/skgimg {
+/tmpmat tmpmat currentmatrix def
+{ concat } if
+/height xd
+/width xd
+/buf width string def
+width height scale
+width height 8
+[width	 0   0	 height neg	  0  height]
+{ currentfile buf readhexstring pop } bind
+image
+tmpmat setmatrix
+} bd
+/rclip {
+4 2 roll m
+dup 0 x rlineto
+x 0 rlineto
+neg 0 x rlineto
+closepath
+clip
+} bd
+/skeps {
+10 dict begin
+/sk_state save def
+concat
+3 index neg 3 index neg translate
+rclip
+0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin
+10 setmiterlimit [ ] 0 setdash
+newpath
+/sk_dict_count countdictstack def
+/sk_count count 1 sub def
+userdict begin
+/showpage { } def
+/languagelevel where
+{
+pop
+languagelevel 1 ne
+{
+false setstrokeadjust
+false setoverprint
+} if
+} if
+} bd 
+/skepsend {
+count sk_count sub { pop } repeat
+countdictstack sk_dict_count sub { end } repeat
+sk_state restore
+end
+} bd
+/gradidx 0 def
+/gradient { 
+3 mul array
+/gradidx 0 def
+} bd
+/$ {
+3 index gradidx       5 -1 roll put 
+2 index gradidx 1 add 4 -1 roll put 
+1 index gradidx 2 add 3 -1 roll put 
+/gradidx gradidx 3 add def
+} bd
+/! { 
+3 
+{
+dup dup gradidx dup 3 1 roll 3 sub get put
+/gradidx gradidx 1 add def
+}
+repeat
+} bd
+/gradcolor {
+3 mul dup 2 add 1 exch	% idx  1  idx+2
+{
+1 index exch	% array array i
+get		% array component
+exch		% component array
+}
+for
+4 1 roll
+} bd
+/x0 0 def /y0 0 def /x1 0 def /y1 0 def
+/left 0 def /right 0 def /top 0 def /bottom 0 def
+/numcolors 0 def
+/axial	{
+/y1 xd /x1 xd /y0 xd /x0 xd
+dup length 3 idiv /numcolors xd
+pusht exch  % ctm array
+x0 x1 ne y0 y1 ne or
+{
+x0 y0 translate
+[x1 x0 sub  y1 y0 sub	dup neg    2 index    0	    0] concat
+clippath flattenpath pathbbox
+/top xd /right xd /bottom xd /left xd
+newpath
+0 gradcolor rgb clippath f
+0 1 numcolors 1 sub
+{
+dup numcolors div
+3 1 roll
+gradcolor rgb
+exch
+bottom right top R f
+}
+for
+}
+if 
+pop
+popt
+} bd
+/r0 0 def /r1 0 def /dr 0 def
+/radial	{
+/r1 xd /r0 xd /y0 xd /x0 xd
+/dr r1 r0 sub def
+dup length 3 idiv /numcolors xd
+pusht exch  % ctm array
+r0 r1 ne
+{
+x0 y0 translate
+clippath flattenpath pathbbox
+/top xd /right xd /bottom xd /left xd
+newpath
+dr 0 gt {numcolors 1 sub}{0} ifelse gradcolor rgb
+clippath f
+dr 0 gt {numcolors 1 sub -1 0} { 0 1 numcolors 1 sub} ifelse
+{
+dup numcolors div dr mul r0 add
+3 1 roll
+gradcolor rgb
+exch
+0 0 3 -1 roll C f
+}
+for
+}
+if 
+pop
+popt
+} bd
+/max {
+2 copy lt {exch} if pop
+} bd
+/conical {
+pusht 5 1 roll
+3 1 roll /y0 xd /x0 xd
+x0 y0 translate
+radgrad rotate
+dup length 3 idiv /numcolors xd
+clippath flattenpath pathbbox newpath
+4 { abs 4 1 roll} repeat
+3 { max } repeat
+2 mul
+dup scale
+0 gradcolor rgb
+0 0 1 0 360 arc f
+1 1 numcolors 1 sub
+{
+dup numcolors div 180 mul
+3 1 roll
+gradcolor rgb
+exch
+0 0 moveto
+0 0 1  4 -1 roll  dup neg  arc
+closepath f
+}
+for
+pop
+popt
+} bd
+/XStep 0 def /YStep 0 def /imagedata 0 def /components 0 def
+/tileimage2 {
+exch 4 2 roll
+/height xd
+/width xd
+mark
+/components 2 index
+/PatternType 1
+/PaintType 1
+/TilingType 1
+/BBox [0 0 width height]
+/XStep width
+/YStep height
+/PaintProc {
+begin
+XStep YStep 8
+matrix
+imagedata
+false
+components
+colorimage
+end
+}
+counttomark 2 div cvi dup dict begin
+{ def } repeat
+pop currentdict end
+dup
+/imagedata
+4 -1 roll
+width height mul mul string
+currentfile exch readhexstring pop
+put
+exch
+makepattern
+setpattern
+clippath
+eofill
+} bd
+/tileimage1 {
+concat
+/components xd
+/height xd
+/width xd
+/imagedata
+currentfile
+width height mul components mul string
+readhexstring pop
+def
+clippath flattenpath pathbbox
+/top xd /right xd /bottom xd /left xd
+left width div floor width mul
+bottom height div floor height mul
+translate
+top bottom sub height div ceiling cvi
+{
+gsave
+right left sub width div ceiling cvi
+{
+width height 8 matrix
+components 1 eq
+{
+{ imagedata }
+image
+}
+{
+imagedata
+false components
+colorimage
+}
+ifelse
+width 0 translate
+}
+repeat
+grestore
+0 height translate
+}
+repeat
+} bd
+/makepattern where
+{
+pop
+/tileimage /tileimage2 load def
+}
+{
+/tileimage /tileimage1 load def
+}
+ifelse
+end
+%%EndResource
+%%EndProlog
+
+%%BeginSetup
+
+10.433 setmiterlimit
+%%EndSetup
+
+%%Page: 1 1
+SketchDict begin
+newpath
+81.1479 90.3363 m
+83.1262 89.4518 85.8962 89.4399 87.7755 90.732 c
+88.4885 91.2221 89.1744 91.8548 89.1744 92.7451 c
+89.3805 92.7446 89.5146 92.3854 89.7059 92.4617 c
+90.3588 92.7216 91.0745 92.5334 91.5725 92.3012 c
+91.8169 92.1873 92.0442 92.7366 92.3141 92.7358 c
+92.4246 92.4106 93.2359 91.4866 93.2359 91.4372 c
+95.3948 89.4748 99.2768 88.555 102.019 89.186 c
+102.881 89.3844 110.268 92.0436 110.268 92.7837 c
+110.735 92.6454 111.042 92.3763 111.801 92.3588 c
+113.208 92.7366 l
+114.425 92.9532 114.356 92.6862 114.93 92.6609 c
+114.93 90.5837 114.005 87.8389 114.95 85.8136 c
+115.043 85.6129 115.327 85.1931 115.474 85.044 c
+119.365 81.1112 125.41 82.6691 129.868 84.5493 c
+129.868 84.4181 130.124 84.2636 130.124 84.1323 c
+130.124 83.9504 129.868 83.7916 129.868 83.6096 c
+129.521 83.6096 129.294 83.4821 129.005 83.2726 c
+126.771 81.6517 123.827 80.5003 121.756 78.5645 c
+121.551 78.3735 121.558 78.1688 121.558 77.872 c
+121.756 77.6246 122.036 77.2541 122.315 77.061 c
+122.399 77.0029 122.564 76.8961 124.449 75.877 c
+126.015 75.0309 127.68 74.6575 129.194 74.6604 c
+129.194 74.475 129.046 74.2851 129.051 74.0807 c
+129.052 74.0297 129.066 73.9744 129.086 73.9171 c
+129.106 73.8599 129.132 73.8003 129.158 73.7411 c
+129.183 73.6819 129.209 73.6226 129.227 73.5659 c
+129.245 73.5087 129.255 73.4539 129.252 73.4038 c
+129.238 73.1617 129.151 72.9814 129.076 72.7773 c
+126.75 73.9407 124.211 75.0082 121.611 75.7449 c
+120.232 76.1358 118.876 76.4938 117.501 76.7872 c
+116.305 77.0426 113.981 77.2912 113.298 75.7452 c
+112.578 74.1158 113.329 72.4451 113.544 70.8622 c
+113.245 70.9989 113.04 71.6163 112.826 71.3291 c
+112.556 70.799 l
+112.21 71.5408 111.908 72.5375 111.698 73.3754 c
+111.413 74.5161 110.852 75.2644 109.473 75.4597 c
+107.323 75.7648 107.541 75.5249 106.808 75.0986 c
+105.489 74.3316 104.447 72.6469 104.427 70.7633 c
+104.103 70.8166 104.04 71.1029 103.715 71.1562 c
+103.661 71.1361 103.594 71.1001 103.521 71.0624 c
+103.448 71.0247 103.368 70.985 103.288 70.9575 c
+103.209 70.9303 103.129 70.9147 103.056 70.9254 c
+102.983 70.9359 102.916 70.9725 102.862 71.049 c
+102.814 71.2619 102.513 71.4476 102.165 71.1947 c
+101.229 70.799 l
+101.108 71.1117 100.582 71.3382 100.316 71.5037 c
+99.0659 72.2807 97.0528 71.5295 96.2781 70.5102 c
+96.093 70.57 95.9079 70.6298 95.7225 70.6896 c
+95.5289 70.7905 95.2567 70.9099 94.8114 70.6321 c
+94.4917 70.5802 l
+94.4917 70.8373 94.9407 70.8557 95.0994 71.1094 c
+95.4787 71.7155 95.856 72.5599 96.434 73.236 c
+97.4233 74.3934 98.3768 75.7545 97.6356 77.2578 c
+97.415 77.7045 97.576 77.5078 96.6749 78.2941 c
+96.1414 78.7598 95.3594 79.3486 94.7173 79.6468 c
+91.9201 80.9465 88.4556 81.0936 85.1714 80.6681 c
+83.4604 80.4467 81.7831 80.1902 80.3068 79.6031 c
+80.2609 79.585 80.3031 79.5122 80.2535 79.5122 c
+80.306 79.6936 80.6359 79.9461 80.4556 80.0496 c
+80.2343 80.1389 80.2481 80.2886 80.2552 80.4833 c
+80.2731 80.7971 l
+80.4213 80.7971 80.3077 80.824 80.4554 80.8396 c
+82.6332 81.0712 84.5517 81.7552 86.5887 82.4718 c
+87.2231 82.6952 87.987 83.0019 88.527 83.452 c
+88.8771 83.744 89.3216 84.2214 89.3216 84.6667 c
+89.3216 85.0624 88.8949 85.959 88.6166 86.1815 c
+86.4209 87.9381 80.8845 88.8736 80.8346 88.9422 c
+80.7828 89.0136 l
+80.7856 89.1103 81.0512 89.1729 81.1198 89.3575 c
+81.1731 89.5006 81.0506 89.7858 81.1017 89.9232 c
+81.1924 90.1679 81.2247 90.3363 81.1479 90.3363 c
+closepath
+gsave
+0.9 0.9 0.9 rgb
+F
+grestore
+0.9 0.9 0.9 rgb
+0.215433 w
+0 j
+0 J
+[] 0 d
+S
+newpath
+108.203 84.2032 m
+107.659 84.1536 106.67 83.9557 106.373 83.5107 c
+106.324 83.5107 106.274 83.4611 106.274 83.4118 c
+106.126 83.3622 106.027 82.9665 105.829 82.8675 c
+105.829 82.1257 105.533 81.4828 106.126 80.8396 c
+106.225 80.7407 l
+106.423 80.6914 l
+107.907 79.8999 109.341 79.9989 110.726 80.8892 c
+110.776 80.9882 l
+110.875 81.0375 111.072 81.3343 111.27 81.3343 c
+111.27 81.8782 111.765 82.4225 111.418 83.115 c
+111.32 83.3129 110.825 83.4611 110.825 83.659 c
+110.726 83.659 110.132 84.0054 110.132 84.0547 c
+109.935 84.0547 l
+109.737 84.2525 108.401 84.2525 108.203 84.2032 c
+closepath
+gsave
+0.8 0.8 0.8 rgb
+F
+grestore
+0.7 0.7 0.7 rgb
+0.566929 w
+0 j
+0 J
+[] 0 d
+S
+newpath
+129.218 74.6074 m
+126.745 74.9042 123.636 75.6956 121.805 77.5256 c
+121.657 77.6742 121.459 78.0203 121.459 78.2677 c
+121.558 78.3171 l
+121.558 78.3667 121.757 78.5634 121.805 78.6139 c
+123.135 79.9966 125.128 80.6576 126.673 81.7561 c
+128.047 82.7323 129.427 83.5107 129.67 83.5107 c
+129.775 83.5629 130.033 83.615 130.115 83.659 c
+129.109 72.8173 m
+127.427 73.3119 125.912 74.363 124.229 74.9042 c
+121.542 75.7684 l
+120.528 76.0947 119.51 76.4014 118.523 76.5599 c
+116.741 76.8465 115.229 77.6229 113.743 76.2892 c
+112.805 75.4467 113.006 74.657 113.006 73.4205 c
+113.121 72.9094 113.569 71.2846 113.569 70.7888 c
+112.54 70.8024 m
+111.897 72.0885 111.86 74.2406 110.585 75.1462 c
+109.981 75.576 107.912 75.6808 107.214 75.4484 c
+106.724 75.2851 106.373 74.7559 106.027 74.4095 c
+105.087 73.4698 104.431 72.0363 104.431 70.7009 c
+101.387 70.7216 m
+100.435 71.9918 98.2462 72.4301 97.0247 71.1409 c
+96.8801 71.0068 96.6052 70.7772 96.0915 70.388 c
+94.588 70.6593 m
+95.3302 71.0054 95.6213 71.8212 95.9603 72.5171 c
+96.561 73.7499 98.571 75.6363 97.6602 77.1169 c
+97.3518 77.6183 l
+97.063 78.124 95.8361 79.0019 95.7069 79.1312 c
+95.509 79.329 94.9892 79.5357 94.7496 79.6525 c
+90.7346 81.6135 86.2429 80.9354 82.0379 80.1471 c
+81.4945 80.0454 80.7354 79.496 80.1915 79.496 c
+80.855 88.9875 m
+81.4486 88.839 81.943 88.619 82.5326 88.4566 c
+83.9216 88.0751 85.6935 87.8542 86.9841 87.1708 c
+87.3753 86.9639 87.8251 86.5772 88.2209 86.3794 c
+88.9627 86.0333 89.3091 85.2418 89.2595 84.4008 c
+89.2595 84.2032 88.8592 83.7624 88.7155 83.6096 c
+88.0678 82.9214 86.6839 82.482 85.7972 82.175 c
+84.1118 81.5919 82.1369 80.7407 80.3068 80.7407 c
+80.2575 80.6914 l
+81.2564 90.302 m
+81.7865 90.031 81.8707 90.1115 82.3007 89.9334 c
+83.7949 89.3152 85.8009 89.932 87.1823 90.5344 c
+88.1222 90.944 89.2116 91.7442 89.2116 92.8407 c
+92.2753 92.7032 m
+92.9678 91.6646 93.7564 90.8221 94.8982 90.2869 c
+95.3392 90.0803 95.9901 89.7098 96.481 89.5944 c
+98.5129 89.1165 100.233 88.7908 102.318 89.1987 c
+102.511 89.2367 102.58 89.2282 103.109 89.3966 c
+105.253 90.0783 107.678 91.2292 109.638 92.3148 c
+109.697 92.3474 110.336 92.8129 110.352 92.8129 c
+114.93 92.7352 m
+114.815 91.7541 114.609 90.9627 114.61 90.427 c
+114.611 88.8645 114.327 87.8086 114.634 86.6268 c
+115.198 84.4504 118.458 82.8638 119.975 82.7193 c
+123.178 82.4137 126.158 83.2958 129.076 84.3515 c
+129.123 84.3682 129.274 84.4008 129.373 84.4008 c
+129.423 84.4997 129.818 84.6483 129.967 84.6483 c
+0.8 0.8 0.8 rgb
+1 j
+1 J
+S
+newpath
+81.6246 86.9766 m
+82.6698 86.9766 l
+82.6698 79.2655 l
+81.6246 79.2655 l
+81.6246 86.9766 l
+closepath
+84.0446 82.4667 m
+84.0446 82.7598 84.0959 83.0368 84.1988 83.297 c
+84.3014 83.5575 84.4553 83.8013 84.6606 84.0286 c
+84.8734 84.2486 85.1226 84.4155 85.4086 84.5292 c
+85.6946 84.6429 86.0209 84.6996 86.3877 84.6996 c
+86.4464 84.6996 86.5104 84.6959 86.5802 84.6885 c
+86.6499 84.6811 86.725 84.6704 86.8058 84.6556 c
+86.8863 84.6409 86.9688 84.6227 87.0533 84.6006 c
+87.1375 84.5785 87.2236 84.5493 87.3118 84.5125 c
+87.4657 84.4467 87.6123 84.3622 87.7517 84.2596 c
+87.8909 84.157 88.0267 84.0323 88.1588 83.8857 c
+88.2906 83.7463 88.3898 83.5739 88.4559 83.3687 c
+88.5216 83.1632 88.5548 82.9285 88.5548 82.6646 c
+88.5548 82.6572 88.5548 82.6481 88.5548 82.6371 c
+88.5548 82.626 88.5548 82.6133 88.5548 82.5985 c
+88.5548 82.5911 88.5548 82.5821 88.5548 82.571 c
+88.5548 82.56 88.5548 82.5472 88.5548 82.5325 c
+88.5548 79.2655 l
+87.5097 79.2655 l
+87.5097 82.3786 l
+87.5097 82.5398 87.4858 82.6994 87.4382 82.857 c
+87.3906 83.0146 87.3192 83.1632 87.2236 83.3026 c
+87.1284 83.4492 87.0037 83.5592 86.8497 83.6326 c
+86.6958 83.706 86.5124 83.7426 86.2998 83.7426 c
+86.1017 83.7426 85.9276 83.7097 85.7771 83.6437 c
+85.6269 83.5776 85.4968 83.4787 85.3868 83.3466 c
+85.2768 83.2145 85.1906 83.0733 85.1283 82.9231 c
+85.0659 82.7729 85.0237 82.6133 85.0016 82.4446 c
+85.0016 79.2655 l
+84.0446 79.2655 l
+84.0446 82.4667 l
+closepath
+89.6767 85.8436 m
+90.7108 85.8436 l
+90.7108 84.5456 l
+92.7126 84.5456 l
+92.7126 83.5997 l
+90.7108 83.5997 l
+90.7108 80.9156 l
+90.7108 80.813 90.7179 80.7211 90.7326 80.6406 c
+90.7474 80.5598 90.7695 80.483 90.7987 80.4096 c
+90.8279 80.3362 90.8922 80.2832 90.9912 80.25 c
+91.0901 80.2171 91.2276 80.2007 91.4036 80.2007 c
+92.6248 80.2225 l
+92.6248 79.2655 l
+91.3268 79.2655 l
+91.3194 79.2655 91.312 79.2655 91.3047 79.2655 c
+91.2973 79.2655 91.2899 79.2655 91.2826 79.2655 c
+91.2755 79.2655 91.2698 79.2655 91.2661 79.2655 c
+91.2624 79.2655 91.2571 79.2619 91.2497 79.2545 c
+91.2423 79.2545 91.2349 79.2545 91.2276 79.2545 c
+91.2205 79.2545 91.2131 79.2545 91.2057 79.2545 c
+91.1984 79.2545 91.193 79.2545 91.1893 79.2545 c
+91.1856 79.2545 91.18 79.2545 91.1726 79.2545 c
+90.9234 79.2545 90.7071 79.2913 90.5237 79.3645 c
+90.3403 79.4379 90.1901 79.5516 90.0727 79.7055 c
+89.9554 79.8597 89.8655 80.0247 89.8032 80.2007 c
+89.7408 80.3764 89.7023 80.5598 89.6878 80.7506 c
+89.6804 80.7654 89.6767 80.7818 89.6767 80.7999 c
+89.6767 80.8184 89.6767 80.8385 89.6767 80.8606 c
+89.6767 80.8753 89.6767 80.8918 89.6767 80.9099 c
+89.6767 80.9283 89.6767 80.9485 89.6767 80.9706 c
+89.6767 80.9927 l
+89.6767 85.8436 l
+closepath
+96.7829 83.1595 m
+96.7682 83.1669 96.7534 83.1762 96.7387 83.187 c
+96.7242 83.198 96.7095 83.2145 96.6948 83.2366 c
+96.68 83.2513 96.6636 83.2695 96.6454 83.2916 c
+96.627 83.3137 96.6069 83.3355 96.5848 83.3576 c
+96.5629 83.3724 96.5388 83.3888 96.5133 83.407 c
+96.4875 83.4254 96.4637 83.4455 96.4419 83.4676 c
+96.4124 83.4824 96.3832 83.4988 96.3537 83.5172 c
+96.3246 83.5354 96.2914 83.5518 96.2548 83.5666 c
+96.1814 83.6031 96.0952 83.6289 95.9963 83.6437 c
+95.8974 83.6584 95.7854 83.6655 95.6607 83.6655 c
+95.3747 83.6655 95.1235 83.6142 94.9072 83.5116 c
+94.6909 83.4089 94.5095 83.2587 94.3627 83.0606 c
+94.2161 82.8627 94.1062 82.6535 94.0327 82.4335 c
+93.9593 82.2136 93.9228 81.9862 93.9228 81.7515 c
+93.9228 81.7442 93.9228 81.7368 93.9228 81.7297 c
+93.9228 81.7186 l
+93.9228 81.5058 93.9613 81.3025 94.0384 81.1081 c
+94.1152 80.9136 94.2272 80.7285 94.3737 80.5525 c
+94.5206 80.3764 94.702 80.2446 94.9183 80.1565 c
+95.1346 80.0686 95.382 80.0247 95.6607 80.0247 c
+95.9614 80.0247 96.2126 80.0592 96.4144 80.129 c
+96.616 80.1987 96.7682 80.3033 96.8708 80.4425 c
+96.9734 80.5893 97.0669 80.7617 97.1514 80.9595 c
+97.2356 81.1577 97.3107 81.3813 97.3768 81.6305 c
+97.3768 81.6415 l
+97.3878 81.6526 l
+97.3878 81.6637 l
+98.3448 81.6087 l
+98.3448 81.5939 98.3448 81.5812 98.3448 81.5701 c
+98.3448 81.5591 98.3485 81.55 98.3559 81.5426 c
+98.3559 81.5279 98.3559 81.5168 98.3559 81.5094 c
+98.3559 81.5024 98.3559 81.4913 98.3559 81.4766 c
+98.3559 81.4692 98.3559 81.4601 98.3559 81.4491 c
+98.3559 81.438 98.3595 81.4289 98.3669 81.4216 c
+98.3669 81.4068 98.3669 81.3958 98.3669 81.3887 c
+98.3669 81.3813 98.3669 81.374 98.3669 81.3666 c
+98.3669 81.3079 98.3632 81.2475 98.3559 81.1852 c
+98.3485 81.1228 98.3374 81.0585 98.323 80.9927 c
+98.3156 80.9632 98.3063 80.9303 98.2952 80.8935 c
+98.2844 80.8569 98.2751 80.824 98.2677 80.7946 c
+98.2532 80.758 98.2402 80.7231 98.2294 80.69 c
+98.2184 80.6571 98.2056 80.6222 98.1909 80.5856 c
+98.1027 80.4022 97.9854 80.2225 97.8388 80.0465 c
+97.6923 79.8705 97.5126 79.7055 97.3 79.5516 c
+97.0944 79.3976 96.8543 79.282 96.5794 79.2052 c
+96.3044 79.1281 95.9983 79.0895 95.6607 79.0895 c
+95.272 79.0895 94.9129 79.1502 94.5827 79.2709 c
+94.2527 79.392 93.9559 79.5774 93.6917 79.8265 c
+93.4205 80.0833 93.2189 80.3711 93.0868 80.69 c
+92.9547 81.0091 92.8887 81.3629 92.8887 81.7515 c
+92.8887 82.1623 92.9437 82.5254 93.0536 82.8406 c
+93.1636 83.1558 93.3289 83.4274 93.5489 83.6547 c
+93.7688 83.882 93.9999 84.0688 94.2417 84.2157 c
+94.4837 84.3622 94.7369 84.4685 95.0008 84.5346 c
+95.0303 84.542 95.0577 84.5473 95.0833 84.551 c
+95.1091 84.5547 95.1366 84.5604 95.1657 84.5675 c
+95.1952 84.5675 95.2227 84.5695 95.2482 84.5731 c
+95.274 84.5768 95.3015 84.5822 95.3307 84.5896 c
+95.3894 84.5969 95.4464 84.6023 95.5014 84.606 c
+95.5564 84.6097 95.6094 84.6117 95.6607 84.6117 c
+95.9614 84.6117 96.2421 84.5695 96.5023 84.485 c
+96.7628 84.4008 97.0029 84.2744 97.2229 84.1057 c
+97.4354 83.937 97.6279 83.75 97.8003 83.5447 c
+97.9726 83.3392 98.1248 83.1192 98.2569 82.8845 c
+94.6158 80.9156 l
+94.1867 81.6855 l
+96.7829 83.1595 l
+closepath
+99.6431 84.5456 m
+101.282 80.3875 l
+102.756 84.5456 l
+103.889 84.5456 l
+102.063 79.7826 l
+102.019 79.6726 101.969 79.5791 101.914 79.502 c
+101.859 79.4251 101.799 79.3608 101.733 79.3095 c
+101.667 79.2655 101.599 79.229 101.53 79.1995 c
+101.46 79.1703 101.385 79.1519 101.304 79.1445 c
+101.297 79.1445 101.291 79.1445 101.287 79.1445 c
+101.284 79.1445 101.278 79.1445 101.271 79.1445 c
+101.264 79.1445 101.256 79.1445 101.249 79.1445 c
+101.168 79.1445 101.09 79.1556 101.012 79.1777 c
+100.935 79.1995 100.857 79.2327 100.776 79.2766 c
+100.703 79.3353 100.637 79.403 100.578 79.4801 c
+100.519 79.5569 100.468 79.6505 100.424 79.7605 c
+98.5101 84.5456 l
+99.6431 84.5456 l
+closepath
+108.388 82.3015 m
+108.388 82.463 108.357 82.6223 108.294 82.7802 c
+108.232 82.9378 108.139 83.0864 108.014 83.2255 c
+107.889 83.3724 107.713 83.4824 107.486 83.5555 c
+107.259 83.6289 106.984 83.6655 106.661 83.6655 c
+106.609 83.6655 106.556 83.6618 106.501 83.6547 c
+106.447 83.6473 106.386 83.6363 106.32 83.6215 c
+106.254 83.6142 106.188 83.5997 106.122 83.5776 c
+106.056 83.5555 105.99 83.5263 105.924 83.4897 c
+105.807 83.4381 105.693 83.3667 105.583 83.2751 c
+105.473 83.1833 105.367 83.0753 105.264 82.9506 c
+105.169 82.8332 105.092 82.6884 105.033 82.516 c
+104.974 82.3437 104.938 82.1475 104.923 81.9276 c
+104.923 81.6342 104.963 81.3793 105.044 81.1631 c
+105.125 80.9468 105.245 80.7654 105.407 80.6185 c
+105.576 80.4793 105.75 80.3674 105.929 80.2832 c
+106.109 80.1987 106.298 80.1454 106.496 80.1236 c
+106.503 80.1236 106.513 80.1236 106.523 80.1236 c
+106.534 80.1236 106.544 80.1236 106.551 80.1236 c
+106.566 80.1162 106.578 80.1125 106.589 80.1125 c
+106.6 80.1125 106.609 80.1125 106.617 80.1125 c
+106.632 80.1125 106.643 80.1125 106.65 80.1125 c
+106.657 80.1125 106.668 80.1125 106.683 80.1125 c
+106.69 80.1125 106.699 80.1125 106.71 80.1125 c
+106.721 80.1125 106.731 80.1125 106.738 80.1125 c
+106.826 80.1125 106.909 80.1179 106.985 80.129 c
+107.062 80.14 107.138 80.1602 107.211 80.1896 c
+107.248 80.2041 107.282 80.2188 107.315 80.2336 c
+107.348 80.2483 107.383 80.2628 107.42 80.2775 c
+107.449 80.2996 107.482 80.3214 107.519 80.3436 c
+107.556 80.3657 107.589 80.3912 107.618 80.4207 c
+107.655 80.4425 107.689 80.47 107.722 80.5032 c
+107.756 80.536 107.79 80.5672 107.827 80.5967 c
+107.864 80.6333 107.9 80.6681 107.937 80.701 c
+107.974 80.7342 108.01 80.7688 108.047 80.8056 c
+108.047 79.6066 l
+108.04 79.5918 108.032 79.5808 108.025 79.5737 c
+108.025 79.5626 l
+107.937 79.5039 107.845 79.4506 107.75 79.403 c
+107.655 79.3554 107.556 79.3132 107.453 79.2766 c
+107.35 79.2471 107.225 79.2233 107.079 79.2052 c
+106.932 79.1867 106.764 79.1777 106.573 79.1777 c
+106.566 79.1777 106.56 79.1777 106.556 79.1777 c
+106.553 79.1777 106.547 79.1777 106.54 79.1777 c
+106.533 79.1777 106.522 79.1777 106.507 79.1777 c
+106.5 79.1777 106.492 79.1777 106.485 79.1777 c
+106.478 79.1777 106.47 79.1777 106.463 79.1777 c
+106.456 79.1777 106.45 79.1777 106.447 79.1777 c
+106.443 79.1777 106.437 79.1777 106.43 79.1777 c
+106.092 79.1777 105.779 79.238 105.49 79.3591 c
+105.2 79.4801 104.934 79.6652 104.692 79.9147 c
+104.45 80.1712 104.268 80.4663 104.147 80.7999 c
+104.026 81.1339 103.966 81.5094 103.966 81.9276 c
+103.966 82.2944 104.025 82.6354 104.142 82.9506 c
+104.259 83.2658 104.435 83.5555 104.67 83.8197 c
+104.904 84.0836 105.194 84.2817 105.539 84.4135 c
+105.884 84.5456 106.283 84.6117 106.738 84.6117 c
+107.17 84.6117 107.556 84.553 107.893 84.4357 c
+108.23 84.3183 108.513 84.1423 108.74 83.9076 c
+108.975 83.6729 109.149 83.4254 109.262 83.1652 c
+109.376 82.9047 109.433 82.6354 109.433 82.3564 c
+109.433 79.2655 l
+108.388 79.2655 l
+108.388 82.3015 l
+closepath
+110.467 85.8436 m
+111.501 85.8436 l
+111.501 84.5456 l
+113.503 84.5456 l
+113.503 83.5997 l
+111.501 83.5997 l
+111.501 80.9156 l
+111.501 80.813 111.508 80.7211 111.523 80.6406 c
+111.538 80.5598 111.56 80.483 111.589 80.4096 c
+111.618 80.3362 111.683 80.2832 111.782 80.25 c
+111.881 80.2171 112.018 80.2007 112.194 80.2007 c
+113.415 80.2225 l
+113.415 79.2655 l
+112.117 79.2655 l
+112.11 79.2655 112.102 79.2655 112.095 79.2655 c
+112.088 79.2655 112.08 79.2655 112.073 79.2655 c
+112.066 79.2655 112.06 79.2655 112.057 79.2655 c
+112.053 79.2655 112.047 79.2619 112.04 79.2545 c
+112.033 79.2545 112.025 79.2545 112.018 79.2545 c
+112.011 79.2545 112.004 79.2545 111.996 79.2545 c
+111.989 79.2545 111.983 79.2545 111.98 79.2545 c
+111.976 79.2545 111.97 79.2545 111.963 79.2545 c
+111.714 79.2545 111.498 79.2913 111.314 79.3645 c
+111.131 79.4379 110.981 79.5516 110.863 79.7055 c
+110.746 79.8597 110.656 80.0247 110.594 80.2007 c
+110.531 80.3764 110.493 80.5598 110.478 80.7506 c
+110.471 80.7654 110.467 80.7818 110.467 80.7999 c
+110.467 80.8184 110.467 80.8385 110.467 80.8606 c
+110.467 80.8753 110.467 80.8918 110.467 80.9099 c
+110.467 80.9283 110.467 80.9485 110.467 80.9706 c
+110.467 80.9927 l
+110.467 85.8436 l
+closepath
+114.449 84.5456 m
+115.406 84.5456 l
+115.406 79.2655 l
+114.449 79.2655 l
+114.449 84.5456 l
+closepath
+114.372 85.7665 m
+114.372 85.8473 114.387 85.9224 114.416 85.9922 c
+114.446 86.0619 114.493 86.1223 114.559 86.1736 c
+114.618 86.2175 114.682 86.2524 114.752 86.2782 c
+114.821 86.3037 114.893 86.3167 114.966 86.3167 c
+115.047 86.3167 115.12 86.3057 115.186 86.2836 c
+115.252 86.2617 115.318 86.2249 115.384 86.1736 c
+115.45 86.1223 115.5 86.0619 115.533 85.9922 c
+115.566 85.9224 115.582 85.8399 115.582 85.7447 c
+115.582 85.6492 115.566 85.565 115.533 85.4916 c
+115.5 85.4181 115.454 85.3561 115.395 85.3045 c
+115.329 85.2532 115.263 85.2166 115.197 85.1945 c
+115.131 85.1727 115.062 85.1616 114.988 85.1616 c
+114.915 85.1542 114.842 85.1616 114.768 85.1837 c
+114.695 85.2055 114.625 85.2424 114.559 85.2937 c
+114.493 85.345 114.446 85.4091 114.416 85.4862 c
+114.387 85.563 114.372 85.6492 114.372 85.7447 c
+114.372 85.7665 l
+closepath
+116.792 82.0375 m
+116.792 82.4409 116.862 82.804 117.001 83.1266 c
+117.14 83.4492 117.346 83.7315 117.617 83.9736 c
+117.896 84.2157 118.191 84.3971 118.503 84.5181 c
+118.814 84.6392 119.143 84.6996 119.487 84.6996 c
+119.502 84.6996 119.518 84.6996 119.537 84.6996 c
+119.555 84.6996 119.571 84.6996 119.586 84.6996 c
+119.601 84.6922 119.617 84.6885 119.636 84.6885 c
+119.654 84.6885 119.674 84.6885 119.696 84.6885 c
+119.711 84.6885 119.727 84.6885 119.746 84.6885 c
+119.764 84.6885 119.784 84.6885 119.806 84.6885 c
+119.821 84.6811 119.837 84.6777 119.856 84.6777 c
+119.874 84.6777 119.89 84.6777 119.905 84.6777 c
+120.199 84.6335 120.479 84.5473 120.747 84.4192 c
+121.014 84.2908 121.273 84.1202 121.522 83.9076 c
+121.764 83.6876 121.947 83.4126 122.072 83.0827 c
+122.197 82.7527 122.259 82.3675 122.259 81.9276 c
+122.259 81.8984 122.259 81.8689 122.259 81.8397 c
+122.259 81.8102 122.256 81.7847 122.248 81.7626 c
+122.248 81.7331 122.246 81.7039 122.243 81.6747 c
+122.239 81.6452 122.237 81.616 122.237 81.5865 c
+122.23 81.5279 122.221 81.4692 122.21 81.4105 c
+122.199 81.3518 122.186 81.2932 122.171 81.2345 c
+122.105 80.9706 122.004 80.7194 121.869 80.481 c
+121.733 80.2426 121.559 80.0173 121.346 79.8044 c
+121.141 79.5918 120.895 79.4342 120.609 79.3316 c
+120.323 79.229 120.004 79.1777 119.652 79.1777 c
+119.153 79.1777 118.723 79.2454 118.36 79.3809 c
+117.997 79.5167 117.701 79.7239 117.474 80.0025 c
+117.247 80.2812 117.076 80.5893 116.962 80.9266 c
+116.849 81.264 116.792 81.6268 116.792 82.0154 c
+116.792 82.0375 l
+closepath
+117.837 82.0375 m
+117.837 81.9789 117.837 81.9259 117.837 81.878 c
+117.837 81.8303 117.841 81.781 117.848 81.7297 c
+117.855 81.6781 117.865 81.6288 117.876 81.5812 c
+117.887 81.5335 117.896 81.4839 117.903 81.4326 c
+117.94 81.2713 117.999 81.1134 118.079 80.9595 c
+118.16 80.8056 118.259 80.6588 118.376 80.5196 c
+118.501 80.3801 118.655 80.2775 118.838 80.2115 c
+119.022 80.1454 119.238 80.1125 119.487 80.1125 c
+119.722 80.1125 119.942 80.1454 120.147 80.2115 c
+120.352 80.2775 120.54 80.3764 120.708 80.5085 c
+120.877 80.6406 121.003 80.8331 121.088 81.086 c
+121.172 81.3391 121.214 81.6489 121.214 82.0154 c
+121.214 82.2722 121.178 82.505 121.104 82.7142 c
+121.031 82.9231 120.921 83.1082 120.774 83.2695 c
+120.627 83.4237 120.446 83.541 120.23 83.6215 c
+120.013 83.7023 119.766 83.7426 119.487 83.7426 c
+119.223 83.7426 118.996 83.7077 118.805 83.638 c
+118.615 83.5685 118.457 83.4603 118.332 83.3137 c
+118.207 83.1742 118.107 83.024 118.03 82.8627 c
+117.953 82.7011 117.899 82.5362 117.87 82.3675 c
+117.863 82.3383 117.855 82.3088 117.848 82.2796 c
+117.841 82.2501 117.837 82.2209 117.837 82.1915 c
+117.837 82.1623 117.837 82.1328 117.837 82.1036 c
+117.837 82.0741 117.837 82.0449 117.837 82.0154 c
+117.837 82.0375 l
+closepath
+123.205 82.4667 m
+123.205 82.7598 123.257 83.0368 123.359 83.297 c
+123.462 83.5575 123.616 83.8013 123.821 84.0286 c
+124.034 84.2486 124.283 84.4155 124.569 84.5292 c
+124.855 84.6429 125.182 84.6996 125.548 84.6996 c
+125.607 84.6996 125.671 84.6959 125.741 84.6885 c
+125.811 84.6811 125.886 84.6704 125.966 84.6556 c
+126.047 84.6409 126.129 84.6227 126.214 84.6006 c
+126.298 84.5785 126.384 84.5493 126.472 84.5125 c
+126.626 84.4467 126.773 84.3622 126.912 84.2596 c
+127.052 84.157 127.187 84.0323 127.319 83.8857 c
+127.451 83.7463 127.55 83.5739 127.616 83.3687 c
+127.682 83.1632 127.715 82.9285 127.715 82.6646 c
+127.715 82.6572 127.715 82.6481 127.715 82.6371 c
+127.715 82.626 127.715 82.6133 127.715 82.5985 c
+127.715 82.5911 127.715 82.5821 127.715 82.571 c
+127.715 82.56 127.715 82.5472 127.715 82.5325 c
+127.715 79.2655 l
+126.67 79.2655 l
+126.67 82.3786 l
+126.67 82.5398 126.646 82.6994 126.599 82.857 c
+126.551 83.0146 126.48 83.1632 126.384 83.3026 c
+126.289 83.4492 126.164 83.5592 126.01 83.6326 c
+125.856 83.706 125.673 83.7426 125.46 83.7426 c
+125.262 83.7426 125.088 83.7097 124.938 83.6437 c
+124.788 83.5776 124.657 83.4787 124.547 83.3466 c
+124.437 83.2145 124.351 83.0733 124.289 82.9231 c
+124.227 82.7729 124.184 82.6133 124.162 82.4446 c
+124.162 79.2655 l
+123.205 79.2655 l
+123.205 82.4667 l
+closepath
+0 0 0 rgb
+F
+newpath
+113.172 76.343 m
+113.172 76.6049 113.208 76.8397 113.279 77.0474 c
+113.35 77.2549 113.455 77.4355 113.593 77.5889 c
+113.736 77.7422 113.883 77.8732 114.037 77.9817 c
+114.19 78.0903 114.351 78.1745 114.519 78.2343 c
+114.549 78.2456 114.58 78.2558 114.612 78.2652 c
+114.644 78.2746 114.676 78.2848 114.71 78.2961 c
+114.74 78.3035 114.771 78.3111 114.803 78.3185 c
+114.835 78.3259 114.865 78.3315 114.895 78.3352 c
+114.959 78.3465 115.02 78.3551 115.078 78.3607 c
+115.136 78.3661 115.193 78.3689 115.249 78.3689 c
+115.402 78.3689 115.55 78.3539 115.692 78.3242 c
+115.835 78.2941 115.969 78.2513 116.096 78.1952 c
+116.223 78.1391 116.349 78.0659 116.472 77.9761 c
+116.596 77.8865 116.718 77.7816 116.837 77.662 c
+116.484 77.2745 l
+116.469 77.2821 116.454 77.2915 116.441 77.3026 c
+116.428 77.3139 116.414 77.3269 116.4 77.3419 c
+116.392 77.3493 116.384 77.357 116.377 77.3643 c
+116.369 77.372 116.362 77.3794 116.354 77.3867 c
+116.343 77.3944 116.334 77.4018 116.326 77.4094 c
+116.319 77.4168 116.311 77.4242 116.304 77.4318 c
+116.237 77.4879 116.164 77.5412 116.085 77.5917 c
+116.007 77.6421 115.922 77.6917 115.833 77.7405 c
+115.743 77.7853 115.649 77.8199 115.552 77.8443 c
+115.455 77.8686 115.354 77.8808 115.249 77.8808 c
+115.021 77.8808 114.819 77.8479 114.645 77.7825 c
+114.472 77.717 114.325 77.6189 114.205 77.4879 c
+114.089 77.3607 113.995 77.2252 113.921 77.0809 c
+113.849 76.9369 113.799 76.7864 113.773 76.6293 c
+113.769 76.603 113.764 76.5777 113.759 76.5534 c
+113.753 76.5293 113.75 76.5037 113.75 76.4777 c
+113.747 76.4516 113.745 76.4264 113.745 76.402 c
+113.745 76.3776 113.745 76.3541 113.745 76.3317 c
+113.745 76.1446 113.776 75.964 113.837 75.7903 c
+113.899 75.6162 113.992 75.4507 114.115 75.2934 c
+114.239 75.1363 114.395 75.0156 114.584 74.9314 c
+114.773 74.8472 114.994 74.7996 115.249 74.7885 c
+115.253 74.7885 115.255 74.7885 115.257 74.7885 c
+115.259 74.7885 115.262 74.7885 115.266 74.7885 c
+115.269 74.7885 115.273 74.7885 115.277 74.7885 c
+115.281 74.7885 115.284 74.7885 115.288 74.7885 c
+115.296 74.7885 115.301 74.7885 115.305 74.7885 c
+115.309 74.7885 115.312 74.7885 115.313 74.7885 c
+115.315 74.7885 115.318 74.7885 115.322 74.7885 c
+115.49 74.7845 115.644 74.8072 115.782 74.8557 c
+115.92 74.9044 116.042 74.9793 116.147 75.0802 c
+116.255 75.1774 116.346 75.2814 116.419 75.3917 c
+116.492 75.502 116.549 75.6171 116.59 75.737 c
+116.601 75.7667 116.612 75.7957 116.621 75.8237 c
+116.631 75.8518 116.637 75.879 116.641 75.9054 c
+116.644 75.9201 116.647 75.9343 116.649 75.9473 c
+116.651 75.9603 116.652 75.9745 116.652 75.9895 c
+116.656 76.0006 116.659 76.0128 116.66 76.0258 c
+116.662 76.0389 116.663 76.053 116.663 76.0681 c
+115.294 76.0791 l
+115.294 76.6123 l
+117.236 76.6123 l
+117.236 76.1242 l
+117.213 75.8285 117.148 75.5695 117.039 75.3469 c
+116.931 75.1241 116.781 74.9342 116.59 74.7772 c
+116.396 74.6201 116.187 74.5031 115.964 74.4262 c
+115.742 74.3497 115.503 74.3114 115.249 74.3114 c
+114.95 74.3114 114.676 74.3571 114.429 74.4489 c
+114.183 74.5405 113.964 74.6816 113.773 74.8727 c
+113.582 75.0595 113.436 75.2758 113.335 75.5207 c
+113.234 75.7659 113.18 76.0363 113.172 76.3317 c
+113.172 76.343 l
+closepath
+117.724 76.2138 m
+117.724 76.33 117.746 76.4394 117.791 76.5423 c
+117.836 76.6452 117.905 76.7396 117.999 76.8258 c
+118.092 76.9117 118.201 76.9763 118.324 77.0194 c
+118.448 77.0622 118.586 77.0837 118.74 77.0837 c
+118.848 77.0837 118.944 77.0755 119.026 77.0585 c
+119.108 77.0418 119.175 77.0182 119.228 76.9885 c
+119.28 76.9584 119.329 76.9219 119.374 76.8791 c
+119.419 76.836 119.458 76.7864 119.492 76.7302 c
+119.525 76.775 119.567 76.8173 119.615 76.8564 c
+119.664 76.8958 119.722 76.9341 119.789 76.9715 c
+119.857 77.0089 119.931 77.0369 120.014 77.0557 c
+120.096 77.0744 120.188 77.0837 120.289 77.0837 c
+120.416 77.0837 120.536 77.0661 120.648 77.0304 c
+120.76 76.995 120.865 76.9397 120.962 76.8649 c
+121.059 76.7937 121.133 76.7124 121.184 76.6208 c
+121.234 76.5293 121.261 76.4272 121.265 76.315 c
+121.265 76.3113 121.265 76.3084 121.265 76.3065 c
+121.265 76.3048 121.265 76.3019 121.265 76.298 c
+121.265 76.2943 121.265 76.2914 121.265 76.2897 c
+121.265 76.2878 121.265 76.2849 121.265 76.2812 c
+121.261 76.2775 121.26 76.2747 121.26 76.2727 c
+121.26 76.271 121.26 76.2682 121.26 76.2645 c
+121.26 76.2605 121.26 76.258 121.26 76.256 c
+121.26 76.254 121.26 76.2512 121.26 76.2475 c
+121.26 74.3562 l
+120.771 74.3562 l
+120.771 76.0791 l
+120.771 76.0754 120.771 76.0746 120.771 76.0763 c
+120.771 76.0783 120.773 76.0791 120.777 76.0791 c
+120.777 76.0828 120.777 76.0856 120.777 76.0876 c
+120.777 76.0896 120.777 76.0922 120.777 76.0961 c
+120.777 76.1035 120.777 76.11 120.777 76.1157 c
+120.777 76.1214 120.777 76.1259 120.777 76.1296 c
+120.777 76.1409 120.776 76.1523 120.774 76.1633 c
+120.772 76.1746 120.769 76.1877 120.766 76.2027 c
+120.762 76.2138 120.759 76.226 120.757 76.2393 c
+120.756 76.2523 120.753 76.2662 120.749 76.2812 c
+120.734 76.326 120.712 76.3691 120.682 76.4102 c
+120.651 76.4516 120.616 76.4907 120.575 76.5281 c
+120.534 76.5655 120.489 76.5936 120.44 76.6123 c
+120.392 76.631 120.341 76.6404 120.289 76.6404 c
+120.221 76.6404 120.159 76.6282 120.101 76.6038 c
+120.043 76.5797 119.989 76.5432 119.941 76.4944 c
+119.892 76.4459 119.854 76.3943 119.826 76.3402 c
+119.798 76.286 119.778 76.2288 119.767 76.169 c
+119.763 76.1616 119.76 76.1531 119.758 76.1437 c
+119.756 76.1344 119.755 76.1259 119.755 76.1185 c
+119.755 76.1072 119.755 76.0978 119.755 76.0905 c
+119.755 76.0828 119.755 76.0754 119.755 76.0681 c
+119.755 74.3562 l
+119.273 74.3562 l
+119.273 76.0343 l
+119.273 76.1165 119.262 76.1934 119.239 76.2645 c
+119.217 76.3354 119.183 76.4008 119.138 76.4609 c
+119.093 76.5208 119.037 76.5655 118.97 76.5956 c
+118.903 76.6254 118.826 76.6404 118.74 76.6404 c
+118.631 76.6293 118.541 76.6049 118.47 76.5675 c
+118.399 76.5301 118.347 76.4797 118.313 76.4159 c
+118.279 76.3524 118.254 76.2849 118.237 76.2138 c
+118.22 76.1429 118.212 76.0698 118.212 75.9949 c
+118.212 75.9912 118.212 75.9876 118.212 75.9839 c
+118.212 75.9782 l
+118.212 74.3562 l
+117.724 74.3562 l
+117.724 76.2138 l
+closepath
+122.23 78.2456 m
+122.23 75.7256 l
+122.23 75.576 122.249 75.4422 122.286 75.3242 c
+122.324 75.2066 122.378 75.1026 122.449 75.0127 c
+122.524 74.9231 122.613 74.8557 122.716 74.8109 c
+122.819 74.7658 122.936 74.7434 123.067 74.7434 c
+123.19 74.7434 123.3 74.7613 123.398 74.7967 c
+123.495 74.8324 123.579 74.8857 123.65 74.9566 c
+123.718 75.0277 123.774 75.1026 123.819 75.1811 c
+123.864 75.2599 123.897 75.3401 123.92 75.4226 c
+123.927 75.4413 123.932 75.4609 123.934 75.4816 c
+123.936 75.502 123.939 75.5235 123.942 75.5459 c
+123.946 75.5686 123.949 75.5899 123.95 75.6105 c
+123.952 75.6312 123.953 75.6508 123.953 75.6695 c
+123.953 75.8192 123.934 75.9501 123.894 76.0624 c
+123.855 76.1746 123.798 76.2662 123.723 76.3374 c
+123.649 76.4122 123.569 76.4711 123.485 76.5142 c
+123.401 76.5573 123.313 76.5843 123.224 76.5956 c
+123.213 76.5956 123.202 76.5956 123.193 76.5956 c
+123.184 76.5956 123.175 76.5956 123.168 76.5956 c
+123.164 76.5956 123.159 76.5956 123.154 76.5956 c
+123.148 76.5956 123.143 76.5973 123.14 76.6013 c
+123.132 76.6013 123.126 76.6013 123.123 76.6013 c
+123.119 76.6013 123.115 76.6013 123.112 76.6013 c
+123.056 76.6013 123.003 76.5973 122.954 76.5899 c
+122.906 76.5826 122.861 76.5712 122.82 76.5562 c
+122.779 76.5412 122.738 76.5253 122.699 76.5086 c
+122.66 76.4918 122.62 76.474 122.578 76.4553 c
+122.573 76.4496 l
+122.567 76.4496 l
+122.56 76.4459 122.552 76.4422 122.545 76.4383 c
+122.537 76.4346 122.532 76.4329 122.528 76.4329 c
+122.52 76.4289 122.514 76.4252 122.508 76.4215 c
+122.503 76.4179 122.496 76.4142 122.489 76.4102 c
+122.474 76.4065 122.46 76.402 122.446 76.3963 c
+122.433 76.3906 122.419 76.3841 122.404 76.3768 c
+122.404 76.8762 l
+122.446 76.8949 122.486 76.9136 122.525 76.9323 c
+122.564 76.9511 122.605 76.9678 122.646 76.9828 c
+122.687 76.9978 122.728 77.0109 122.769 77.0222 c
+122.81 77.0333 122.853 77.0426 122.898 77.0503 c
+122.917 77.054 122.936 77.0568 122.957 77.0585 c
+122.978 77.0605 122.999 77.0633 123.022 77.067 c
+123.033 77.067 123.043 77.067 123.053 77.067 c
+123.062 77.067 123.072 77.069 123.084 77.0727 c
+123.091 77.0727 123.1 77.0727 123.112 77.0727 c
+123.123 77.0727 123.134 77.0727 123.145 77.0727 c
+123.321 77.0727 123.486 77.0435 123.639 76.9856 c
+123.793 76.9275 123.937 76.8388 124.071 76.7189 c
+124.206 76.603 124.308 76.4646 124.377 76.3036 c
+124.446 76.1429 124.481 75.9615 124.481 75.7594 c
+124.481 75.5723 124.451 75.3926 124.391 75.2205 c
+124.331 75.0484 124.242 74.8838 124.122 74.7267 c
+124.006 74.5694 123.859 74.4534 123.681 74.3786 c
+123.503 74.3038 123.298 74.2664 123.067 74.2664 c
+122.835 74.2664 122.633 74.3029 122.461 74.3758 c
+122.288 74.4489 122.146 74.56 122.034 74.7097 c
+121.922 74.8633 121.837 75.0269 121.781 75.2009 c
+121.725 75.375 121.697 75.5609 121.697 75.7594 c
+121.697 78.2456 l
+122.23 78.2456 l
+closepath
+124.969 78.2904 m
+125.497 78.2904 l
+125.497 76.6965 l
+127.181 76.6965 l
+127.181 78.2904 l
+127.708 78.2904 l
+127.708 74.3562 l
+127.181 74.3562 l
+127.181 76.169 l
+125.497 76.169 l
+125.497 74.3562 l
+124.969 74.3562 l
+124.969 78.2904 l
+closepath
+F
+%%PageTrailer
+showpage
+%%Trailer
+end
+%%DocumentSuppliedResources: procset Linux-Sketch-Procset 1.0 2
+%%EOF
Binary file flys-artifacts/doc/datacage-config-manual/figures/intevation-logo.pdf has changed
--- a/flys-artifacts/pom.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/pom.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -21,8 +21,8 @@
           <artifactId>maven-compiler-plugin</artifactId>
           <version>2.0.2</version>
           <configuration>
-              <source>1.5</source>
-              <target>1.5</target>
+              <source>1.6</source>
+              <target>1.6</target>
           </configuration>
       </plugin>
       <plugin>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/AbstractStaticStateArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,69 @@
+package de.intevation.flys.artifacts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.intevation.artifactdatabase.state.State;
+
+/**
+ * A abstract baseclass for Artifacts which are using only one static state.
+ *
+ * This class is intended to be used without the config/stateengine to generate
+ * the static state.
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public abstract class AbstractStaticStateArtifact extends StaticFLYSArtifact {
+
+    private transient State staticstate;
+
+    /**
+     * Get a list containing the one and only State.
+     * @param  context ignored.
+     * @return list with one and only state.
+     */
+    @Override
+    protected List<State> getStates(Object context) {
+        ArrayList<State> states = new ArrayList<State>();
+        states.add(getStaticState());
+        return states;
+    }
+
+
+    /**
+     * Get the "current" state.
+     * @param cc ignored.
+     * @return always the set static state.
+     */
+    @Override
+    public State getCurrentState(Object cc) {
+        return getStaticState();
+    }
+
+    /**
+     * A child class must override this method to set its static state
+     */
+    protected abstract void initStaticState();
+
+    protected void setStaticState(State state) {
+        this.staticstate = state;
+    }
+
+    protected State getStaticState() {
+        if (staticstate == null) {
+            initStaticState();
+        }
+        return staticstate;
+    }
+
+    /**
+     * Get the state.
+     * @param context ignored.
+     * @param stateID ignored.
+     * @return the state.
+     */
+    @Override
+    protected State getState(Object context, String stateID) {
+        return getStaticState();
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/AnnotationArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/AnnotationArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -160,13 +160,13 @@
             DefaultState state = (DefaultState) engine.getState(stateId);
 
             List<Output> list = state.getOutputs();
-            if (list == null || list.size() == 0) {
+            if (list == null || list.isEmpty()) {
                 logger.debug("-> No output modes for this state.");
                 continue;
             }
 
             List<Facet> fs = facets.get(stateId);
-            if (fs == null || fs.size() == 0) {
+            if (fs == null || fs.isEmpty()) {
                 logger.debug("No facets found.");
                 continue;
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/BedHeightsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,163 @@
+package de.intevation.flys.artifacts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
+import de.intevation.artifactdatabase.state.State;
+import de.intevation.artifacts.ArtifactFactory;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.artifacts.model.minfo.BedHeight;
+import de.intevation.flys.artifacts.model.minfo.BedHeightFacet;
+import de.intevation.flys.artifacts.model.minfo.BedHeightFactory;
+import de.intevation.flys.artifacts.states.StaticState;
+
+public class BedHeightsArtifact
+extends      StaticFLYSArtifact
+{
+    /** The logger for this class. */
+    private static Logger logger =
+        Logger.getLogger(BedHeightsArtifact.class);
+
+    private static final String NAME = "bedheights";
+
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance()
+            .register(NAME, FacetActivity.INACTIVE);
+    }
+
+    public static final String STATIC_STATE_NAME =
+        "state.additional_bedheights.static";
+
+    /** Data Item name to know whether we are Heighmarks and reveive
+     * some data slightly different. */
+    public static final String DATA_HEIGHT_TYPE =
+        "height_marks";
+
+    /** One and only state to be in. */
+    protected transient State state = null;
+
+
+    /**
+     * Trivial Constructor.
+     */
+    public BedHeightsArtifact() {
+        logger.debug("BedHeightsArtifact.BedHeightsArtifact");
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    /**
+     * Gets called from factory, to set things up.
+     */
+    @Override
+    public void setup(
+        String          identifier,
+        ArtifactFactory factory,
+        Object          context,
+        CallMeta        callMeta,
+        Document        data)
+    {
+        logger.debug("BedHeightsArtifact.setup");
+
+        state = new StaticState(STATIC_STATE_NAME);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug(XMLUtils.toString(data));
+        }
+
+        List<Facet> fs = new ArrayList<Facet>();
+        String code = getDatacageIDValue(data);
+
+        if (code != null) {
+            String [] parts = code.split("-");
+
+            if (parts.length >= 4) {
+                if (parts[0].equals("bedheight")) {
+                    addStringData("type", parts[1]);
+                    addStringData("height_id", parts[2]);
+                    addStringData("time", parts[3]);
+                }
+                int hId = Integer.parseInt(parts[2]);
+                String bedHName = BedHeightFactory.getHeightName(parts[1], hId);
+
+                Facet bedHFacet = new BedHeightFacet(
+                    "bedheight",
+                    bedHName);
+
+                fs.add(bedHFacet);
+                facets.put(state.getID(), fs);
+            }
+        }
+
+        //spawnState();
+        super.setup(identifier, factory, context, callMeta, data);
+    }
+
+    /**
+     * Get a list containing the one and only State.
+     * @param  context ignored.
+     * @return list with one and only state.
+     */
+    @Override
+    protected List<State> getStates(Object context) {
+        ArrayList<State> states = new ArrayList<State>();
+        states.add(getState());
+        return states;
+    }
+
+    /**
+     * Get the "current" state (there is but one).
+     * @param cc ignored.
+     * @return the "current" (only possible) state.
+     */
+    @Override
+    public State getCurrentState(Object cc) {
+        return getState();
+    }
+
+
+    /**
+     * Get the only possible state.
+     * @return the state.
+     */
+    protected State getState() {
+        return getState(null, null);
+    }
+
+
+    /**
+     * Get the state.
+     * @param context ignored.
+     * @param stateID ignored.
+     * @return the state.
+     */
+    @Override
+    protected State getState(Object context, String stateID) {
+        return (state != null)
+            ? state
+            : new StaticState(STATIC_STATE_NAME);
+    }
+
+    /**
+     * Get WKms from factory.
+     * @param idx param is not needed (TODO?)
+     * @return WKms according to parameterization (can be null);
+     */
+    public BedHeight getHeight() {
+        return BedHeightFactory.getHeight(
+            getDataAsString("type"),
+            Integer.parseInt(getDataAsString("height_id")),
+            Integer.parseInt(getDataAsString("time")));
+    }
+
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/ChartArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/ChartArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -30,6 +30,7 @@
 import de.intevation.flys.artifacts.resources.Resources;
 
 
+/** Artifact, open to generate any (?) out. */
 public class ChartArtifact extends FLYSArtifact {
 
     private static final Logger logger =
@@ -95,14 +96,14 @@
             DefaultState state = (DefaultState) engine.getState(stateId);
 
             List<Output> list = state.getOutputs();
-            if (list == null || list.size() == 0) {
+            if (list == null || list.isEmpty()) {
                 logger.debug("-> No output modes for this state.");
                 continue;
             }
 
             List<Facet> fs = facets.get(stateId);
 
-            if (fs == null || fs.size() == 0) {
+            if (fs == null || fs.isEmpty()) {
                 logger.debug("No facets for previous state found.");
                 continue;
             }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CollectionMonitor.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CollectionMonitor.java	Fri Sep 28 12:15:40 2012 +0200
@@ -28,7 +28,6 @@
 
     public static final String XPATH_RESULT = "/art:result";
 
-
     private static final Logger logger =
         Logger.getLogger(CollectionMonitor.class);
 
@@ -60,6 +59,9 @@
         Map<String, Object> params = getNoneUserSpecificParameters(flys, context);
 
         Recommendations rec = Recommendations.getInstance();
+
+        // TODO For newer official-lines recommendations we actually
+        // need user-id (null here).
         rec.recommend(flys, null, outs, params, recommended);
     }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -24,6 +24,7 @@
 import de.intevation.flys.artifacts.states.StaticState;
 
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 import de.intevation.artifactdatabase.state.State;
 
 import de.intevation.flys.utils.FLYSUtils;
@@ -64,6 +65,26 @@
     private static final Logger logger =
         Logger.getLogger(CrossSectionArtifact.class);
 
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance().register(
+            CS_ARTIFACT_NAME,
+            new FacetActivity() {
+                @Override
+                public Boolean isInitialActive(
+                    Artifact artifact,
+                    Facet    facet,
+                    String   outputName
+                ) {
+                    if (artifact instanceof FLYSArtifact) {
+                        FLYSArtifact flys = (FLYSArtifact)artifact;
+                        String data = flys.getDataAsString(DATA_IS_NEWEST);
+                        return data != null && data.equals("1");
+                    }
+                    return null;
+                }
+            });
+    }
 
     /** Return given name. */
     @Override
@@ -97,7 +118,7 @@
 
         List<Facet> fs = new ArrayList<Facet>();
         CrossSection cs = CrossSectionFactory.getCrossSection(
-            Integer.valueOf(ids));
+            Integer.parseInt(ids));
 
         List<CrossSectionLine> csls = cs.getLines();
         if (!csls.isEmpty()) {
@@ -198,7 +219,7 @@
     public int getDataAsIntNull(String dataName) {
         String val = getDataAsString(dataName);
         try {
-            return Integer.valueOf(val);
+            return Integer.parseInt(val);
         }
         catch (NumberFormatException e) {
             logger.warn("Could not get data " + dataName + " as int", e);
@@ -320,22 +341,5 @@
         return FastCrossSectionLineFactory
             .getCrossSectionLine(crossSection, km);
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param outputName Ignored.
-     * @param facetName Ignored.
-     * @param index     Ignored.
-     * @return 0 if not active
-     */
-    @Override
-    public int getInitialFacetActivity(String outputName, String facetName, int index) {
-        return (getDataAsString(DATA_IS_NEWEST) != null
-            && getDataAsString(DATA_IS_NEWEST).equals("1")) ? 1 : 0;
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,5 +1,25 @@
 package de.intevation.flys.artifacts;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.xml.xpath.XPathConstants;
+
+import net.sf.ehcache.Cache;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
 import de.intevation.artifactdatabase.ArtifactDatabaseImpl;
 import de.intevation.artifactdatabase.DefaultArtifact;
 import de.intevation.artifactdatabase.ProtocolUtils;
@@ -29,26 +49,6 @@
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
 import de.intevation.flys.utils.FLYSUtils;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import javax.xml.xpath.XPathConstants;
-
-import net.sf.ehcache.Cache;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
 /**
  * The default FLYS artifact with convenience added.
  * (Subclass to get fully functional artifacts).
@@ -58,7 +58,7 @@
 public abstract class FLYSArtifact extends DefaultArtifact {
 
     /** The logger that is used in this artifact. */
-    private static Logger logger = Logger.getLogger(FLYSArtifact.class);
+    private static Logger log = Logger.getLogger(FLYSArtifact.class);
 
     public static final String COMPUTING_CACHE = "computed.values";
 
@@ -92,7 +92,7 @@
     protected String name;
 
     /** The data that have been inserted into this artifact. */
-    protected Map<String, StateData> data;
+    private Map<String, StateData> data;
 
     /** Mapping of state names to created facets. */
     protected Map<String, List<Facet>> facets;
@@ -134,8 +134,12 @@
         StateEngine engine      = (StateEngine) flysContext.get(
             FLYSContext.STATE_ENGINE_KEY);
 
+        boolean debug = log.isDebugEnabled();
+
         for (String stateId: stateIds) {
-            logger.debug("Append static data for state: " + stateId);
+            if (debug) {
+                log.debug("Append static data for state: " + stateId);
+            }
             DefaultState state = (DefaultState) engine.getState(stateId);
 
             ui.appendChild(state.describeStatic(this, doc, ui, context, uuid));
@@ -170,7 +174,11 @@
         CallMeta        callMeta,
         Document        data)
     {
-        logger.debug("Setup this artifact with the uuid: " + identifier);
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug("Setup this artifact with the uuid: " + identifier);
+        }
 
         super.setup(identifier, factory, context, callMeta, data);
 
@@ -179,10 +187,13 @@
         List<State> states = getStates(context);
 
         String name = getName();
-        logger.debug("Set initial state for artifact '" + name + "'");
+
+        if (debug) {
+            log.debug("setup(): Set initial state for artifact '" + name + "'");
+        }
 
         if (states == null) {
-            logger.error("No states found from which an initial "
+            log.error("No states found from which an initial "
                 + "state could be picked.");
         }
         setCurrentState(states.get(0));
@@ -200,7 +211,7 @@
                 initialize(db.getRawArtifact(model), context, callMeta);
             }
             catch (ArtifactDatabaseException adbe) {
-                logger.error(adbe, adbe);
+                log.error(adbe, adbe);
             }
         }
 
@@ -222,14 +233,14 @@
      */
     protected void importData(FLYSArtifact other, final String name) {
         if (other == null) {
-            logger.error("No other art. to import data " + name + " from.");
+            log.error("No other art. to import data " + name + " from.");
             return;
         }
 
         StateData sd = other.getData(name);
 
         if (sd == null) {
-            logger.warn("Other artifact has no data " + name + ".");
+            log.warn("Other artifact has no data " + name + ".");
             return;
         }
 
@@ -345,7 +356,7 @@
                     index = Integer.parseInt(facetElement.getAttribute("index"));
                 }
                 catch (NumberFormatException nfe) {
-                    logger.warn(nfe);
+                    log.warn(nfe);
                     index = 0;
                 }
                 facets.add(new DefaultFacet(index, fName, ""));
@@ -370,7 +381,7 @@
      */
     @Override
     public Document feed(Document target, CallContext context) {
-        logger.info("FLYSArtifact.feed()");
+        log.debug("FLYSArtifact.feed()");
 
         Document doc = XMLUtils.newDocument();
 
@@ -383,7 +394,7 @@
         doc.appendChild(result);
 
         try {
-            saveData(target, XPATH_FEED_INPUT, context);
+            saveData(target, context);
 
             compute(context, ComputeType.FEED, true);
 
@@ -410,9 +421,10 @@
      */
     @Override
     public Document describe(Document data, CallContext context) {
-        logger.debug("Describe: the current state is: " + getCurrentStateId());
 
-        if (logger.isDebugEnabled()) {
+        if (log.isDebugEnabled()) {
+            log.debug(
+                "Describe: the current state is: " + getCurrentStateId());
             dumpArtifact();
         }
 
@@ -529,7 +541,10 @@
         String      uuid)
     {
         List<Output> generated = getOutputs(context);
-        logger.debug("This Artifact has " + generated.size() + " Outputs.");
+
+        if (log.isDebugEnabled()) {
+            log.debug("This Artifact has " + generated.size() + " Outputs.");
+        }
 
         ProtocolUtils.appendOutputModes(doc, outs, generated);
     }
@@ -546,6 +561,9 @@
      */
     @Override
     public Document advance(Document target, CallContext context) {
+
+        boolean debug = log.isDebugEnabled();
+
         Document doc = XMLUtils.newDocument();
 
         XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
@@ -559,25 +577,33 @@
         String targetState    = XMLUtils.xpathString(
             target, XPATH_ADVANCE_TARGET, ArtifactNamespaceContext.INSTANCE);
 
-        logger.info("FLYSArtifact.advance() to '" + targetState + "'");
+        if (debug) {
+            log.debug("FLYSArtifact.advance() to '" + targetState + "'");
+        }
 
         if (!currentStateId.equals(targetState)
             && isStateReachable(targetState, context))
         {
-            logger.info("Advance: Step forward");
+            if (debug) {
+                log.debug("Advance: Step forward");
+            }
 
             List<String> prev = getPreviousStateIds();
             prev.add(currentStateId);
 
             setCurrentStateId(targetState);
 
-            logger.debug("Compute data for state: " + targetState);
+            if (debug) {
+                log.debug("Compute data for state: " + targetState);
+            }
             compute(context, ComputeType.ADVANCE, true);
 
             return describe(target, context);
         }
         else if (isPreviousState(targetState, context)) {
-            logger.info("Advance: Step back to");
+            if (debug) {
+                log.debug("Advance: Step back to");
+            }
 
             List<String> prevs   = getPreviousStateIds();
             int targetIdx        = prevs.indexOf(targetState);
@@ -587,7 +613,9 @@
 
             for (int i = start; i >= targetIdx; i--) {
                 String prev = prevs.get(i);
-                logger.debug("Remove state id '" + prev + "'");
+                if (debug) {
+                    log.debug("Remove state id '" + prev + "'");
+                }
 
                 prevs.remove(prev);
                 facets.remove(prev);
@@ -599,7 +627,7 @@
             return describe(target, context);
         }
 
-        logger.warn("Advance: Cannot advance to '" + targetState + "'");
+        log.warn("Advance: Cannot advance to '" + targetState + "'");
         ec.addAttr(result, "type", OPERATION_FAILED, true);
 
         doc.appendChild(result);
@@ -729,6 +757,12 @@
         return data.get(name);
     }
 
+    /**
+     * A derived Artifact class can use this method to set the data
+     */
+    protected void setData(Map<String, StateData> data) {
+        this.data = data;
+    }
 
     /** Return named data item, null if not found. */
     public String getDataAsString(String name) {
@@ -841,7 +875,10 @@
         addData(name, new DefaultStateData(name, null, null, value));
     }
 
-
+    /**
+     * This method returns all stored StateData in this artifact as a Collection
+     * @return a Collection of all StateData objects in this artifact
+     */
     public Collection<StateData> getAllData() {
         return data.values();
     }
@@ -850,12 +887,8 @@
     public List<Facet> getFacets() {
         List<Facet> all = new ArrayList<Facet>();
 
-        Set<Map.Entry<String, List<Facet>>> entries = facets.entrySet();
-        for (Map.Entry<String, List<Facet>> entry: entries) {
-            List<Facet> fs = entry.getValue();
-            for (Facet f: fs) {
-                all.add(f);
-            }
+        for (List<Facet> fs: facets.values()) {
+            all.addAll(fs);
         }
 
         return all;
@@ -872,15 +905,15 @@
         String name  = facet.getName();
         int    index = facet.getIndex();
 
-        for (Map.Entry<String, List<Facet>> facetList: facets.entrySet()) {
-            for (Facet f: facetList.getValue()) {
+        for (List<Facet> fs: facets.values()) {
+            for (Facet f: fs) {
                 if (f.getIndex() == index && f.getName().equals(name)) {
                     return f;
                 }
             }
         }
 
-        logger.warn("Could not find facet: " + name + " at " + index);
+        log.warn("Could not find facet: " + name + " at " + index);
         return null;
     }
 
@@ -891,16 +924,16 @@
      * @param feed The FEED document.
      * @param xpath The XPath that points to the data nodes.
      */
-    public void saveData(Document feed, String xpath, CallContext context)
+    public void saveData(Document feed, CallContext context)
     throws IllegalArgumentException
     {
-        if (feed == null || xpath == null || xpath.length() == 0) {
+        if (feed == null) {
             throw new IllegalArgumentException("error_feed_no_data");
         }
 
         NodeList nodes = (NodeList) XMLUtils.xpath(
             feed,
-            xpath,
+            XPATH_FEED_INPUT,
             XPathConstants.NODESET,
             ArtifactNamespaceContext.INSTANCE);
 
@@ -908,8 +941,13 @@
             throw new IllegalArgumentException("error_feed_no_data");
         }
 
+        boolean debug = log.isDebugEnabled();
+
         int count = nodes.getLength();
-        logger.debug("Try to save " + count + " data items.");
+
+        if (debug) {
+            log.debug("Try to save " + count + " data items.");
+        }
 
         String uri = ArtifactNamespaceContext.NAMESPACE_URI;
 
@@ -926,7 +964,9 @@
             String value = node.getAttributeNS(uri, "value");
 
             if (name.length() > 0 && value.length() > 0) {
-                logger.debug("Save data item for '" + name + "' : " + value);
+                if (debug) {
+                    log.debug("Save data item for '" + name + "' : " + value);
+                }
 
                 StateData model = engine.getStateData(getName(), name);
 
@@ -938,8 +978,8 @@
                     name, current.transform(this, context, sd, name, value));
             }
             else if (name.length() > 0 && value.length() == 0) {
-                if (removeData(name) != null) {
-                    logger.debug("Removed data '" + name + "' successfully.");
+                if (removeData(name) != null && debug) {
+                    log.debug("Removed data '" + name + "' successfully.");
                 }
             }
         }
@@ -960,7 +1000,10 @@
      * otherwise false.
      */
     protected boolean isStateReachable(String stateId, Object context) {
-        logger.debug("Determine if the state '" + stateId + "' is reachable.");
+
+        if (log.isDebugEnabled()) {
+            log.debug("Determine if the state '" + stateId + "' is reachable.");
+        }
 
         FLYSContext flysContext = FLYSUtils.getFlysContext(context);
 
@@ -983,14 +1026,11 @@
      * @param context The context object.
      */
     protected boolean isPreviousState(String stateId, Object context) {
-        logger.debug("Determine if the state '" + stateId + "' is old.");
-
-        List<String> prevs = getPreviousStateIds();
-        if (prevs.contains(stateId)) {
-            return true;
+        if (log.isDebugEnabled()) {
+            log.debug("Determine if the state '" + stateId + "' is old.");
         }
 
-        return false;
+        return getPreviousStateIds().contains(stateId);
     }
 
 
@@ -1026,26 +1066,32 @@
      */
     protected List<Output> filterOutputs(List<Output> outs) {
         if (filterFacets == null || filterFacets.isEmpty()) {
-            logger.debug("No filter for Outputs.");
+            log.debug("No filter for Outputs.");
             return outs;
         }
 
-        logger.debug("Filter Facets with " + filterFacets.size() + " filters.");
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug(
+                "Filter Facets with " + filterFacets.size() + " filters.");
+        }
 
         List<Output> filtered = new ArrayList<Output>();
 
         for (Output out: outs) {
             String outName = out.getName();
 
-            logger.debug("  filter Facets for Output: " + outName);
+            if (debug) {
+                log.debug("  filter Facets for Output: " + outName);
+            }
 
             List<Facet> fFacets = filterFacets.get(outName);
             if (fFacets != null) {
-                logger.debug("" + fFacets.size() + " filters for: " + outName);
-
-                if (logger.isDebugEnabled()) {
+                if (debug) {
+                    log.debug("" + fFacets.size() + " filters for: " + outName);
                     for (Facet tmp: fFacets) {
-                        logger.debug("   filter = '" + tmp.getName() + "'");
+                        log.debug("   filter = '" + tmp.getName() + "'");
                     }
                 }
 
@@ -1061,7 +1107,10 @@
                     }
                 }
 
-                logger.debug("Facets after filtering = " + resultFacets.size());
+                if (debug) {
+                    log.debug(
+                        "Facets after filtering = " + resultFacets.size());
+                }
 
                 if (!resultFacets.isEmpty()) {
                     DefaultOutput nout = new DefaultOutput(
@@ -1074,7 +1123,9 @@
             }
         }
 
-        logger.debug("All Facets after filtering = " + filtered.size());
+        if (debug) {
+            log.debug("All Facets after filtering = " + filtered.size());
+        }
 
         return filtered;
     }
@@ -1087,9 +1138,10 @@
      * @return list of outputs
      */
     public List<Output> getOutputs(Object context) {
-        logger.debug("##### Get Outputs for: " + identifier() + " #####");
-
-        dumpArtifact();
+        if (log.isDebugEnabled()) {
+            log.debug("##### Get Outputs for: " + identifier() + " #####");
+            dumpArtifact();
+        }
 
         List<String> stateIds  = getPreviousStateIds();
         List<Output> generated = new ArrayList<Output>();
@@ -1129,11 +1181,23 @@
      * @return list of output(s) for given state.
      */
     protected List<Output> getOutputForState(DefaultState state) {
-        logger.debug("Find Outputs for State: " + state.getID());
+
+        if (state == null) {
+            log.error("state == null: This should not happen!");
+            return new ArrayList<Output>();
+        }
+
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug("Find Outputs for State: " + state.getID());
+        }
 
         List<Output> list = state.getOutputs();
-        if (list == null || list.size() == 0) {
-            logger.debug("-> No output modes for this state.");
+        if (list == null || list.isEmpty()) {
+            if (debug) {
+                log.debug("-> No output modes for this state.");
+            }
             return new ArrayList<Output>();
         }
 
@@ -1141,14 +1205,18 @@
 
         List<Facet> fs = facets.get(stateId);
 
-        if (fs == null || fs.size() == 0) {
-            logger.debug("No facets found.");
+        if (fs == null || fs.isEmpty()) {
+            if (debug) {
+                log.debug("No facets found.");
+            }
             return new ArrayList<Output>();
         }
 
         List<Output> gen = generateOutputs(list, fs);
 
-        logger.debug("State '" + stateId + "' has " + gen.size() + " outs");
+        if (debug) {
+            log.debug("State '" + stateId + "' has " + gen.size() + " outs");
+        }
 
         return gen;
     }
@@ -1164,7 +1232,7 @@
     protected List<Output> generateOutputs(List<Output> list, List<Facet> fs) {
         List<Output> generated = new ArrayList<Output>();
 
-        boolean debug = logger.isDebugEnabled();
+        boolean debug = log.isDebugEnabled();
 
         for (Output out: list) {
             Output o = new DefaultOutput(
@@ -1177,7 +1245,7 @@
 
             for (Facet f: out.getFacets()) {
                 if (outTypes.add(f.getName()) && debug) {
-                    logger.debug("configured facet " + f);
+                    log.debug("configured facet " + f);
                 }
             }
 
@@ -1187,7 +1255,7 @@
 
                 if (outTypes.contains(type)) {
                     if (debug) {
-                        logger.debug("Add facet " + f);
+                        log.debug("Add facet " + f);
                     }
                     facetAdded = true;
                     o.addFacet(f);
@@ -1291,12 +1359,12 @@
             if (cache != null) {
                 net.sf.ehcache.Element element = cache.get(key);
                 if (element != null) {
-                    logger.debug("Got computation result from cache.");
+                    log.debug("Got computation result from cache.");
                     old = element.getValue();
                 }
             }
             else {
-                logger.debug("cache not configured.");
+                log.debug("cache not configured.");
             }
 
             Object res;
@@ -1314,7 +1382,7 @@
             }
 
             if (cache != null && old != res && res != null) {
-                logger.debug("Store computation result to cache.");
+                log.debug("Store computation result to cache.");
                 net.sf.ehcache.Element element =
                     new net.sf.ehcache.Element(key, res);
                 cache.put(element);
@@ -1328,69 +1396,79 @@
                     facets.remove(stateID);
                 }
                 else {
-                    facets.put(stateID, fs);
+                    addFacets(stateID, fs);
                 }
             }
         }
     }
 
+    /**
+     * Sets the facets for an ID
+     *
+     * Normally the id is a state ID.
+     *
+     * @param id ID to map the facets to
+     * @param facets List of facets to be stored
+     */
+    protected void addFacets(String id, List<Facet> facets) {
+        this.facets.put(id, facets);
+    }
+
 
     /**
      * Method to dump the artifacts state/data.
      */
     protected void dumpArtifact() {
-        if (logger.isDebugEnabled()) {
-            logger.debug("++++++++++++++ DUMP ARTIFACT DATA +++++++++++++++++");
-            // Include uuid, type, name
-
-            logger.debug("------ DUMP DATA ------");
-            Collection<StateData> allData = data.values();
-
-            for (StateData d: allData) {
-                String name  = d.getName();
-                String value = (String) d.getValue();
-
-                logger.debug("- " + name + ": " + value);
-            }
+        log.debug("++++++++++++++ DUMP ARTIFACT DATA +++++++++++++++++");
+        // Include uuid, type, name
 
-            logger.debug("------ DUMP PREVIOUS STATES ------");
-            List<String> stateIds = getPreviousStateIds();
-
-            for (String id: stateIds) {
-                logger.debug("- State: " + id);
-            }
+        log.debug("------ DUMP DATA ------");
+        Collection<StateData> allData = data.values();
 
-            logger.debug("CURRENT STATE: " + getCurrentStateId());
+        for (StateData d: allData) {
+            String name  = d.getName();
+            String value = (String) d.getValue();
 
-            debugFacets();
-            dumpFilterFacets();
+            log.debug("- " + name + ": " + value);
+        }
 
-            logger.debug("++++++++++++++ END ARTIFACT DUMP +++++++++++++++++");
+        log.debug("------ DUMP PREVIOUS STATES ------");
+        List<String> stateIds = getPreviousStateIds();
+
+        for (String id: stateIds) {
+            log.debug("- State: " + id);
         }
+
+        log.debug("CURRENT STATE: " + getCurrentStateId());
+
+        debugFacets();
+        dumpFilterFacets();
+
+        log.debug("++++++++++++++ END ARTIFACT DUMP +++++++++++++++++");
     }
 
 
     protected void debugFacets() {
-        logger.debug("######### FACETS #########");
+        log.debug("######### FACETS #########");
         Set<Map.Entry<String, List<Facet>>> entries = facets.entrySet();
 
         for (Map.Entry<String, List<Facet>> entry: entries) {
             String out = entry.getKey();
             List<Facet> fs = entry.getValue();
             for (Facet f: fs) {
-                logger.debug("  # " + out + " : " + f.getName());
+                log.debug("  # " + out + " : " + f.getName());
             }
         }
 
-        logger.debug("######## FACETS END ########");
+        log.debug("######## FACETS END ########");
     }
 
 
     protected void dumpFilterFacets() {
-        logger.debug("######## FILTER FACETS ########");
+        log.debug("######## FILTER FACETS ########");
 
         if (filterFacets == null || filterFacets.isEmpty()) {
-            logger.debug("No Filter Facets defined.");
+            log.debug("No Filter Facets defined.");
             return;
         }
 
@@ -1399,14 +1477,14 @@
             String      out     = entry.getKey();
             List<Facet> filters = entry.getValue();
 
-            logger.debug("There are " + filters.size() + " filters for: " +out);
+            log.debug("There are " + filters.size() + " filters for: " +out);
 
             for (Facet filter: filters) {
-                logger.debug("  filter: " + filter.getName());
+                log.debug("  filter: " + filter.getName());
             }
         }
 
-        logger.debug("######## FILTER FACETS END ########");
+        log.debug("######## FILTER FACETS END ########");
     }
 
 
@@ -1434,7 +1512,9 @@
      */
     @Override
     public void endOfLife(Object context) {
-        logger.info("FLYSArtifact.endOfLife: " + identifier());
+        if (log.isDebugEnabled()) {
+            log.debug("FLYSArtifact.endOfLife: " + identifier());
+        }
 
         ArrayList<String> ids       = (ArrayList<String>) getPreviousStateIds();
         ArrayList<String> toDestroy = (ArrayList<String>) ids.clone();
@@ -1443,27 +1523,5 @@
 
         destroyStates(toDestroy, context);
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName  name of the facet.
-     * @param outputName name of the output.
-     * @param index      index of the facet.
-     *
-     * @return 1 if wished to be initally active, 0 if not. FLYSArtifact
-     *         defaults to "1".
-     */
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index
-    )
-    {
-        return 1;
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FixationArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FixationArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,5 @@
 package de.intevation.flys.artifacts;
 
-import de.intevation.flys.artifacts.model.FacetTypes;
-
 import org.apache.log4j.Logger;
 
 /**
@@ -11,8 +9,7 @@
  */
 public class FixationArtifact
 extends      FLYSArtifact
-implements   FacetTypes {
-
+{
     /** The logger for this class. */
     private static Logger logger = Logger.getLogger(FixationArtifact.class);
 
@@ -23,6 +20,7 @@
      * The default constructor.
      */
     public FixationArtifact() {
+        logger.debug("ctor()");
     }
 
     /**
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/GaugeDischargeArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/GaugeDischargeArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -170,6 +170,7 @@
         double [][] values = map.get(name);
         if (values == null) {
             logger.error("No values for this gauge / discharge found.");
+            return error(new WQKms[0], "no.gauge.found");
         }
         for (int i = 0 ; i < values[0].length; i++) {
             values[0][i] += gauge.getDatum().doubleValue();
@@ -182,24 +183,5 @@
             res.toArray(new WQKms[res.size()]),
             new Calculation());
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     * @return 1 - all Facets enter activated.
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 1;
-    }
 }
 // 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-artifacts/src/main/java/de/intevation/flys/artifacts/GaugeDischargeCurveArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,99 @@
+package de.intevation.flys.artifacts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.DefaultOutput;
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.ArtifactFactory;
+import de.intevation.artifacts.CallMeta;
+
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.flys.artifacts.states.StaticState;
+import de.intevation.flys.artifacts.StaticFLYSArtifact;
+import de.intevation.flys.artifacts.model.GaugeDischargeCurveFacet;
+
+import de.intevation.flys.model.Gauge;
+
+import de.intevation.flys.utils.FLYSUtils;
+
+/**
+ * Artifact to calculate a discharge curve from a gauge overview info
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeDischargeCurveArtifact
+extends      AbstractStaticStateArtifact
+{
+
+    private static final Logger logger =
+        Logger.getLogger(GaugeDischargeCurveArtifact.class);
+
+    public static final String XPATH_RIVER = "/art:action/art:river/@name";
+    public static final String XPATH_GAUGE = "/art:action/art:gauge/@reference";
+    public static final String NAME = "gaugedischargecurve";
+    public static final String STATIC_STATE_NAME = "state.gaugedischargecurve.static";
+
+    /**
+     * Setup initializes the data by extracting the river and gauge from
+     * the XML Document.
+     */
+    @Override
+    public void setup(
+        String          identifier,
+        ArtifactFactory factory,
+        Object          context,
+        CallMeta        callmeta,
+        Document        data)
+    {
+        logger.debug("GaugeDischargeCurveArtifact.setup");
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("GaugeDischargeCurveState.setup" + XMLUtils.toString(data));
+        }
+        String gaugeref = XMLUtils.xpathString(data, XPATH_GAUGE,
+                ArtifactNamespaceContext.INSTANCE);
+        String rivername = XMLUtils.xpathString(data, XPATH_RIVER,
+                ArtifactNamespaceContext.INSTANCE);
+
+        addStringData("river", rivername);
+        addStringData("reference_gauge", gaugeref);
+
+        Gauge gauge = FLYSUtils.getReferenceGauge(this);
+
+        Facet gfacet = new GaugeDischargeCurveFacet(rivername, gauge);
+
+        List<Facet> fs = new ArrayList<Facet>(1);
+        fs.add(gfacet);
+
+        addFacets(STATIC_STATE_NAME, fs);
+
+        super.setup(identifier, factory, context, callmeta, data);
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    protected void initStaticState() {
+        StaticState state = new StaticState(STATIC_STATE_NAME);
+        List<Facet> fs = facets.get(STATIC_STATE_NAME);
+        DefaultOutput output = new DefaultOutput(
+            "discharge_curve",
+            "output.discharge_curve", "image/png",
+            fs,
+            "chart");
+
+        state.addOutput(output);
+        setStaticState(state);
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/HYKArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/HYKArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -15,6 +15,7 @@
 import de.intevation.flys.artifacts.states.DefaultState;
 
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 
 
 /**
@@ -35,6 +36,11 @@
     private static final Logger logger =
         Logger.getLogger(HYKArtifact.class);
 
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance()
+            .register(HYK_ARTIFACT_NAME, FacetActivity.INACTIVE);
+    }
 
     /** Return given name. */
     @Override
@@ -99,8 +105,7 @@
         CallMeta callMeta)
     {
         logger.debug("HYKArtifact.initialize");
-        WINFOArtifact winfo = (WINFOArtifact) artifact;
-        importData(winfo, "river");
+        importData((FLYSArtifact)artifact, "river");
 
         List<Facet> fs = new ArrayList<Facet>();
 
@@ -115,25 +120,5 @@
                 + state.getID() + ").");
         }
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     *
-     * @return Always 0. Hyk Data will enter plots inactive.
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 0;
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,5 @@
 package de.intevation.flys.artifacts;
 
-import de.intevation.flys.artifacts.model.FacetTypes;
-
 /**
  * The default MINFO artifact.
  *
@@ -9,8 +7,7 @@
  */
 public class MINFOArtifact
 extends      FLYSArtifact
-implements   FacetTypes {
-
+{
     /** The name of the artifact. */
     public static final String ARTIFACT_NAME = "minfo";
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -9,6 +9,7 @@
 
 import de.intevation.artifactdatabase.data.DefaultStateData;
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 import de.intevation.artifactdatabase.state.DefaultOutput;
 import de.intevation.artifactdatabase.state.State;
 
@@ -56,6 +57,23 @@
     protected transient State state = null;
 
 
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance().register(
+            ARTIFACT_NAME,
+            new FacetActivity() {
+                @Override
+                public Boolean isInitialActive(
+                    Artifact artifact,
+                    Facet    facet,
+                    String   outputName
+                ) {
+                    return outputName.equals("computed_discharge_curve")
+                        || outputName.equals("duration_curve");
+                }
+            });
+    }
+
     /**
      * Trivial Constructor.
      */
@@ -315,35 +333,5 @@
         }
         return filteredList;
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     * @return 0 if not active
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        logger.debug("MainValuesArtifact.active?: "
-           + outputName
-           + "/"
-           + facetName);
-
-        if (outputName.equals("computed_discharge_curve")
-            || outputName.equals("duration_curve")) {
-            return 0;
-        }
-        else {
-            return 1;
-        }
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/ManualPointsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/ManualPointsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,31 +1,23 @@
 package de.intevation.flys.artifacts;
 
+import java.awt.geom.Point2D;
 import java.util.ArrayList;
 import java.util.List;
 
-import java.awt.geom.Point2D;
-
 import org.apache.log4j.Logger;
-
+import org.json.JSONArray;
+import org.json.JSONException;
 import org.w3c.dom.Document;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-
 import de.intevation.artifactdatabase.state.Facet;
-
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.ArtifactFactory;
 import de.intevation.artifacts.CallMeta;
-
+import de.intevation.flys.artifacts.geom.Lines;
 import de.intevation.flys.artifacts.model.FacetTypes;
-
 import de.intevation.flys.artifacts.states.DefaultState;
-
 import de.intevation.flys.model.FastCrossSectionLine;
 
-import de.intevation.flys.artifacts.geom.Lines;
-
 
 /**
  * Artifact to store user-added points and water lines.
@@ -34,6 +26,8 @@
 extends      StaticFLYSArtifact
 implements   FacetTypes, WaterLineArtifact
 {
+    private static final long serialVersionUID = 7096025125474986011L;
+
     /** The logger for this class. */
     private static Logger logger = Logger.getLogger(ManualPointsArtifact.class);
 
@@ -41,24 +35,21 @@
     public static final String ARTIFACT_NAME = "manualpoints";
 
 
-    /**
-     * Trivial Constructor.
-     */
     public ManualPointsArtifact() {
         logger.debug("ManualPointsArtifact.ManualPointsArtifact()");
     }
 
 
     /**
-     * Gets called from factory, to set things up.
+     * Gets called from factory to set things up.
      */
     @Override
     public void setup(
-        String          identifier,
-        ArtifactFactory factory,
-        Object          context,
-        CallMeta        callMeta,
-        Document        data)
+            String          identifier,
+            ArtifactFactory factory,
+            Object          context,
+            CallMeta        callMeta,
+            Document        data)
     {
         logger.debug("ManualPointsArtifact.setup");
         super.setup(identifier, factory, context, callMeta, data);
@@ -67,6 +58,7 @@
 
 
     /** Return the name of this artifact. */
+    @Override
     public String getName() {
         return ARTIFACT_NAME;
     }
@@ -106,7 +98,7 @@
         }
         else {
             logger.debug("No facets to add in ManualPointsArtifact.initialize ("
-                + state.getID() + ").");
+                    + state.getID() + ").");
         }
     }
 
@@ -118,7 +110,7 @@
      */
     protected double getLine(int index) {
         try {
-            JSONArray lines = new JSONArray((String) getLinesData(null));
+            JSONArray lines = new JSONArray(getLinesData(null));
             JSONArray array = lines.getJSONArray(index);
 
             return array.getDouble(0);
@@ -139,30 +131,12 @@
      */
     @Override
     public Lines.LineData getWaterLines(
-        int                  index,
-        FastCrossSectionLine csl,
-        double a, double b
-    ) {
+            int                  index,
+            FastCrossSectionLine csl,
+            double a, double b
+            ) {
         List<Point2D> points = csl.getPoints();
         return Lines.createWaterLines(points, getLine(index));
     }
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     * @return 0 if not active
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 1;
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MapArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MapArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -98,14 +98,14 @@
             DefaultState state = (DefaultState) engine.getState(stateId);
 
             List<Output> list = state.getOutputs();
-            if (list == null || list.size() == 0) {
+            if (list == null || list.isEmpty()) {
                 logger.debug("-> No output modes for this state.");
                 continue;
             }
 
             List<Facet> fs = facets.get(stateId);
 
-            if (fs == null || fs.size() == 0) {
+            if (fs == null || fs.isEmpty()) {
                 logger.debug("No facets for previous state found.");
                 continue;
             }
@@ -174,7 +174,8 @@
             String name = type + "-" + artifact.identifier();
 
             facet.addLayer(name);
-            facet.setExtent(getExtent());
+            facet.setExtent(getExtent(false));
+            facet.setOriginalExtent(getExtent(true));
             facet.setSrid(getSrid());
             facet.setData(getDataString());
             facet.setFilter(getFilter());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/QSectorArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,131 @@
+package de.intevation.flys.artifacts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.ArtifactFactory;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.model.GaugeFinder;
+import de.intevation.flys.artifacts.model.GaugeFinderFactory;
+import de.intevation.flys.artifacts.model.GaugeRange;
+import de.intevation.flys.artifacts.model.NamedDouble;
+
+import de.intevation.flys.artifacts.services.FixingsKMChartService;
+
+import de.intevation.flys.artifacts.states.DefaultState;
+
+import de.intevation.flys.artifacts.resources.Resources;
+
+
+/**
+ * Artifact to produce sector markers.
+ */
+public class QSectorArtifact
+extends      StaticFLYSArtifact
+{
+    /** The logger for this class. */
+    private static Logger logger = Logger.getLogger(QSectorArtifact.class);
+
+    /** The name of the artifact. */
+    public static final String ARTIFACT_NAME = "qsector";
+
+
+    /**
+     * Trivial Constructor.
+     */
+    public QSectorArtifact() {
+        logger.debug("QSectorArtifact.QSectorArtifact()");
+    }
+
+
+    /**
+     * Gets called from factory, to set things up.
+     */
+    @Override
+    public void setup(
+        String          identifier,
+        ArtifactFactory factory,
+        Object          context,
+        CallMeta        callMeta,
+        Document        data)
+    {
+        logger.debug("QSectorArtifact.setup");
+        super.setup(identifier, factory, context, callMeta, data);
+        initialize(null, context, callMeta);
+    }
+
+
+    /** Return the name of this artifact. */
+    public String getName() {
+        return ARTIFACT_NAME;
+    }
+
+
+    /** Get list of NamedDouble s (QSectors). */
+    public Object getQSectors(double km, CallContext context) {
+
+        String river = getDataAsString("river");
+        List<NamedDouble> qsectors = new ArrayList<NamedDouble>();
+
+        GaugeFinderFactory ggf = GaugeFinderFactory.getInstance();
+        GaugeFinder        gf  = ggf.getGaugeFinder(river);
+
+        if (gf == null) {
+            logger.warn("No gauge finder found for river '" + river + "'");
+            return null;
+        }
+
+        GaugeRange gr = gf.find(km);
+        if (gr == null) {
+            logger.debug("No gauge range found for km "
+                + km + " on river " + river + ".");
+            return null;
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug(gr);
+        }
+
+        for (int i = 0; i < FixingsKMChartService.I18N_Q_SECTOR_BOARDERS.length; ++i) {
+            String key   = FixingsKMChartService.I18N_Q_SECTOR_BOARDERS[i];
+            String def   = FixingsKMChartService.DEFAULT_Q_SECTOR_BORDERS[i];
+            String label = Resources.getMsg(context.getMeta(), key, def);
+
+            qsectors.add(new NamedDouble(label, gr.getSectorBorder(i)));
+        }
+
+        return qsectors;
+    }
+
+
+    /** Setup state and facet. */
+    @Override
+    protected void initialize(Artifact artifact, Object context, CallMeta meta) {
+        logger.debug("QSectorArtifact.initialize");
+        List<Facet> fs = new ArrayList<Facet>();
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+        importData(flys, "river");
+
+        DefaultState state = (DefaultState) getCurrentState(context);
+        state.computeInit(this, hash(), context, meta, fs);
+        if (!fs.isEmpty()) {
+            logger.debug("Facets to add in QSectorArtifact.initialize .");
+            facets.put(getCurrentStateId(), fs);
+        }
+        else {
+            logger.debug("No facets to add in QSectorArtifact.initialize ("
+                + state.getID() + ").");
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/RiverAxisArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/RiverAxisArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -92,7 +92,7 @@
                 String ids = artifact.getDataAsString("ids");
 
                 try {
-                    riverId = Integer.valueOf(ids);
+                    riverId = Integer.parseInt(ids);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + ids + "'");
@@ -119,11 +119,20 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             River river = RiverFactory.getRiver(getRiverId());
-            return GeometryUtils.transform(
-                GeometryUtils.getRiverBoundary(river.getName()),
-                getSrid());
+
+            if (reproject) {
+                logger.debug("Query extent for RiverAxis with Srid: " + getSrid());
+                return GeometryUtils.transform(
+                    GeometryUtils.getRiverBoundary(river.getName()),
+                    getSrid());
+            }
+            else {
+                return GeometryUtils.transform(
+                    GeometryUtils.getRiverBoundary(river.getName()),
+                    "31467");
+            }
         }
 
         @Override
@@ -133,13 +142,11 @@
 
         @Override
         protected String getDataString() {
-            String srid = getSrid();
-
             if (FLYSUtils.isUsingOracle()) {
-                return "geom FROM river_axes USING SRID " + srid;
+                return "geom FROM river_axes";
             }
             else {
-                return "geom FROM river_axes USING UNIQUE id USING SRID " + srid;
+                return "geom FROM river_axes USING UNIQUE id";
             }
         }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -50,11 +50,18 @@
         Element root = ProtocolUtils.createRootNode(creator);
         desc.appendChild(root);
 
+        Element name = ProtocolUtils.createArtNode(
+            creator, "name",
+            new String[] { "value" },
+            new String[] { getName() });
+
+        root.appendChild(name);
+
         ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash());
         root.appendChild(createOutputModes(cc, desc, creator));
 
         // Add the data to an anonymous state.
-        Collection<StateData> datas = this.data.values();
+        Collection<StateData> datas = getAllData();
         if (datas.size() > 0) {
             Element ui = creator.create("ui");
             Element staticE = creator.create("static");
@@ -90,7 +97,7 @@
     }
 
 
-    protected Element createOutputModes(
+    private Element createOutputModes(
         CallContext    cc,
         Document       doc,
         ElementCreator creator)
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,21 +1,18 @@
 package de.intevation.flys.artifacts;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.w3c.dom.Document;
-
-import java.awt.geom.Point2D;
-
+import de.intevation.artifactdatabase.state.DefaultOutput;
 import de.intevation.artifactdatabase.state.Facet;
-import de.intevation.artifactdatabase.state.DefaultOutput;
+import de.intevation.artifactdatabase.state.FacetActivity;
 import de.intevation.artifactdatabase.state.State;
 
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.ArtifactFactory;
 import de.intevation.artifacts.CallMeta;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.flys.artifacts.geom.Lines;
+
 import de.intevation.flys.artifacts.math.Distance;
 import de.intevation.flys.artifacts.math.Linear;
 
@@ -26,15 +23,20 @@
 import de.intevation.flys.artifacts.model.WKmsFacet;
 import de.intevation.flys.artifacts.model.WKmsFactory;
 
-import de.intevation.flys.artifacts.states.StaticState;
 import de.intevation.flys.artifacts.resources.Resources;
 
-import de.intevation.artifacts.common.utils.XMLUtils;
-
-import de.intevation.flys.artifacts.geom.Lines;
+import de.intevation.flys.artifacts.states.StaticState;
 
 import de.intevation.flys.model.FastCrossSectionLine;
 
+import java.awt.geom.Point2D;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
 
 /**
  * Artifact to access additional "waterlevel"-type of data, like the height
@@ -51,6 +53,14 @@
     private static Logger logger =
         Logger.getLogger(StaticWKmsArtifact.class);
 
+    private static final String NAME = "staticwkms";
+
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance()
+            .register(NAME, FacetActivity.INACTIVE);
+    }
+
     public static final String STATIC_STATE_NAME =
         "state.additional_wkms.static";
 
@@ -70,6 +80,10 @@
         logger.debug("StaticWKmsArtifact.StaticWKmsArtifact");
     }
 
+    @Override
+    public String getName() {
+        return NAME;
+    }
 
     /**
      * Gets called from factory, to set things up.
@@ -86,8 +100,11 @@
 
         state = new StaticState(STATIC_STATE_NAME);
 
+        if (logger.isDebugEnabled()) {
+            logger.debug(XMLUtils.toString(data));
+        }
+
         List<Facet> fs = new ArrayList<Facet>();
-        logger.debug(XMLUtils.toString(data));
         String code = getDatacageIDValue(data);
 
         // TODO Go for JSON, one day.
@@ -97,10 +114,10 @@
 
             if (parts.length >= 4) {
                 int col = -1;
-                int wst = Integer.valueOf(parts[3]);
+                int wst = Integer.parseInt(parts[3]);
 
                 if (!parts[2].equals("A")) {
-                    col = Integer.valueOf(parts[2]);
+                    col = Integer.parseInt(parts[2]);
                 }
 
                 addStringData("col_pos", parts[2]);
@@ -236,8 +253,8 @@
         logger.debug("StaticWKmsArtifact.getWKms");
 
         return WKmsFactory.getWKms(
-            Integer.valueOf(getDataAsString("col_pos")),
-            Integer.valueOf(getDataAsString("wst_id")));
+            Integer.parseInt(getDataAsString("col_pos")),
+            Integer.parseInt(getDataAsString("wst_id")));
     }
 
 
@@ -286,12 +303,36 @@
      * @return W in wkms that is closer to km than to next and prev, or Double.NaN.
      */
     public double getWAtCloseKm(WKms wkms, double km, double next, double prev) {
+        // TODO symbolic "-1" pr next/prev is a bad idea (tm), as we compare
+        //      distances to these values later.
+        // TODO issue888
+
         int size = wkms.size();
         for (int i = 0; i < size; i++) {
             double wkmsKm = wkms.getKm(i);
             double dist = Distance.distance(wkmsKm, km);
-            if ((prev == -1d || dist <= Distance.distance(wkmsKm, prev))
-                && (next == -1d || dist <= Distance.distance(wkmsKm, next))) {
+            if (dist == 0d) {
+                return wkms.getW(i);
+            }
+
+            // Problematic Cases:
+            // X == km , | and | == prev and next, (?) == wkmsKm
+            //
+            // Standard case:
+            // ----------|----X-----|-------
+            //     (1)    (2)    (3)   (4)
+            //
+            // With prev==-1
+            // -1 ------X-------|------
+            //    (5)      (6)     (7)
+            //
+            // With next==-1
+            //
+            // ---|-----X----- -1
+            // (8)  (9)   (10)
+
+            if (dist <= Distance.distance(wkmsKm, prev)
+                && dist <= Distance.distance(wkmsKm, next)) {
                 return wkms.getW(i);
             }
         }
@@ -363,25 +404,5 @@
 
         return Lines.createWaterLines(points, wAtKm);
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     *
-     * @return Always 0. Static Data will enter plots inactive.
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 0;
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,7 @@
 import org.w3c.dom.Document;
 
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.ArtifactFactory;
@@ -41,6 +42,13 @@
     public static final String STATIC_STATE_NAME =
         "state.additional_wqkms.static";
 
+    private static final String NAME = "staticwqkms";
+
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance()
+            .register(NAME, FacetActivity.INACTIVE);
+    }
 
     /**
      * Trivial Constructor.
@@ -64,7 +72,9 @@
         logger.debug("StaticWQKmsArtifact.setup");
 
         // Store the 'ids' (from datacage).
-        logger.debug("StaticWQKmsArtiact.setup" + XMLUtils.toString(data));
+        if (logger.isDebugEnabled()) {
+            logger.debug("StaticWQKmsArtiact.setup" + XMLUtils.toString(data));
+        }
 
         String code = getDatacageIDValue(data);
         addStringData("ids", code);
@@ -72,8 +82,8 @@
             String [] parts = code.split("-");
 
             if (parts.length >= 4) {
-                int col = Integer.valueOf(parts[2]);
-                int wst = Integer.valueOf(parts[3]);
+                int col = Integer.parseInt(parts[2]);
+                int wst = Integer.parseInt(parts[3]);
 
                 addStringData("col_pos", parts[2]);
                 addStringData("wst_id",  parts[3]);
@@ -123,43 +133,21 @@
     public WQKms getWQKms() {
         logger.debug("StaticWQKmsArtifact.getWQKms");
 
-        int col = Integer.valueOf(getDataAsString("col_pos"));
-        int wst = Integer.valueOf(getDataAsString("wst_id"));
+        int col = Integer.parseInt(getDataAsString("col_pos"));
+        int wst = Integer.parseInt(getDataAsString("wst_id"));
 
         /** TODO do not run twice against db to do this. */
         String wkmsName = WKmsFactory.getWKmsName(col, wst);
 
-        WQKms res = WQKmsFactory.getWQKms(
-            Integer.valueOf(getDataAsString("col_pos")),
-            Integer.valueOf(getDataAsString("wst_id")));
+        WQKms res = WQKmsFactory.getWQKms(col, wst);
         res.setName(wkmsName);
         return res;
     }
 
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     *
-     * @return Always 0. Static Data will enter plots inactive.
-     */
+    /** Return specific name. */
     @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 0;
-    }
-
-
-    /** Return specific name. */
     public String getName() {
-        return "staticwqkms";
+        return NAME;
     }
 
     // TODO implement deepCopy.
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,6 +2,10 @@
 
 import de.intevation.artifactdatabase.data.StateData;
 
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
+
+import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.artifacts.common.utils.StringUtils;
@@ -18,7 +22,6 @@
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DischargeTables;
 import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.MainValuesFactory;
 import de.intevation.flys.artifacts.model.Segment;
 import de.intevation.flys.artifacts.model.WQCKms;
 import de.intevation.flys.artifacts.model.WQKms;
@@ -75,6 +78,33 @@
     /** The default step width between the start end end kilometer. */
     public static final double DEFAULT_KM_STEPS = 0.1;
 
+    private static final String [] INACTIVES = new String[] {
+        LONGITUDINAL_Q,
+        DURATION_Q
+    };
+
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance().register(
+            ARTIFACT_NAME,
+            new FacetActivity() {
+                @Override
+                public Boolean isInitialActive(
+                    Artifact artifact,
+                    Facet    facet,
+                    String   outputName
+                ) {
+                    String fname = facet.getName();
+                    if ((fname.equals(COMPUTED_DISCHARGE_MAINVALUES_Q)
+                    ||   fname.equals(COMPUTED_DISCHARGE_MAINVALUES_W))
+                    && outputName.equals("computed_discharge_curve")) {
+                        return Boolean.FALSE;
+                    }
+                    return !StringUtils.contains(fname, INACTIVES);
+
+                }
+            });
+    }
 
     /**
      * The default constructor.
@@ -135,7 +165,9 @@
     {
         logger.debug("WINFOArtifact.getWaterlevelData");
 
-        if (getDataAsString("calculation_mode").equals("calc.discharge.longitudinal.section")) {
+        if (getDataAsString("calculation_mode")
+            .equals("calc.discharge.longitudinal.section")
+        ) {
             return getDischargeLongitudinalSectionData();
         }
 
@@ -284,7 +316,7 @@
     {
         logger.info("WINFOArtifact.computeDurationCurveData");
 
-        Object[] obj = MainValuesFactory.getDurationCurveData(gauge);
+        Object[] obj = gauge.fetchDurationCurveData();
 
         int[]    days = (int[]) obj[0];
         double[] qs   = (double[]) obj[1];
@@ -528,12 +560,12 @@
         StateData wqValues = getData("wq_values");
         if (wqValues == null) {
             logger.warn("no wq_values given");
-            return Collections.emptyList();
+            return Collections.<Segment>emptyList();
         }
-        String input = (String)wqValues.getValue();
+        String input = (String) wqValues.getValue();
         if (input == null || (input = input.trim()).length() == 0) {
             logger.warn("wq_values are empty");
-            return Collections.emptyList();
+            return Collections.<Segment>emptyList();
         }
         return Segment.parseSegments(input);
     }
@@ -615,18 +647,28 @@
         // Find W at km, linear naive approach.
         WQKms triple = wqkms[idx];
 
-        int old_idx = 0;
-
         if (triple.size() == 0) {
             logger.warn("Calculation of waterline is empty.");
             return Lines.createWaterLines(points, 0.0f);
         }
 
+        // Early abort if we would need to extrapolate.
+        int T = triple.size();
+        double max_km = triple.getKm(T-1), min_km = triple.getKm(0);
+        if (wishKM < min_km || wishKM > max_km) {
+            // TODO Does this have to be done in the other WaterlineArtifact
+            //      implementations, too?
+            logger.warn("Will not extrapolate waterlevels.");
+            return Lines.createWaterLines(points, 0.0f);
+        }
+
+        int old_idx = 0;
+
         // Linear seach in WQKms for closest km.
         double old_dist_wish = Math.abs(wishKM - triple.getKm(0));
         double last_w = triple.getW(0);
 
-        for (int i = 0, T = triple.size(); i < T; i++) {
+        for (int i = 0; i < T; i++) {
             double diff = Math.abs(wishKM - triple.getKm(i));
             if (diff > old_dist_wish) {
                 break;
@@ -888,25 +930,6 @@
     }
 
 
-    /**
-     * Returns the gauges that match the selected kilometer range.
-     *
-     * @return the gauges based on the selected kilometer range.
-     */
-    public List<Gauge> getGauges() {
-
-        River river = FLYSUtils.getRiver(this);
-        if (river == null) {
-            return null;
-        }
-
-        double [] dist = FLYSUtils.getKmRange(this);
-        if (dist == null) {
-            return null;
-        }
-
-        return river.determineGauges(dist[0], dist[1]);
-    }
 
 
     /**
@@ -1161,40 +1184,6 @@
         return values.toNativeArray();
     }
 
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     * @return 0 if not active
-     */
-    @Override
-    public int getInitialFacetActivity(String outputName, String facetName, int index) {
-
-        logger.debug("WINFOArtifact.active?: "
-            + outputName
-            + "/"
-            + facetName);
-
-        if (facetName.equals(COMPUTED_DISCHARGE_MAINVALUES_Q) ||
-             facetName.equals(COMPUTED_DISCHARGE_MAINVALUES_W)
-             && outputName.equals("computed_discharge_curve"))
-            {
-                return 0;
-            }
-
-        return StringUtils.contains(facetName, INACTIVES) ? 0 : 1;
-    }
-
-    private static final String [] INACTIVES = new String[] {
-        LONGITUDINAL_Q,
-        DURATION_Q
-    };
-
-
     /**
      * Returns the WstValueTable of current river.
      */
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSBuildingsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSBuildingsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -101,7 +101,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<Building> buildings =
                 Building.getBuildings(getRiverId(), getName());
 
@@ -118,7 +118,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSCatchmentArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSCatchmentArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -90,7 +90,7 @@
                 String[] parts = ids.split(";");
 
                 try {
-                    riverId = Integer.valueOf(parts[0]);
+                    riverId = Integer.parseInt(parts[0]);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + ids + "'");
@@ -117,7 +117,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<Catchment> catchments =
                 Catchment.getCatchments(getRiverId(), getName());
 
@@ -134,7 +134,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSDBArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSDBArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -43,6 +43,9 @@
     public static final Pattern DB_URL_PATTERN =
         Pattern.compile("(.*)\\/\\/(.*):([0-9]+)\\/([a-zA-Z]+)");
 
+    public static final Pattern DB_PSQL_URL_PATTERN =
+        Pattern.compile("(.*)\\/\\/(.*):([0-9]+)\\/([a-zA-Z0-9]+)");
+
 
     @Override
     public void setup(
@@ -148,6 +151,7 @@
 
             facet.addLayer(name);
             facet.setExtent(getExtent());
+            facet.setOriginalExtent(getExtent(true));
             facet.setSrid(getSrid());
             facet.setData(getDataString());
             facet.setFilter(getFilter());
@@ -179,8 +183,10 @@
 
             Matcher m = DB_URL_PATTERN.matcher(url);
             if (!m.matches()) {
-                logger.warn("Could not parse Connection string.");
-                return null;
+                logger.warn("Could not parse Connection string." +
+                	"Try to parse PostgreSQL string.");
+                // maybe this is a PostgreSQL connection...
+                return getPostgreSQLConnection();
             }
 
             logger.debug("Groups for connection string: " + m.groupCount());
@@ -228,6 +234,55 @@
             return connection;
         }
 
+        protected String getPostgreSQLConnection() {
+            SessionFactoryImpl sf = (SessionFactoryImpl)
+                SessionFactoryProvider.getSessionFactory();
+
+            String user = SessionFactoryProvider.getUser(sf);
+            String pass = SessionFactoryProvider.getPass(sf);
+            String url  = SessionFactoryProvider.getURL(sf);
+
+            Matcher m = DB_PSQL_URL_PATTERN.matcher(url);
+            if (!m.matches()) {
+                logger.warn("Could not parse PostgreSQL Connection string.");
+                return null;
+            }
+
+            int groups = m.groupCount();
+            logger.debug("Groups for PostgreSQL connection string: " + groups);
+
+            if (logger.isDebugEnabled()) {
+                for (int i = 0; i <= groups; i++) {
+                    logger.debug("Group " + i + ": " + m.group(i));
+                }
+            }
+
+            String connection = null;
+
+            if (groups < 4) {
+                logger.warn("Could only partially parse connection string.");
+                return null;
+            }
+
+            String host = m.group(2);
+            String port = m.group(3);
+            String db   = m.group(4);
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("dbname=" + db);
+            sb.append(" host='" + host + "'");
+            sb.append(" port=" + port);
+            sb.append(" user=" + user);
+            sb.append(" password='" + pass + "'");
+            sb.append(" sslmode=disable");
+
+            connection = sb.toString();
+
+            logger.debug("Created connection: '" + connection + "'");
+
+            return connection;
+        }
+
         protected String getConnectionType() {
             return FLYSUtils.isUsingOracle() ? "oraclespatial" : "postgis";
         }
@@ -242,7 +297,7 @@
                 String[] parts = ids.split(";");
 
                 try {
-                    riverId = Integer.valueOf(parts[0]);
+                    riverId = Integer.parseInt(parts[0]);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + parts[0] + "'");
@@ -310,6 +365,16 @@
             }
         }
 
+        /**
+         * This method returns the extent of a DB layer in the projection of the
+         * database.
+         *
+         * @return the extent of the DB layer in the projection of the database.
+         */
+        protected Envelope getExtent() {
+            return getExtent(false);
+        }
+
 
         protected abstract String getFacetType();
 
@@ -317,7 +382,19 @@
 
         protected abstract String getSrid();
 
-        protected abstract Envelope getExtent();
+        /**
+         * This method returns the extent of the DB layer. The projection of the
+         * extent depends on the <i>reproject</i> parameter. If reproject is set,
+         * the extent is reprojected into the original projection which is
+         * specified in the configuration. Otherwise, the projection of the
+         * database is used.
+         *
+         * @param reproject True, to reproject the extent into the projection
+         * specified in the configuration.
+         *
+         * @return the extent of the database layer.
+         */
+        protected abstract Envelope getExtent(boolean reproject);
 
         protected abstract String getFilter();
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSFixpointsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSFixpointsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -101,7 +101,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<Fixpoint> fixpoints = Fixpoint.getFixpoints(getRiverId());
 
             Envelope max = null;
@@ -117,7 +117,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSFloodmapsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSFloodmapsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -101,7 +101,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<Floodmaps> floodmaps =
                 Floodmaps.getFloodmaps(getRiverId(), getName());
 
@@ -118,7 +118,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSFloodplainArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSFloodplainArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -89,7 +89,7 @@
                 String ids = artifact.getDataAsString("ids");
 
                 try {
-                    riverId = Integer.valueOf(ids);
+                    riverId = Integer.parseInt(ids);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + ids + "'");
@@ -120,13 +120,15 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             River      river = getRiver();
             Floodplain plain = Floodplain.getFloodplain(river.getName());
 
-            return GeometryUtils.transform(
-                plain.getGeom().getEnvelopeInternal(),
-                getSrid());
+            Envelope e = plain.getGeom().getEnvelopeInternal();
+
+            return e != null && reproject
+                ? GeometryUtils.transform(e, getSrid())
+                : e;
         }
 
         @Override
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSGaugeLocationArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSGaugeLocationArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -103,7 +103,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<GaugeLocation> gauges =
                 GaugeLocation.getGaugeLocations(getRiverId(), getName());
 
@@ -120,7 +120,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSHwsArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSHwsArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -90,7 +90,7 @@
                 String[] parts = ids.split(";");
 
                 try {
-                    riverId = Integer.valueOf(parts[0]);
+                    riverId = Integer.parseInt(parts[0]);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + parts[0] + "'");
@@ -117,7 +117,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<Hws> hws = Hws.getHws(getRiverId(), getName());
 
             Envelope max = null;
@@ -133,7 +133,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSHydrBoundaryArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSHydrBoundaryArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -101,7 +101,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<HydrBoundary> boundaries = HydrBoundary.getHydrBoundaries(
                 getRiverId(), getName());
 
@@ -118,7 +118,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSHydrBoundaryPolyArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSHydrBoundaryPolyArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -101,7 +101,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<HydrBoundaryPoly> boundaries = HydrBoundaryPoly.getHydrBoundaries(
                 getRiverId(), getName());
 
@@ -118,7 +118,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSKmArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSKmArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -91,7 +91,7 @@
                 String ids = artifact.getDataAsString("ids");
 
                 try {
-                    riverId = Integer.valueOf(ids);
+                    riverId = Integer.parseInt(ids);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + ids + "'");
@@ -118,7 +118,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<RiverAxisKm> kms = RiverAxisKm.getRiverAxisKms(getRiverId());
 
             Envelope max = null;
@@ -134,7 +134,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSLineArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSLineArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -90,7 +90,7 @@
                 String[] parts = ids.split(";");
 
                 try {
-                    riverId = Integer.valueOf(parts[0]);
+                    riverId = Integer.parseInt(parts[0]);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + parts[0] + "'");
@@ -117,7 +117,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             List<Line> lines = Line.getLines(getRiverId(), getName());
 
             Envelope max = null;
@@ -133,7 +133,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSQPSArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSQPSArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -89,7 +89,7 @@
                 String ids = artifact.getDataAsString("ids");
 
                 try {
-                    riverId = Integer.valueOf(ids);
+                    riverId = Integer.parseInt(ids);
                 }
                 catch (NumberFormatException nfe) {
                     logger.error("Cannot parse river id from '" + ids + "'");
@@ -116,7 +116,7 @@
         }
 
         @Override
-        protected Envelope getExtent() {
+        protected Envelope getExtent(boolean reproject) {
             River river = RiverFactory.getRiver(getRiverId());
 
             List<CrossSectionTrack> qps =
@@ -135,7 +135,7 @@
                 max.expandToInclude(env);
             }
 
-            return max != null
+            return max != null && reproject
                 ? GeometryUtils.transform(max, getSrid())
                 : max;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WQKmsInterpolArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,7 @@
 import org.w3c.dom.Document;
 
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 import de.intevation.artifactdatabase.state.DefaultOutput;
 import de.intevation.artifactdatabase.state.State;
 
@@ -42,9 +43,19 @@
     private static Logger logger =
         Logger.getLogger(WQKmsInterpolArtifact.class);
 
+    /** State name. */
     public static final String STATIC_STATE_NAME =
         "state.additional_wqkms.interpol.static";
 
+    /** Artifact name. */
+    private static final String NAME = "staticwqkmsinterpol";
+
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance()
+            .register(NAME, FacetActivity.INACTIVE);
+    }
+
     /** One and only state to be in. */
     protected transient State state = null;
 
@@ -57,6 +68,13 @@
     }
 
 
+    /** Return fixed artifact (types) name. */
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+
     /**
      * Gets called from factory, to set things up.
      */
@@ -80,8 +98,10 @@
         if (code != null) {
             String [] parts = code.split("-");
 
+            logger.debug("WQKmsInterpolArtifact.setup: code " + code);
+
             if (parts.length >= 4) {
-                int wst = Integer.valueOf(parts[3]);
+                int wst = Integer.parseInt(parts[3]);
                 int col = -1;
                 String colpos = parts[2];
                 // Are we interested in a single column or in all columns?
@@ -89,11 +109,11 @@
                     ; // Take all.
                 }
                 else {
-                    col = Integer.valueOf(colpos);
+                    col = Integer.parseInt(colpos);
                     addStringData("col_pos", parts[2]);
                 }
                 addStringData("wst_id",  parts[3]);
-                String wkmsName = (col > 0)
+                String wkmsName = (col >= 0)
                                 ? WKmsFactory.getWKmsName(col, wst)
                                 : WKmsFactory.getWKmsName(wst);
                 String name;
@@ -107,15 +127,18 @@
                     name = STATIC_WQ;
                 }
 
-                Facet facet = new WQFacet(name,
+                Facet wQFacet = new WQFacet(name,
                     Resources.getMsg(
                         callMeta,
                         wkmsName,
                         wkmsName));
-                fs.add(facet);
+                fs.add(wQFacet);
                 facets.put(state.getID(), fs);
             }
         }
+        else {
+            logger.warn("WQKmsInterpolArtifact: no code");
+        }
 
         spawnState();
         super.setup(identifier, factory, context, callMeta, data);
@@ -175,8 +198,10 @@
 
     /**
      * Get WQ at a given km.
+     * @param currentKm the requested km. If NULL, ld_location data
+     *        will be used.
      */
-    public double [][] getWQAtKm(double km) {
+    public double [][] getWQAtKm(Double currentKm) {
 
         WstValueTable interpolator = null;
         // Get WstValueTable
@@ -189,7 +214,10 @@
                 getDataAsInt("wst_id"));
         }
 
-        Double tmp = getDataAsDouble("ld_locations");
+        Double tmp = (currentKm != null)
+                     ? currentKm
+                     : getDataAsDouble("ld_locations");
+
         double [][] vs = interpolator.interpolateWQColumnwise(
             tmp != null ? tmp : 0);
 
@@ -207,7 +235,7 @@
     public int getDataAsInt(String dataName) {
         String val = getDataAsString(dataName);
         try {
-            return Integer.valueOf(val);
+            return Integer.parseInt(val);
         }
         catch (NumberFormatException e) {
             logger.warn("Could not get data " + dataName + " as int", e);
@@ -260,28 +288,8 @@
         logger.warn("Stub, getWQKms not yet implemented.");
 
         return WQKmsFactory.getWQKms(
-            Integer.valueOf(getDataAsString("col_pos")),
-            Integer.valueOf(getDataAsString("wst_id")));
-    }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI). This will be checked one time
-     * when the facet enters a collections describe document.
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     *
-     * @return Always 0. Static Data will enter plots inactive.
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 0;
+            Integer.parseInt(getDataAsString("col_pos")),
+            Integer.parseInt(getDataAsString("wst_id")));
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WaterlevelArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WaterlevelArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,6 +2,7 @@
 
 import de.intevation.artifactdatabase.state.DefaultFacet;
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.ArtifactFactory;
@@ -32,6 +33,11 @@
     /** The name of the artifact. */
     public static final String ARTIFACT_NAME = "waterlevel";
 
+    static {
+        // TODO: Move to configuration.
+        FacetActivity.Registry.getInstance()
+            .register(ARTIFACT_NAME, FacetActivity.INACTIVE);
+    }
 
     /**
      * The default constructor.
@@ -82,7 +88,7 @@
         CallMeta meta)
     {
         WINFOArtifact winfo = (WINFOArtifact) artifact;
-        this.data = winfo.cloneData();
+        setData(winfo.cloneData());
         logger.debug("Cloned data of winfo artifact.");
         // Statically add Facets.
         List<Facet> fs = new ArrayList<Facet>();
@@ -107,26 +113,5 @@
     public String getName() {
         return ARTIFACT_NAME;
     }
-
-
-    /**
-     * Determines Facets initial disposition regarding activity (think of
-     * selection in Client ThemeList GUI).
-     * WaterlevelArtifact Facets should come to live "inactive" (always
-     * return 0).
-     *
-     * @param facetName name of the facet.
-     * @param index     index of the facet.
-     *
-     * @return Always 0 to have Facets initial predisposition to "inactive".
-     */
-    @Override
-    public int getInitialFacetActivity(
-        String outputName,
-        String facetName,
-        int index)
-    {
-        return 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-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,52 @@
+package de.intevation.flys.artifacts.access;
+
+import java.util.Arrays;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.utils.FLYSUtils;
+import de.intevation.flys.utils.StringUtil;
+
+
+public class BedDifferencesAccess
+extends RiverAccess
+{
+    private static Logger logger = Logger.getLogger(BedDifferencesAccess.class);
+    private String yearEpoch;
+    private String[] diffs;
+
+    private CallContext context;
+
+    public BedDifferencesAccess(FLYSArtifact artifact, CallContext context) {
+        super(artifact);
+        this.context = context;
+    }
+
+    public String getYearEpoch() {
+        yearEpoch = getString("ye_select");
+        return yearEpoch;
+    }
+
+    public FLYSArtifact[][] getDifferenceArtifacts() {
+        diffs = getString("diffids").split("#");
+        logger.debug("diffs: " + Arrays.toString(diffs));
+        FLYSArtifact[][] artifacts = new FLYSArtifact[diffs.length/2][2];
+        for (int i = 0; i < diffs.length; i += 2) {
+            String diff1 = StringUtil.unbracket(diffs[0 + 2*i]);
+            String diff2 = StringUtil.unbracket(diffs[1 + 2*i]);
+            String[] diff1parts = diff1.split(";");
+            String[] diff2parts = diff2.split(";");
+            logger.debug("creating 2 artifacts." + diff1parts[0] + "; " + diff2parts[0]);
+            artifacts[i][0] = FLYSUtils.getArtifact(diff1parts[0], context);
+            artifacts[i][1] = FLYSUtils.getArtifact(diff2parts[0], context);
+        }
+        return artifacts;
+    }
+
+    public static int getHeightId(FLYSArtifact artifact) {
+        Access a = new Access(artifact);
+        return a.getInteger("height_id");
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedHeightAccess.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedHeightAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -18,6 +18,7 @@
     private Double lowerKM;
     private Double upperKM;
 
+    private String time;
 
     public BedHeightAccess(FLYSArtifact artifact) {
         super(artifact);
@@ -75,6 +76,14 @@
     }
 
 
+    public String getYearEpoch() {
+        if (time == null) {
+            time =  getString("ye_select");
+        }
+        return time;
+    }
+
+
     public int[] getBedHeightEpochIDs() {
         if (epochIDs == null) {
             String data = getString("soundings");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedQualityAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,97 @@
+package de.intevation.flys.artifacts.access;
+
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.DateRange;
+
+
+public class BedQualityAccess extends RiverAccess {
+
+    private static final Logger logger = Logger
+        .getLogger(BedQualityAccess.class);
+
+    private Double from;
+    private Double to;
+    private List<String> bedDiameter;
+    private List<String> bedloadDiameter;
+    private List<DateRange> ranges;
+
+    public BedQualityAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public double getFrom() {
+        if (from == null) {
+            from = getDouble("ld_from");
+        }
+        return from.doubleValue();
+    }
+
+    public double getTo() {
+        if (to == null) {
+            to = getDouble("ld_to");
+        }
+        return to.doubleValue();
+    }
+
+    public List<DateRange> getDateRanges() {
+        if (ranges == null) {
+            ranges = extractRanges(getString("periods"));
+        }
+        return ranges;
+    }
+
+    public List<String> getBedDiameter() {
+        String value = getString("bed_diameter");
+        if (bedDiameter == null && value != null) {
+            bedDiameter = extractDiameter(value);
+        }
+        return bedDiameter;
+    }
+
+    public List<String> getBedloadDiameter() {
+        String value = getString("load_diameter");
+        if (bedloadDiameter == null && value != null) {
+            bedloadDiameter = extractDiameter(value);
+        }
+        return bedloadDiameter;
+    }
+
+    private List<DateRange> extractRanges(String dateString) {
+        List<DateRange> list = new LinkedList<DateRange>();
+        String[] dates = dateString.split(";");
+        for (String s : dates) {
+            String[] pair = s.split(",");
+            try {
+                long l1      = Long.parseLong(pair[0]);
+                long l2      = Long.parseLong(pair[1]);
+                Date first   = new Date(l1);
+                Date second  = new Date(l2);
+                DateRange dr = new DateRange(first, second);
+                list.add(dr);
+            }
+            catch (NumberFormatException nfe) {
+                continue;
+            }
+        }
+        return list;
+    }
+
+    private List<String> extractDiameter(String value) {
+        List<String> result = new LinkedList<String>();
+        String[] diameter = value.split(";");
+        for (String v : diameter) {
+            logger.debug("diameter: " + v);
+            String[] parts = v.split("\\.");
+            result.add(parts[parts.length - 1]);
+            logger.debug(parts[parts.length-1]);
+        }
+        return result;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/access/ExtremeAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,126 @@
+package de.intevation.flys.artifacts.access;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.model.RangeWithValues;
+
+import de.intevation.flys.utils.DoubleUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class ExtremeAccess
+extends      RiverAccess
+{
+    private static Logger log = Logger.getLogger(ExtremeAccess.class);
+
+    protected Double from;
+    protected Double to;
+    protected Double step;
+
+    protected Long start;
+    protected Long end;
+
+    protected Double percent;
+
+    protected String function;
+
+    protected List<RangeWithValues> ranges;
+
+    public ExtremeAccess() {
+    }
+
+    public ExtremeAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public Double getFrom() {
+
+        if (from == null) {
+            from = getDouble("ld_from");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("from: '" + from + "'");
+        }
+
+        return from;
+    }
+
+    public Double getTo() {
+
+        if (to == null) {
+            to = getDouble("ld_to");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("to: '" + to + "'");
+        }
+
+        return to;
+    }
+
+    public Double getStep() {
+
+        if (step == null) {
+            step = getDouble("ld_step");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("step: '" + step + "'");
+        }
+
+        return step;
+    }
+
+    public Double getPercent() {
+
+        if (percent == null) {
+            percent = getDouble("percent");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("percent: '" + percent + "'");
+        }
+
+        return percent;
+    }
+
+    public String getFunction() {
+        if (function == null) {
+            function = getString("function");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("function: '" + function + "'");
+        }
+
+        return function;
+    }
+
+    public List<RangeWithValues> getRanges() {
+
+        if (ranges == null) {
+            String rangesS = getString("ranges");
+            if (ranges == null) {
+                return null;
+            }
+            ranges = new ArrayList<RangeWithValues>();
+            DoubleUtil.parseSegments(rangesS, new DoubleUtil.SegmentCallback() {
+                @Override
+                public void newSegment(double from, double to, double [] values) {
+                    ranges.add(new RangeWithValues(from, to, values));
+                }
+            });
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("ranges: " + ranges);
+        }
+
+        return ranges;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/FixAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,158 @@
+package de.intevation.flys.artifacts.access;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import java.util.Arrays;
+
+import org.apache.log4j.Logger;
+
+public class FixAccess
+extends      RiverAccess
+{
+    private static Logger log = Logger.getLogger(FixAccess.class);
+
+    protected Double from;
+    protected Double to;
+    protected Double step;
+
+    protected Long start;
+    protected Long end;
+
+    protected Integer qSectorStart;
+    protected Integer qSectorEnd;
+
+    protected int [] events;
+
+    protected Boolean preprocessing;
+
+    protected String  function;
+
+    public FixAccess() {
+    }
+
+    public FixAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public Double getFrom() {
+
+        if (from == null) {
+            from = getDouble("from");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("from: '" + from + "'");
+        }
+
+        return from;
+    }
+
+    public Double getTo() {
+
+        if (to == null) {
+            to = getDouble("to");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("to: '" + to + "'");
+        }
+
+        return to;
+    }
+
+    public Double getStep() {
+
+        if (step == null) {
+            step = getDouble("step");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("step: '" + step + "'");
+        }
+
+        return step;
+    }
+
+    public Long getStart() {
+
+        if (start == null) {
+            start = getLong("start");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("start: '" + start + "'");
+        }
+
+        return start;
+    }
+
+    public Long getEnd() {
+
+        if (end == null) {
+            end = getLong("end");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("end: '" + end + "'");
+        }
+
+        return end;
+    }
+
+    public Integer getQSectorStart() {
+
+        if (qSectorStart == null) {
+            qSectorStart = getInteger("q1");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("q1: '" + qSectorStart + "'");
+        }
+
+        return qSectorStart;
+    }
+
+    public Integer getQSectorEnd() {
+
+        if (qSectorEnd == null) {
+            qSectorEnd = getInteger("q2");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("q2: '" + qSectorEnd + "'");
+        }
+
+        return qSectorEnd;
+    }
+
+    public int [] getEvents() {
+        if (events == null) {
+            events = getIntArray("events");
+        }
+        if (log.isDebugEnabled() && events != null) {
+            log.debug("events: " + Arrays.toString(events));
+        }
+        return events;
+    }
+
+    public Boolean getPreprocessing() {
+        if (preprocessing == null) {
+            preprocessing = getBoolean("preprocessing");
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("preprocessing: " + preprocessing);
+        }
+        return preprocessing;
+    }
+
+    public String getFunction() {
+        if (function == null) {
+            function = getString("function");
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("function: " + function);
+        }
+        return function;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/access/FixAnalysisAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,105 @@
+package de.intevation.flys.artifacts.access;
+
+import de.intevation.artifactdatabase.data.StateData;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.model.DateRange;
+
+import java.util.Arrays;
+import java.util.Date;
+
+import org.apache.log4j.Logger;
+
+public class FixAnalysisAccess
+extends      FixAccess
+{
+    private static Logger log = Logger.getLogger(FixAnalysisAccess.class);
+
+    protected DateRange    referencePeriod;
+    protected DateRange [] analysisPeriods;
+
+    protected double [] qs;
+
+    public FixAnalysisAccess() {
+    }
+
+    public FixAnalysisAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public DateRange getReferencePeriod() {
+        if (referencePeriod == null) {
+            StateData refStart = artifact.getData("ref_start");
+            StateData refEnd   = artifact.getData("ref_end");
+
+            if (refStart == null || refEnd == null) {
+                log.warn("missing 'ref_start' or 'ref_start' value");
+                return null;
+            }
+
+            try {
+                long rs = Long.parseLong((String)refStart.getValue());
+                long re = Long.parseLong((String)refEnd  .getValue());
+
+                if (rs > re) { long t = rs; rs = re; re = t; }
+
+                Date from = new Date(rs);
+                Date to   = new Date(re);
+                referencePeriod = new DateRange(from, to);
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("ref_start or ref_end is not an integer.");
+            }
+        }
+
+        return referencePeriod;
+    }
+
+    public DateRange [] getAnalysisPeriods() {
+        if (analysisPeriods == null) {
+            analysisPeriods = getDateRange("ana_data");
+        }
+
+        return analysisPeriods;
+    }
+
+    /**
+     * @return DateRange object ranging from eldest to youngest date
+     * of analysis and reference periods.
+     */
+    public DateRange getDateRange() {
+        DateRange refP = getReferencePeriod();
+
+        if (refP == null) {
+            return null;
+        }
+
+        Date from = refP.getFrom();
+        Date to   = refP.getTo();
+
+        DateRange[] rs = getAnalysisPeriods();
+        for (DateRange r: rs) {
+            if (r.getFrom().before(from)) {
+                from = r.getFrom();
+            }
+            if (r.getTo().after(to)) {
+                to = r.getTo();
+            }
+        }
+
+        return new DateRange(from, to);
+    }
+
+    public double [] getQs() {
+        if (qs == null) {
+            qs = getDoubleArray("qs");
+        }
+
+        if (log.isDebugEnabled() && qs != null) {
+            log.debug("qs: " + Arrays.toString(qs));
+        }
+        return qs;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/access/FixRealizingAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,53 @@
+package de.intevation.flys.artifacts.access;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.model.Segment;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class FixRealizingAccess
+extends      FixAccess
+{
+    private static Logger log = Logger.getLogger(FixRealizingAccess.class);
+
+    protected Boolean isQ;
+
+    protected List<Segment> segments;
+
+    public FixRealizingAccess() {
+    }
+
+    public FixRealizingAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public Boolean isQ() {
+        if (isQ == null) {
+            isQ = getBoolean("wq_isq");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("isQ: " + isQ);
+        }
+
+        return isQ;
+    }
+
+    public List<Segment> getSegments() {
+        if (segments == null) {
+            String segmentsS = getString("wq_values");
+            if (segmentsS != null) {
+                segments = Segment.parseSegments(segmentsS);
+            }
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("segments: " + segments);
+        }
+
+        return segments;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/FixationArtifactAccess.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-package de.intevation.flys.artifacts.access;
-
-import de.intevation.artifactdatabase.data.StateData;
-import de.intevation.flys.artifacts.FLYSArtifact;
-import de.intevation.flys.artifacts.model.DateRange;
-
-import java.util.Arrays;
-import java.util.Date;
-
-import org.apache.log4j.Logger;
-
-
-public class FixationArtifactAccess
-extends      Access
-{
-    private static Logger log = Logger.getLogger(FixationArtifactAccess.class);
-
-    protected String river;
-
-    protected String calculationMode;
-
-    protected Double from;
-    protected Double to;
-    protected Double step;
-
-    protected Long start;
-    protected Long end;
-
-    protected Integer qSectorStart;
-    protected Integer qSectorEnd;
-
-    protected DateRange    referencePeriod;
-    protected DateRange [] analysisPeriods;
-
-    protected int [] events;
-
-    protected Boolean preprocessing;
-
-    protected String  function;
-
-    protected double [] qs;
-
-    public FixationArtifactAccess() {
-    }
-
-    public FixationArtifactAccess(FLYSArtifact artifact) {
-        super(artifact);
-    }
-
-    public String getRiver() {
-        if (river == null) {
-            river = getString("river");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("river: '" + river + "'");
-        }
-        return river;
-    }
-
-    public String getCalculationMode() {
-        if (calculationMode == null) {
-            calculationMode = getString("calculation.mode");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("calculationMode: '" + calculationMode + "'");
-        }
-        return calculationMode;
-    }
-
-    public Double getFrom() {
-
-        if (from == null) {
-            from = getDouble("from");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("from: '" + from + "'");
-        }
-
-        return from;
-    }
-
-    public Double getTo() {
-
-        if (to == null) {
-            to = getDouble("to");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("to: '" + to + "'");
-        }
-
-        return to;
-    }
-
-    public Double getStep() {
-
-        if (step == null) {
-            step = getDouble("step");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("step: '" + step + "'");
-        }
-
-        return step;
-    }
-
-    public Long getStart() {
-
-        if (start == null) {
-            start = getLong("start");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("start: '" + start + "'");
-        }
-
-        return start;
-    }
-
-    public Long getEnd() {
-
-        if (end == null) {
-            end = getLong("end");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("end: '" + end + "'");
-        }
-
-        return end;
-    }
-
-    public Integer getQSectorStart() {
-
-        if (qSectorStart == null) {
-            qSectorStart = getInteger("q1");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("q1: '" + qSectorStart + "'");
-        }
-
-        return qSectorStart;
-    }
-
-    public Integer getQSectorEnd() {
-
-        if (qSectorEnd == null) {
-            qSectorEnd = getInteger("q2");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("q2: '" + qSectorEnd + "'");
-        }
-
-        return qSectorEnd;
-    }
-
-    public int [] getEvents() {
-        if (events == null) {
-            events = getIntArray("events");
-        }
-        if (log.isDebugEnabled() && events != null) {
-            log.debug("events: " + Arrays.toString(events));
-        }
-        return events;
-    }
-
-    public DateRange getReferencePeriod() {
-        if (referencePeriod == null) {
-            StateData refStart = artifact.getData("ref_start");
-            StateData refEnd   = artifact.getData("ref_end");
-
-            if (refStart == null || refEnd == null) {
-                log.warn("missing 'ref_start' or 'ref_start' value");
-                return null;
-            }
-
-            try {
-                long rs = Long.parseLong((String)refStart.getValue());
-                long re = Long.parseLong((String)refEnd  .getValue());
-
-                if (rs > re) { long t = rs; rs = re; re = t; }
-
-                Date from = new Date(rs);
-                Date to   = new Date(re);
-                referencePeriod = new DateRange(from, to);
-            }
-            catch (NumberFormatException nfe) {
-                log.warn("ref_start or ref_end is not an integer.");
-            }
-        }
-
-        return referencePeriod;
-    }
-
-    public DateRange [] getAnalysisPeriods() {
-        if (analysisPeriods == null) {
-            analysisPeriods = getDateRange("ana_data");
-        }
-
-        return analysisPeriods;
-    }
-
-    /**
-     * @return DateRange object ranging from eldest to youngest date
-     * of analysis and reference periods.
-     */
-    public DateRange getDateRange() {
-        DateRange refP = getReferencePeriod();
-
-        Date from = refP.getFrom();
-        Date to   = refP.getTo();
-
-        DateRange[] rs = getAnalysisPeriods();
-        for(DateRange r : rs) {
-            if(r.getFrom().before(from)) {
-                from = r.getFrom();
-            }
-            if(r.getTo().after(to)) {
-                to = r.getTo();
-            }
-        }
-
-        return new DateRange(from, to);
-    }
-
-    public Boolean getPreprocessing() {
-        if (preprocessing == null) {
-            preprocessing = getBoolean("preprocessing");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("preprocessing: " + preprocessing);
-        }
-        return preprocessing;
-    }
-
-    public String getFunction() {
-        if (function == null) {
-            function = getString("function");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("function: " + function);
-        }
-        return function;
-    }
-
-    public double [] getQs() {
-        if (qs == null) {
-            qs = getDoubleArray("qs");
-        }
-
-        if (log.isDebugEnabled() && qs != null) {
-            log.debug("qs: " + Arrays.toString(qs));
-        }
-        return qs;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/FlowVelocityAccess.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/FlowVelocityAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,7 +3,8 @@
 import de.intevation.flys.artifacts.FLYSArtifact;
 
 
-public class FlowVelocityAccess extends Access {
+/** Access to data that deals with flow velocity stuff. */
+public class FlowVelocityAccess extends RiverAccess {
 
     private int[] mainChannels;
     private int[] totalChannels;
@@ -19,7 +20,7 @@
 
     public int[] getMainChannels() {
         if (mainChannels == null) {
-            mainChannels = getIntArray("main.channel");
+            mainChannels = getIntArray("main_channel");
         }
 
         return mainChannels;
@@ -28,7 +29,7 @@
 
     public int[] getTotalChannels() {
         if (totalChannels == null) {
-            totalChannels = getIntArray("total.channel");
+            totalChannels = getIntArray("total_channel");
         }
 
         return totalChannels;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/RiverAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,31 @@
+package de.intevation.flys.artifacts.access;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import org.apache.log4j.Logger;
+
+public class RiverAccess
+extends      Access
+{
+    private static Logger log = Logger.getLogger(RiverAccess.class);
+
+    protected String river;
+
+    public RiverAccess() {
+    }
+
+    public RiverAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public String getRiver() {
+        if (river == null) {
+            river = getString("river");
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("river: '" + river + "'");
+        }
+        return river;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/SQRelationAccess.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/SQRelationAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,23 +1,22 @@
 package de.intevation.flys.artifacts.access;
 
-import de.intevation.flys.artifacts.FLYSArtifact;
-
-import de.intevation.flys.artifacts.model.DateRange;
+import java.util.Date;
 
 import org.apache.log4j.Logger;
 
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.DateRange;
+
 public class SQRelationAccess
-extends      Access
+extends      RiverAccess
 {
     private static Logger log = Logger.getLogger(SQRelationAccess.class);
 
-    protected String       river;
+    protected Double    location;
 
-    protected Double       location;
+    protected DateRange period;
 
-    protected DateRange [] periods;
-
-    protected Double       outliers;
+    protected Double    outliers;
 
     public SQRelationAccess() {
     }
@@ -26,16 +25,6 @@
         super(artifact);
     }
 
-    public String getRiver() {
-        if (river == null) {
-            river = getString("river");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("river: '" + river + "'");
-        }
-        return river;
-    }
-
     public Double getLocation() {
         if (location == null) {
             // XXX: The parameter name suggests plural!?
@@ -49,11 +38,17 @@
         return location;
     }
 
-    public DateRange [] getPeriods() {
-        if (periods == null) {
-            periods = getDateRange("periods");
+    public DateRange getPeriod() {
+        if (period == null) {
+            Long start = getLong("start");
+            Long end   = getLong("end");
+
+            if (start != null && end != null) {
+                period = new DateRange(new Date(start), new Date(end));
+            }
         }
-        return periods;
+
+        return period;
     }
 
     public Double getOutliers() {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java	Fri Sep 28 12:15:40 2012 +0200
@@ -54,6 +54,9 @@
     public static final String SCHEDULER =
         "flys.wsplgen.scheduler";
 
+    /** Key to store the configured modules in the context. */
+    public static final String MODULES = "flys.modules";
+
 
     /**
      * The default constructor.
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -26,6 +26,7 @@
 import de.intevation.artifactdatabase.transition.Transition;
 import de.intevation.artifactdatabase.transition.TransitionEngine;
 
+import de.intevation.flys.artifacts.model.Module;
 import de.intevation.flys.artifacts.states.StateFactory;
 import de.intevation.flys.artifacts.transitions.TransitionFactory;
 import de.intevation.flys.themes.Theme;
@@ -81,6 +82,8 @@
     public static final String XPATH_RIVER_WMS =
         "/artifact-database/floodmap/river";
 
+    public static final String XPATH_MODULES = "/artifact-database/modules/module";
+
     /**
      * Creates a new FLYSArtifactContext object and initialize all
      * components required by the application.
@@ -97,6 +100,7 @@
         configureThemes(config, context);
         configureThemesMappings(config, context);
         configureRiverWMS(config, context);
+        configureModules(config, context);
 
         return context;
     }
@@ -423,5 +427,31 @@
 
         context.put(FLYSContext.RIVER_WMS, riverWMS);
     }
+
+
+    /**
+     * This method initializes the modules configuration.
+     *
+     * @param config the config document.
+     * @param context the FLYSContext.
+     */
+    protected void configureModules(Document cfg, FLYSContext context) {
+        NodeList modulenodes = (NodeList) XMLUtils.xpath(
+            cfg, XPATH_MODULES, XPathConstants.NODESET);
+
+        int num = modulenodes != null ? modulenodes.getLength() : 0;
+        ArrayList<Module> modules = new ArrayList<Module>(num);
+
+        for (int i = 0; i < num; i++) {
+            Element e = (Element) modulenodes.item(i);
+            String modulename = e.getAttribute("name");
+            String attrselected = e.getAttribute("selected");
+            boolean selected = attrselected == null ? false :
+                attrselected.equalsIgnoreCase("true");
+            logger.debug("Loaded module " + modulename);
+            modules.add(new Module(modulename, selected));
+        }
+        context.put(FLYSContext.MODULES, modules);
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/Datacage.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/Datacage.java	Fri Sep 28 12:15:40 2012 +0200
@@ -451,7 +451,6 @@
     }
 
     protected boolean cleanDatabase() {
-
         log.debug("cleanDatabase");
 
         boolean success = sqlExecutor.new Instance() {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/DatacageBackendListener.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/DatacageBackendListener.java	Fri Sep 28 12:15:40 2012 +0200
@@ -14,6 +14,7 @@
 
 import org.w3c.dom.Document;
 
+/** Triggers Datacage to update db. */
 public class DatacageBackendListener
 implements   BackendListener
 {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/Recommendations.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/Recommendations.java	Fri Sep 28 12:15:40 2012 +0200
@@ -35,6 +35,10 @@
 
 import de.intevation.flys.artifacts.datacage.templating.Builder;
 
+
+/**
+ * Also accessible as Singleton with getInstance().
+ */
 public class Recommendations
 {
     private static Logger log = Logger.getLogger(Recommendations.class);
@@ -140,6 +144,10 @@
         }
     }
 
+
+    /**
+     * Append recommendations to \param result.
+     */
     public void  recommend(
         FLYSArtifact        artifact,
         String              userId,
@@ -168,6 +176,10 @@
         recommend(parameters, userId, result);
     }
 
+
+    /**
+     * Append recommendations to \param result.
+     */
     public void recommend(
         Map<String, Object> parameters,
         String              userId,
@@ -218,6 +230,8 @@
         });
     }
 
+
+    /** Get singleton instance. */
     public static synchronized Recommendations getInstance() {
         if (INSTANCE == null) {
             INSTANCE = createRecommendations();
@@ -225,6 +239,7 @@
         return INSTANCE;
     }
 
+
     protected static Document loadTemplate(File file) throws IOException {
         InputStream in = null;
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/Builder.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/Builder.java	Fri Sep 28 12:15:40 2012 +0200
@@ -290,7 +290,7 @@
 
         /**
          * Add attribute to an element
-         * @see element
+         * @see Element
          */
         protected void attribute(Node parent, Element current) {
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,426 +0,0 @@
-package de.intevation.flys.artifacts.geom;
-
-import java.awt.Shape;
-import java.awt.geom.Path2D;
-import java.awt.geom.Point2D;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import de.intevation.flys.artifacts.math.Linear;
-import static de.intevation.flys.artifacts.geom.VectorUtils.EPSILON;
-import static de.intevation.flys.artifacts.geom.VectorUtils.X;
-import static de.intevation.flys.artifacts.geom.VectorUtils.Y;
-
-public class Polygon2D
-implements   Serializable
-{
-    public static final Comparator<Point2D> POINT_X_CMP =
-        new Comparator<Point2D>() {
-            public int compare(Point2D a, Point2D b) {
-                double d = X(a) - X(b);
-                if (d < 0d) return -1;
-                return d > 0d ? + 1 : 0;
-            }
-        };
-
-    public static final Comparator<Point2D []> FIRST_POINT_X =
-        new Comparator<Point2D []>() {
-            public int compare(Point2D [] a, Point2D [] b) {
-                if (a.length == 0) return -1; // should not happen.
-                if (b.length == 0) return +1; // should not happen.
-                double d = X(a[0]) - Y(b[0]);
-                if (d < 0d) return -1;
-                return d > 0d ? + 1 : 0;
-            }
-        };
-
-    protected List<Point2D> points;
-
-    public Polygon2D() {
-        points = new ArrayList<Point2D>();
-    }
-
-    public Polygon2D(List<Point2D> points) {
-        this.points = points;
-    }
-
-    public void add(double x, double y) {
-        points.add(new Point2D.Double(x, y));
-    }
-
-    protected static boolean addCheck(Point2D p, List<Point2D> points) {
-        switch (points.size()) {
-            case 0:
-                points.add(p);
-                return true;
-            case 1:
-                if (VectorUtils.epsilonEquals(points.get(0), p)) {
-                    return false;
-                }
-                points.add(p);
-                return true;
-            default:
-                int L = points.size()-1;
-                Point2D last = points.get(L);
-                if (VectorUtils.epsilonEquals(last, p)) {
-                    return false;
-                }
-                Point2D before = points.get(L-1);
-                if (VectorUtils.collinear(before, last, p)) {
-                    points.set(L, p);
-                }
-                else {
-                    points.add(p);
-                }
-                return true;
-        }
-    }
-
-    public boolean addCheck(Point2D p) {
-        return addCheck(p, points);
-    }
-
-    public void addReversed(List<Point2D> other) {
-        for (int i = other.size()-1; i >= 0; --i) {
-            addCheck(other.get(i));
-        }
-    }
-
-    public double area() {
-        double area = 0d;
-
-        for (int i = 0, N = points.size(); i < N; ++i) {
-            int j = (i + 1) % N;
-            Point2D pi = points.get(i);
-            Point2D pj = points.get(j);
-            area += X(pi)*Y(pj);
-            area -= X(pj)*Y(pi);
-        }
-
-        return 0.5d*area;
-    }
-
-    public Shape toShape() {
-        Path2D.Double path = new Path2D.Double();
-
-        int N = points.size();
-
-        if (N > 0) {
-            Point2D p = points.get(0);
-            path.moveTo(X(p), Y(p));
-            for (int i = 1; i < N; ++i) {
-                p = points.get(i);
-                path.lineTo(X(p), Y(p));
-            }
-            path.closePath();
-        }
-
-        return path;
-    }
-
-    protected static List<Point2D []> splitByNaNs(
-        double [] xs,
-        double [] ys
-    ) {
-        List<Point2D []> parts = new ArrayList<Point2D []>();
-
-        List<Point2D> tmp = new ArrayList<Point2D>(xs.length);
-
-        for (int i = 0; i < xs.length; ++i) {
-            double x = xs[i];
-            double y = ys[i];
-
-            if (Double.isNaN(x) || Double.isNaN(y)) {
-                if (!tmp.isEmpty()) {
-                    Point2D [] part = new Point2D[tmp.size()];
-                    parts.add(tmp.toArray(part));
-                    tmp.clear();
-                }
-            }
-            else {
-                tmp.add(new Point2D.Double(x, y));
-            }
-        }
-
-        if (!tmp.isEmpty()) {
-            Point2D [] part = new Point2D[tmp.size()];
-            parts.add(tmp.toArray(part));
-        }
-
-        return parts;
-    }
-
-    protected static boolean removeNoneIntersecting(
-        List<Point2D []> As,
-        List<Point2D []> Bs
-    ) {
-        int B = Bs.size()-1;
-        OUTER: for (int i = 0; i < As.size();) {
-            Point2D [] a = As.get(i);
-            int lo = 0, hi = B;
-            while (lo <= hi) {
-                int mid = (lo + hi) >> 1;
-                Point2D [] b = Bs.get(mid);
-                     if (X(a[0]) > X(b[b.length-1])) lo = mid+1;
-                else if (X(a[a.length-1]) < X(b[0])) hi = mid-1;
-                else {
-                    // found: keep
-                    ++i;
-                    continue OUTER;
-                }
-            }
-            // not found: remove
-            As.remove(i);
-        }
-
-        return As.isEmpty();
-    }
-
-    protected static void buildPolygons(
-        Point2D []      as,
-        Point2D []      bs,
-        Point2D [][]    rest,
-        List<Polygon2D> positives,
-        List<Polygon2D> negatives
-    ) {
-        List<Point2D> apoints = new ArrayList<Point2D>();
-        List<Point2D> bpoints = new ArrayList<Point2D>();
-
-        double ax = X(as[0]);
-        double bx = X(bs[0]);
-
-        int ai = 1;
-        int bi = 1;
-
-        boolean intersect = false;
-
-        if (ax == bx) {
-            apoints.add(as[0]);
-            bpoints.add(bs[0]);
-        }
-        else if (ax > bx) {
-            apoints.add(as[0]);
-            double bx1;
-            while ((bx1 = X(bs[bi])) < ax) ++bi;
-            if (bx1 == ax) {
-                bpoints.add(bs[bi]);
-            }
-            else { // need to calculate start b point.
-                intersect = true;
-                double by1 = Linear.linear(
-                    ax,
-                    X(bs[bi-1]), bx1,
-                    Y(bs[bi-1]), Y(bs[bi]));
-
-                bpoints.add(new Point2D.Double(ax, by1));
-            }
-        }
-        else { // bx > ax: Symmetric case
-            bpoints.add(bs[0]);
-            double ax1;
-            while ((ax1 = X(as[ai])) < bx) ++ai;
-            if (ax1 == bx) {
-                apoints.add(as[ai]);
-            }
-            else { // need to calculate start b point.
-                intersect = true;
-                double ay1 = Linear.linear(
-                    bx,
-                    X(as[ai-1]), ax1,
-                    Y(as[ai-1]), Y(as[ai]));
-
-                apoints.add(new Point2D.Double(bx, ay1));
-            }
-        }
-
-        // now we have a point in each list, decide if neg/pos.
-        boolean neg = Y(bpoints.get(0)) > Y(apoints.get(0));
-
-        // Continue with inner points
-
-        Line line = new Line();
-
-        while (ai < as.length && bi < bs.length) {
-            double xan = X(as[ai]);
-            double xbn = X(bs[bi]);
-            if (xan == xbn) {
-                double yan = Y(as[ai]);
-                double ybn = Y(bs[ai]);
-
-                if (neg) {
-                    if (yan > ybn) { // intersection
-                        Point2D ip = VectorUtils.intersection(
-                            apoints.get(apoints.size()-1), as[ai],
-                            bpoints.get(bpoints.size()-1), bs[bi]);
-                        addCheck(ip, apoints);
-                        addCheck(ip, bpoints);
-                        Polygon2D p = new Polygon2D(
-                            new ArrayList<Point2D>(apoints));
-                        p.addReversed(bpoints);
-                        negatives.add(p);
-                        apoints.clear();
-                        bpoints.clear();
-                        apoints.add(ip);
-                        bpoints.add(ip);
-                        neg = !neg;
-                    }
-                    else { // no intersection
-                        addCheck(as[ai], apoints);
-                        addCheck(bs[bi], bpoints);
-                    }
-                }
-                else { // not neg
-                    if (ybn > yan) { // intersection
-                        Point2D ip = VectorUtils.intersection(
-                            apoints.get(apoints.size()-1), as[ai],
-                            bpoints.get(bpoints.size()-1), bs[bi]);
-                        addCheck(ip, apoints);
-                        addCheck(ip, bpoints);
-                        Polygon2D p = new Polygon2D(
-                            new ArrayList<Point2D>(apoints));
-                        p.addReversed(bpoints);
-                        positives.add(p);
-                        apoints.clear();
-                        bpoints.clear();
-                        apoints.add(ip);
-                        bpoints.add(ip);
-                        neg = !neg;
-                    }
-                    else { // no intersection
-                        addCheck(as[ai], apoints);
-                        addCheck(bs[bi], bpoints);
-                    }
-                }
-                ++ai;
-                ++bi;
-            }
-            else if (xan > xbn) {
-                line.set(apoints.get(apoints.size()-1), as[ai]);
-                double dir = neg ? -1d: 1d; // XXX: correct sign?
-                while  (bi < bs.length
-                    && X(bs[bi]) < xan
-                    && line.eval(bs[bi])*dir > EPSILON)
-                    ++bi;
-                if (bi == bs.length) {
-                    // b run out of points
-                    // calculate Y(last_a, as[ai]) for X(bs[bi-1])
-                    double ay1 = Linear.linear(
-                        X(bs[bi-1]),
-                        X(apoints.get(apoints.size()-1)), X(as[ai]),
-                        Y(apoints.get(apoints.size()-1)), Y(as[ai]));
-                    addCheck(new Point2D.Double(X(bs[bi-1]), ay1), apoints);
-                    addCheck(bs[bi-1], bpoints);
-                    Polygon2D p = new Polygon2D(
-                        new ArrayList<Point2D>(apoints));
-                    p.addReversed(bpoints);
-                    apoints.clear();
-                    bpoints.clear();
-                    (neg ? negatives : positives).add(p);
-                    break;
-                }
-                else {
-                    // TODO: intersect line and/or X(bs[bi]) >= xan?
-                }
-            }
-            else { // xbn > xan
-                line.set(bpoints.get(bpoints.size()-1), bs[bi]);
-                // TODO: continue symmetric
-            }
-        }
-
-        // TODO: Continue with closing segment
-    }
-
-    public static final class Line {
-
-        private double a;
-        private double b;
-        private double c;
-
-        public Line() {
-        }
-
-        public Line(Point2D p1, Point2D p2) {
-            set(p1, p2);
-        }
-
-        public void set(Point2D p1, Point2D p2) {
-            Point2D p3 =
-                VectorUtils.normalize(
-                VectorUtils.sub(p1, p2));
-
-            Point2D n = VectorUtils.ortho(p3);
-
-            a = X(n);
-            b = Y(n);
-
-            // a*x + b*y + c = 0
-            // c = -a*x -b*y
-
-            c = -a*X(p1) - b*Y(p1);
-        }
-
-        public double eval(Point2D p) {
-            return a*X(p) + b*Y(p) + c;
-        }
-    }
-
-    public static void createPolygons(
-        double [] xAs, double [] yAs,
-        double [] xBs, double [] yBs,
-        List<Polygon2D> positives,
-        List<Polygon2D> negatives
-    ) {
-        if (xAs.length == 0 || xBs.length == 0) {
-            return;
-        }
-
-        List<Point2D []> splAs = splitByNaNs(xAs, yAs);
-        List<Point2D []> splBs = splitByNaNs(xBs, yBs);
-
-        // They feeded us with NaNs only.
-        if (splAs.isEmpty() || splBs.isEmpty()) {
-            return;
-        }
-
-        // Sort each part by x to ensure that the first
-        // is the smallest.
-        for (Point2D [] splA: splAs) {
-            Arrays.sort(splA, POINT_X_CMP);
-        }
-
-        for (Point2D [] splB: splBs) {
-            Arrays.sort(splB, POINT_X_CMP);
-        }
-
-        // Now sort all parts by there first elements.
-        // Should be good enough to find overlapping regions.
-        Collections.sort(splAs, FIRST_POINT_X);
-        Collections.sort(splBs, FIRST_POINT_X);
-
-        // Check if the two series intersect at all.
-        // If no then there will be no area between them.
-
-        Point2D [] p1 = splAs.get(0);
-        Point2D [] p2 = splBs.get(splBs.size()-1);
-
-        // Sort out the ranges that are not intersecting
-        // the ranges in the other series.
-        // We are going to merge them anyway
-        // so this is not strictly required.
-        // Keep it to recude cases.
-        if (removeNoneIntersecting(splAs, splBs)
-        ||  removeNoneIntersecting(splBs, splAs)
-        ) {
-            // They do not intersect at all.
-            return;
-        }
-
-        // TODO: Intersect/split the two series parts.
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/VectorUtils.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-package de.intevation.flys.artifacts.geom;
-
-import java.awt.geom.Point2D;
-
-public final class VectorUtils
-{
-    public static final double EPSILON = 1e-4;
-
-    private VectorUtils() {
-    }
-
-    public static final double X(Point2D p) {
-        return p.getX();
-    }
-
-    public static final double Y(Point2D p) {
-        return p.getY();
-    }
-
-    public static final Point2D sub(Point2D a, Point2D b) {
-        return new Point2D.Double(X(a)-X(b), Y(a)-Y(b));
-    }
-
-    public static final double dot(Point2D a, Point2D b) {
-        return X(a)*X(b) + Y(a)*Y(b);
-    }
-
-    public static final Point2D add(Point2D a, Point2D b) {
-        return new Point2D.Double(X(a)+X(b), Y(a)+Y(b));
-    }
-
-    public static final Point2D negate(Point2D a) {
-        return new Point2D.Double(-X(a), -Y(a));
-    }
-
-    public static final Point2D ortho(Point2D a) {
-        return new Point2D.Double(-Y(a), X(a));
-    }
-
-    public static final Point2D scale(Point2D a, double s) {
-        return new Point2D.Double(s*X(a), s*Y(a));
-    }
-
-    public static final double lengthSq(Point2D a) {
-        double x = X(a);
-        double y = Y(a);
-        return x*x + y*y;
-    }
-
-    public static final double length(Point2D a) {
-        return Math.sqrt(lengthSq(a));
-    }
-
-    public static final Point2D normalize(Point2D a) {
-        double length = length(a);
-        return length != 0d
-            ? scale(a, 1d/length)
-            : new Point2D.Double(X(a), Y(a));
-    }
-
-    public static final double L1(Point2D a, Point2D b) {
-        return Math.abs(X(a)-X(b)) + Math.abs(Y(a)-Y(b));
-    }
-
-    public static final boolean collinear(Point2D a, Point2D b, Point2D c) {
-        double x1 = X(a);
-        double y1 = Y(a);
-        double x2 = X(b);
-        double y2 = Y(b);
-        double x3 = X(c);
-        double y3 = Y(c);
-
-        return Math.abs((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)) < EPSILON;
-    }
-
-    public static boolean epsilonEquals(Point2D a, Point2D b) {
-        return Math.abs(X(a)-X(b)) < EPSILON
-            && Math.abs(Y(a)-Y(b)) < EPSILON;
-    }
-
-    public static final Point2D intersection(
-        Point2D p1, Point2D p2,
-        Point2D p3, Point2D p4
-    ) {
-        double x1 = X(p1);
-        double y1 = Y(p1);
-        double x2 = X(p2);
-        double y2 = Y(p2);
-        double x3 = X(p3);
-        double y3 = Y(p3);
-        double x4 = X(p4);
-        double y4 = Y(p4);
-
-        // Compute a1, b1, c1, where line joining points 1 and 2
-        // is "a1 x + b1 y + c1 = 0".
-        double a1 = y2 - y1;
-        double b1 = x1 - x2;
-        double c1 = x2*y1 - x1*y2;
-
-        // Compute r3 and r4.
-        double r3 = a1*x3 + b1*y3 + c1;
-        double r4 = a1*x4 + b1*y4 + c1;
-
-        if (r3 != 0d && r4 != 0d && r3*r4 >= 0) {
-            return null;
-        }
-
-        // Compute a2, b2, c2
-        double a2 = y4 - y3;
-        double b2 = x3 - x4;
-        double c2 = (x4 * y3) - (x3 * y4);
-
-        // Compute r1 and r2
-        double r1 = a2*x1 + b2*y1 + c2;
-        double r2 = a2*x2 + b2*y2 + c2;
-
-        if (r1 != 0d && r2 != 0d && r1*r2 >= 0) {
-            return null;
-        }
-
-        // Line segments intersect: compute intersection point.
-        double denom = a1*b2 - a2*b1;
-
-        if (denom == 0d) { // collinear
-            return null;
-        }
-
-        double offset = Math.abs(denom)/2d;
-
-        // The denom/2 is to get rounding instead of truncating. It
-        // is added or subtracted to the numerator, depending upon the
-        // sign of the numerator.
-        double num = b1*c2 - b2*c1;
-
-        double x = num < 0d
-            ? (num - offset)/denom
-            : (num + offset)/denom;
-
-        num = a2*c1 - a1*c2;
-
-        double y = num < 0d
-            ? (num - offset)/denom
-            : (num + offset)/denom;
-
-        return new Point2D.Double(x, y);
-    }
-
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/Linear.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/Linear.java	Fri Sep 28 12:15:40 2012 +0200
@@ -64,5 +64,15 @@
         //return (1.0-factor)*a + factor*b;
         return a + factor*(b-a);
     }
+
+    public static final void weight(
+        double factor,
+        double [] a, double [] b, double [] c
+    ) {
+        int N = Math.min(Math.min(a.length, b.length), c.length);
+        for (int i = 0; i < N; ++i) {
+            c[i] = weight(factor, a[i], b[i]);
+        }
+    }
 }
 // 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-artifacts/src/main/java/de/intevation/flys/artifacts/math/NaNFunction.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,16 @@
+package de.intevation.flys.artifacts.math;
+
+public final class NaNFunction
+implements         Function
+{
+    public static final Function INSTANCE = new NaNFunction();
+
+    private NaNFunction() {
+    }
+
+    @Override
+    public double value(double x) {
+        return Double.NaN;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/Outlier.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/Outlier.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,168 +1,107 @@
 package de.intevation.flys.artifacts.math;
 
+import java.util.List;
+
 import org.apache.commons.math.MathException;
 
+import org.apache.commons.math.distribution.TDistributionImpl;
+
 import org.apache.commons.math.stat.descriptive.moment.Mean;
 import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
 
-import org.apache.commons.math.distribution.TDistributionImpl;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.ArrayList;
-
 import org.apache.log4j.Logger;
 
 public class Outlier
 {
+    public static final double EPSILON = 1e-5;
+
     public static final double DEFAULT_ALPHA = 0.05;
 
     private static Logger log = Logger.getLogger(Outlier.class);
 
-    public static class IndexedValue
-    implements          Comparable<IndexedValue>
-    {
-        protected int    index;
-        protected double value;
-
-        public IndexedValue() {
-        }
-
-        public IndexedValue(int index, double value) {
-            this.index = index;
-            this.value = value;
-        }
-
-        public int getIndex() {
-            return index;
-        }
-
-        public void setIndex(int index) {
-            this.index = index;
-        }
-
-        public double getValue() {
-            return value;
-        }
-
-        public void setValue(double value) {
-            this.value = value;
-        }
+    protected Outlier() {
+    }
 
-        @Override
-        public int compareTo(IndexedValue other) {
-            int diff = index - other.index;
-            if (index < 0) return -1;
-            return index > 0 ? +1 : 0;
-        }
-    } // class IndexedValue
-
-    public static class Outliers {
-
-        protected List<IndexedValue> retained;
-        protected List<IndexedValue> removed;
-
-        public Outliers() {
-        }
+    public static Integer findOutlier(List<Double> values) {
+        return findOutlier(values, DEFAULT_ALPHA);
+    }
 
-        public Outliers(
-            List<IndexedValue> retained,
-            List<IndexedValue> removed
-        ) {
-            this.retained = retained;
-            this.removed  = removed;
-        }
+    public static Integer findOutlier(List<Double> values, double alpha) {
+        boolean debug = log.isDebugEnabled();
 
-        public boolean hasOutliers() {
-            return !removed.isEmpty();
-        }
-
-        public List<IndexedValue> getRetained() {
-            return retained;
-        }
-
-        public void setRetained(List<IndexedValue> retained) {
-            this.retained = retained;
+        if (debug) {
+            log.debug("outliers significance: " + alpha);
         }
 
-        public List<IndexedValue> getRemoved() {
-            return removed;
+        alpha = 1d - alpha;
+
+        int N = values.size();
+
+        if (debug) {
+            log.debug("Values to check: " + N);
         }
 
-        public void setRemoved(List<IndexedValue> removed) {
-            this.removed = removed;
+        if (N < 3) {
+            return null;
         }
-    } // class Outliers
-
-    public Outlier() {
-    }
-
-    public static Outliers findOutliers(List<IndexedValue> inputValues) {
-        return findOutliers(inputValues, DEFAULT_ALPHA);
-    }
-
-    public static Outliers findOutliers(
-        List<IndexedValue> inputValues,
-        double             alpha
-    ) {
-        ArrayList<IndexedValue> outliers = new ArrayList<IndexedValue>();
-
-        ArrayList<IndexedValue> values =
-            new ArrayList<IndexedValue>(inputValues);
-
-        for (;;) {
-            int N = values.size();
-
-            if (N < 4) {
-                break;
-            }
-
-            Mean mean = new Mean();
-            StandardDeviation std = new StandardDeviation();
 
-            for (IndexedValue value: values) {
-                mean.increment(value.getValue());
-                std .increment(value.getValue());
-            }
-
-            double m = mean.getResult();
-            double s = std.getResult();
+        Mean mean = new Mean();
+        StandardDeviation std = new StandardDeviation();
 
-            double maxZ = -Double.MAX_VALUE;
-            int iv = -1;
-            for (int i = N-1; i >= 0; --i) {
-                IndexedValue v = values.get(i);
-                double z = Math.abs(m - v.getValue())/s;
-                if (z > maxZ) {
-                    maxZ = z;
-                    iv = i;
-                }
-            }
-
-            double t = Math.sqrt((N*(N-2)*maxZ*maxZ)
-                /((N-1)*(N-1) - N*maxZ*maxZ));
+        for (Double value: values) {
+            double v = value.doubleValue();
+            mean.increment(v);
+            std .increment(v);
+        }
 
-            TDistributionImpl tdist = new TDistributionImpl(N-2);
-
-            try {
-                double p = tdist.cumulativeProbability(t);
+        double m = mean.getResult();
+        double s = std.getResult();
 
-                if (p < alpha) {
-                    outliers.add(values.get(iv));
-                    values.remove(iv);
-                }
-                else {
-                    break;
-                }
-            }
-            catch (MathException me) {
-                log.error(me);
+        if (debug) {
+            log.debug("mean: " + m);
+            log.debug("std dev: " + s);
+        }
+
+        double maxZ = -Double.MAX_VALUE;
+        int iv = -1;
+        for (int i = N-1; i >= 0; --i) {
+            double v = values.get(i).doubleValue();
+            double z = Math.abs(v - m);
+            if (z > maxZ) {
+                maxZ = z;
+                iv = i;
             }
         }
 
-        Collections.sort(outliers);
+        if (Math.abs(s) < EPSILON) {
+            return null;
+        }
 
-        return new Outliers(values, outliers);
+        maxZ /= s;
+
+        TDistributionImpl tdist = new TDistributionImpl(N-2);
+
+        double t;
+
+        try {
+            t = tdist.inverseCumulativeProbability(alpha/(N+N));
+        }
+        catch (MathException me) {
+            log.error(me);
+            return null;
+        }
+
+        t *= t;
+
+        double za = ((N-1)/Math.sqrt(N))*Math.sqrt(t/(N-2d+t));
+
+        if (debug) {
+            log.debug("max: " + maxZ + " crit: " + za);
+        }
+
+        return maxZ > za
+            ? Integer.valueOf(iv)
+            : 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-artifacts/src/main/java/de/intevation/flys/artifacts/math/UnivariateRealFunctionFunction.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,34 @@
+package de.intevation.flys.artifacts.math;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+public final class UnivariateRealFunctionFunction
+implements         Function
+{
+    private UnivariateRealFunction function;
+
+    public UnivariateRealFunctionFunction(UnivariateRealFunction function) {
+        this.function = function;
+    }
+
+    @Override
+    public double value(double x) {
+        try {
+            return function.value(x);
+        }
+        catch (FunctionEvaluationException fee) {
+            return Double.NaN;
+        }
+    }
+
+    public UnivariateRealFunction getFunction() {
+        return function;
+    }
+
+    public void setFunction(UnivariateRealFunction function) {
+        this.function = function;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AnnotationsFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AnnotationsFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -100,8 +100,7 @@
         riverQuery.setParameter("name", riverName);
         List<River> rivers = riverQuery.list();
         if (rivers.isEmpty()) {
-            List<Annotation> list = Collections.emptyList();
-            return list.iterator();
+            return Collections.<Annotation>emptyList().iterator();
         }
 
         Query query = session.createQuery(
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AreaFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AreaFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -27,8 +27,7 @@
  */
 public class AreaFacet
 extends      DefaultFacet
-implements   FacetTypes {
-
+{
     private static Logger logger = Logger.getLogger(AreaFacet.class);
 
     /**
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation4.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation4.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,22 +1,18 @@
 package de.intevation.flys.artifacts.model;
 
-import java.util.List;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Collections;
+import de.intevation.flys.artifacts.math.BackJumpCorrector;
+import de.intevation.flys.artifacts.math.Function;
+import de.intevation.flys.artifacts.math.Identity;
+import de.intevation.flys.artifacts.math.Linear;
+
+import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
+
+import de.intevation.flys.model.River;
 
 import de.intevation.flys.utils.DoubleUtil;
 
-import de.intevation.flys.model.River;
-import de.intevation.flys.model.Gauge;
-import de.intevation.flys.model.DischargeTable;
-
-import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
-
-import de.intevation.flys.artifacts.math.Function;
-import de.intevation.flys.artifacts.math.Linear;
-import de.intevation.flys.artifacts.math.Identity;
-import de.intevation.flys.artifacts.math.BackJumpCorrector;
+import java.util.Arrays;
+import java.util.List;
 
 import org.apache.log4j.Logger;
 
@@ -27,15 +23,6 @@
 
     public static final double MINIMAL_STEP_WIDTH = 1e-5;
 
-    public static final Comparator<Segment> REF_CMP =
-        new Comparator<Segment>() {
-            public int compare(Segment a, Segment b) {
-                double d = a.referencePoint - b.referencePoint;
-                if (d < 0d) return -1;
-                return d > 0d ? +1 : 0;
-            }
-        };
-
     protected List<Segment> segments;
 
     protected boolean       isQ;
@@ -48,65 +35,7 @@
         this.segments = segments;
         this.isQ      = isQ;
 
-        int numResults = -1;
-
-        // assign reference points
-        for (Segment segment: segments) {
-            Gauge gauge = river.maxOverlap(segment.getFrom(), segment.getTo());
-
-            if (gauge == null) {
-                logger.warn("no gauge found. Defaults to mid point.");
-                segment.setReferencePoint(
-                    0.5*(segment.getFrom()+segment.getTo()));
-            }
-            else {
-                double ref = gauge.getStation().doubleValue();
-                logger.debug(
-                    "reference gauge: " + gauge.getName() +
-                    " (km " + ref + ")");
-                segment.setReferencePoint(ref);
-            }
-
-            double [] values = segment.values;
-
-            if (numResults == -1) {
-                numResults = values.length;
-            }
-            else if (numResults != values.length) {
-                throw new IllegalArgumentException("wrong length of values");
-            }
-
-            // convert to Q if needed
-            if (!isQ && gauge != null) {
-
-                DischargeTable dt = gauge.fetchMasterDischargeTable();
-
-                double [][] table =
-                    DischargeTables.loadDischargeTableValues(dt, 1);
-
-                // need the original values for naming
-                segment.backup();
-
-                for (int i = 0; i < values.length; ++i) {
-                    double w = values[i] / 100.0;
-                    double [] qs = DischargeTables.getQsForW(table, w);
-                    if (qs.length == 0) {
-                        logger.warn("No Qs found for W = " + values[i]);
-                        addProblem("cannot.find.w.for.q", values[i]);
-                        values[i] = Double.NaN;
-                    }
-                    else {
-                        values[i] = qs[0];
-                        if (qs.length > 1) {
-                            logger.warn(
-                                "More than one Q found for W = " + values[i]);
-                        }
-                    }
-                }
-            }
-        } // for all segments
-
-        Collections.sort(segments, REF_CMP);
+        Segment.setReferencePointConvertQ(segments, river, isQ, this);
     }
 
     public CalculationResult calculate(
@@ -303,7 +232,7 @@
     }
 
     protected String createName(int index) {
-        // TODO: I18N
+        // TODO: i18n
         StringBuilder sb = new StringBuilder(isQ ? "Q" : "W");
         sb.append(" benutzerdefiniert (");
         for (int i = 0, N = segments.size(); i < N; ++i) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java	Fri Sep 28 12:15:40 2012 +0200
@@ -191,7 +191,7 @@
             }
         }
 
-        return (WQTimerange[]) wqts.toArray(new WQTimerange[wqts.size()]);
+        return wqts.toArray(new WQTimerange[wqts.size()]);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri Sep 28 12:15:40 2012 +0200
@@ -54,7 +54,14 @@
                 || type.equals(SQ_C_CURVE)
                 || type.equals(SQ_D_CURVE)
                 || type.equals(SQ_E_CURVE)
-                || type.equals(SQ_F_CURVE))
+                || type.equals(SQ_F_CURVE)
+                || type.equals(SQ_A_OUTLIER_CURVE)
+                || type.equals(SQ_B_OUTLIER_CURVE)
+                || type.equals(SQ_C_OUTLIER_CURVE)
+                || type.equals(SQ_D_OUTLIER_CURVE)
+                || type.equals(SQ_E_OUTLIER_CURVE)
+                || type.equals(SQ_F_OUTLIER_CURVE)
+                )
             {
                 return true;
             }
@@ -67,7 +74,14 @@
                 || type.equals(SQ_C_MEASUREMENT)
                 || type.equals(SQ_D_MEASUREMENT)
                 || type.equals(SQ_E_MEASUREMENT)
-                || type.equals(SQ_F_MEASUREMENT))
+                || type.equals(SQ_F_MEASUREMENT)
+                || type.equals(SQ_A_OUTLIER_MEASUREMENT)
+                || type.equals(SQ_B_OUTLIER_MEASUREMENT)
+                || type.equals(SQ_C_OUTLIER_MEASUREMENT)
+                || type.equals(SQ_D_OUTLIER_MEASUREMENT)
+                || type.equals(SQ_E_OUTLIER_MEASUREMENT)
+                || type.equals(SQ_F_OUTLIER_MEASUREMENT)
+                )
             {
                 return true;
             }
@@ -90,6 +104,7 @@
     };
 
     public enum ChartType {
+        FD("fix_derivate_curve"),
         LS("longitudinal_section"),
         CS("cross_section"),
         DLS("discharge_longitudinal_section"),
@@ -99,6 +114,10 @@
         RC("reference_curve"),
         RCN("reference_curve_normalized"),
         WD("wdifferences"),
+        FWQC("fix_wq_curve"),
+        FDWC("fix_deltawt_curve"),
+        FLSC("fix_longitudinal_section_curve"),
+        FDC("fix_derivate_curve"),
         HD("historical_discharge");
 
         private String chartTypeString;
@@ -107,6 +126,7 @@
             this.chartTypeString = description;
         }
 
+        @Override
         public String toString() {
             return chartTypeString;
         }
@@ -167,6 +187,8 @@
     String MANUALPOINTS = "manualpoints";
     String MANUALLINE = "manualline";
 
+    String QSECTOR        = "qsectors";
+
     String STATIC_WQ      = "other.wq";
     String STATIC_WQ_ANNOTATIONS = "other.wq.annotations";
     String STATIC_WKMS    = "other.wkms";
@@ -199,31 +221,60 @@
     String MIDDLE_BED_HEIGHT_EPOCH      = "bedheight_middle.epoch";
     String MIDDLE_BED_HEIGHT_ANNOTATION = "bedheight_middle.annotation";
 
+    String BED_QUALITY_POROSITY_TOPLAYER         = "bed_longitudinal_section.porosity_toplayer";
+    String BED_QUALITY_POROSITY_SUBLAYER         = "bed_longitudinal_section.porosity_sublayer";
+    String BED_QUALITY_BED_DIAMETER_TOPLAYER     = "bed_longitudinal_section.bed_diameter_toplayer";
+    String BED_QUALITY_BED_DIAMETER_SUBLAYER     = "bed_longitudinal_section.bed_diameter_sublayer";
+    String BED_QUALITY_SEDIMENT_DENSITY_TOPLAYER = "bed_longitudinal_section.sediment_density_toplayer";
+    String BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER = "bed_longitudinal_section.sediment_density_sublayer";
+    String BED_QUALITY_BEDLOAD_DIAMETER          = "bed_longitudinal_section.bedload_diameter";
+
+    String BED_DIFFERENCE_YEAR          = "bedheight_difference.year";
+    String BED_DIFFERENCE_HEIGHT_YEAR   = "bedheight_difference.height_year";
+    String BED_DIFFERENCE_EPOCH         = "bedheight_difference.epoch";
+    String BED_DIFFERENCE_MORPH_WIDTH   = "bedheight_difference.morph_width";
+    String BED_DIFFERENCE_YEAR_HEIGHT1  = "bedheight_difference.year.height1";
+    String BED_DIFFERENCE_YEAR_HEIGHT2  = "bedheight_difference.year.height2";
+    String BED_DIFFERENCE_EPOCH_HEIGHT1 = "bedheight_difference.epoch.height1";
+    String BED_DIFFERENCE_EPOCH_HEIGHT2 = "bedheight_difference.epoch.height2";
+
     String SQ_OVERVIEW       = "sq_overview";
 
     String SQ_A_CURVE       = "sq_a_curve";
     String SQ_A_MEASUREMENT = "sq_a_measurement";
     String SQ_A_OUTLIER     = "sq_a_outlier";
+    String SQ_A_OUTLIER_CURVE = "sq_a_outlier_curve";
+    String SQ_A_OUTLIER_MEASUREMENT = "sq_a_outlier_measurement";
 
     String SQ_B_CURVE       = "sq_b_curve";
     String SQ_B_MEASUREMENT = "sq_b_measurement";
     String SQ_B_OUTLIER     = "sq_b_outlier";
+    String SQ_B_OUTLIER_CURVE  = "sq_b_outlier_curve";
+    String SQ_B_OUTLIER_MEASUREMENT  = "sq_b_outlier_measurement";
 
     String SQ_C_CURVE       = "sq_c_curve";
     String SQ_C_MEASUREMENT = "sq_c_measurement";
     String SQ_C_OUTLIER     = "sq_c_outlier";
+    String SQ_C_OUTLIER_CURVE = "sq_c_outlier_curve";
+    String SQ_C_OUTLIER_MEASUREMENT = "sq_c_outlier_measurement";
 
     String SQ_D_CURVE       = "sq_d_curve";
     String SQ_D_MEASUREMENT = "sq_d_measurement";
     String SQ_D_OUTLIER     = "sq_d_outlier";
+    String SQ_D_OUTLIER_CURVE = "sq_d_outlier_curve";
+    String SQ_D_OUTLIER_MEASUREMENT = "sq_d_outlier_measurement";
 
     String SQ_E_CURVE       = "sq_e_curve";
     String SQ_E_MEASUREMENT = "sq_e_measurement";
     String SQ_E_OUTLIER     = "sq_e_outlier";
+    String SQ_E_OUTLIER_CURVE = "sq_e_outlier_curve";
+    String SQ_E_OUTLIER_MEASUREMENT = "sq_e_outlier_curve_measurement";
 
     String SQ_F_CURVE       = "sq_f_curve";
     String SQ_F_MEASUREMENT = "sq_f_measurement";
     String SQ_F_OUTLIER     = "sq_f_outlier";
+    String SQ_F_OUTLIER_CURVE = "sq_f_outlier_curve";
+    String SQ_F_OUTLIER_MEASUREMENT = "sq_f_outlier_measurement";
 
     String RELATIVE_POINT = "relativepoint";
 
@@ -234,7 +285,9 @@
     String FIX_REFERENCE_EVENTS_DWT = "fix_reference_events_dwt";
     String FIX_REFERENCE_EVENTS_LS = "fix_reference_events_ls";
     String FIX_REFERENCE_EVENTS_WQ = "fix_reference_events_wq";
+    String FIX_REFERENCE_PERIOD_DWT = "fix_reference_period_dwt";
 
+    // Note that AVERAGE_DWT will get a postfix (e.g. ..._dwt_1)
     String FIX_SECTOR_AVERAGE_DWT = "fix_sector_average_dwt";
     String FIX_SECTOR_AVERAGE_LS = "fix_sector_average_ls";
     String FIX_SECTOR_AVERAGE_WQ = "fix_sector_average_wq";
@@ -247,11 +300,13 @@
     String FIX_ANALYSIS_PERIODS_LS = "fix_analysis_periods_ls";
     String FIX_ANALYSIS_PERIODS_WQ = "fix_analysis_periods_wq";
 
-    String FIX_DERIVATE = "fix_derivate";
+    String FIX_DERIVATE_CURVE = "fix_derivate_curve";
 
     String FIX_DEVIATION_DWT = "fix_deviation_dwt";
     String FIX_DEVIATION_LS = "fix_deviation_ls";
 
     String FIX_PARAMETERS = "fix_parameters";
+
+    String STATIC_BEDHEIGHT = "static_bedheight";
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Fri Sep 28 12:15:40 2012 +0200
@@ -25,7 +25,7 @@
 {
     private static Logger log = Logger.getLogger(FixingsOverview.class);
 
-    public static final double EPSILON = 1e-1;
+    public static final double EPSILON = 1e-2;
 
     public static final String DATE_FORMAT = "dd.MM.yyyy";
 
@@ -78,7 +78,6 @@
         "    wst_column_id = :column_id";
 
 
-
     public static class QRange extends Range {
 
         protected double q;
@@ -105,6 +104,10 @@
             sector = other.sector;
         }
 
+        public SectorRange(Range range) {
+            super(range);
+        }
+
         public SectorRange(double start, double end, int sector) {
             super(start, end);
             this.sector = sector;
@@ -114,9 +117,13 @@
             return sector;
         }
 
+        public void setSector(int sector) {
+            this.sector = sector;
+        }
+
         public boolean enlarge(SectorRange other) {
             if (sector == other.sector
-            && Math.abs(end-other.start) < EPSILON) {
+            && Math.abs(end-other.start) < FixingsOverview.EPSILON) {
                 end = other.end;
                 return true;
             }
@@ -207,17 +214,24 @@
                 return -1;
             }
 
-            public void buildSectors(GaugeRange gauge, List<QRange> qRanges) {
-
+            public void buildSectors(
+                GaugeFinder  gaugeFinder,
+                List<QRange> qRanges
+            ) {
                 for (QRange qRange: qRanges) {
-                    SectorRange sector = new SectorRange(
-                        qRange.start, qRange.end,
-                        gauge.classify(qRange.q));
-                    if (sectors.isEmpty()
-                    || !sectors.get(sectors.size()-1).enlarge(sector)) {
-                        sectors.add(sector);
-                    }
-                }
+                    for (GaugeRange gRange: gaugeFinder.getGauges()) {
+                        SectorRange sector = new SectorRange(qRange);
+                        if (!sector.clip(gRange)) {
+                            continue;
+                        }
+                        sector.setSector(gRange.classify(qRange.q));
+
+                        if (sectors.isEmpty()
+                        || !sectors.get(sectors.size()-1).enlarge(sector)) {
+                            sectors.add(sector);
+                        }
+                    } // for all gauges
+                } // for all Q ranges
             }
 
             public void loadKmRange(SQLQuery query) {
@@ -254,14 +268,7 @@
                     }
                 }
 
-                GaugeRange gauge = gaugeFinder.find(this);
-
-                if (gauge != null) {
-                    buildSectors(gauge, qRanges);
-                }
-                else {
-                    log.warn("No gauge found for column " + columnId + ".");
-                }
+                buildSectors(gaugeFinder, qRanges);
             }
         } // class Column
 
@@ -680,6 +687,47 @@
         return allColumns;
     }
 
+    protected static Range realRange(List<Fixing.Column> columns) {
+        Range range = null;
+        for (Fixing.Column column: columns) {
+            if (range == null) {
+                range = new Range(column);
+            }
+            else {
+                range.extend(column);
+            }
+        }
+        return range;
+    }
+
+    protected Element intersectingGauges(Document document, Range range) {
+        Element gauges = document.createElement("gauges");
+
+        if (range == null) {
+            return gauges;
+        }
+
+        GaugeFinderFactory gff = GaugeFinderFactory.getInstance();
+
+        GaugeFinder gf = gff.getGaugeFinder(riverId, isKmUp);
+
+        if (gf == null) {
+            return gauges;
+        }
+
+        for (GaugeRange gr: gf.getGauges()) {
+            if (gr.intersects(range)) {
+                Element gauge = document.createElement("gauge");
+                gauge.setAttribute("from", String.valueOf(gr.getStart()));
+                gauge.setAttribute("to",   String.valueOf(gr.getEnd()));
+                gauge.setAttribute("name", gr.getName());
+                gauges.appendChild(gauge);
+            }
+        }
+
+        return gauges;
+    }
+
     public void generateOverview(
         Document      document,
         Range         range,
@@ -698,6 +746,11 @@
 
         fixingsElement.appendChild(riverElement);
 
+        fixingsElement.appendChild(
+            intersectingGauges(
+                document,
+                realRange(allColumns)));
+
         SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
 
         Element esE = document.createElement("events");
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,18 +1,21 @@
 package de.intevation.flys.artifacts.model;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
-import org.apache.log4j.Logger;
+import de.intevation.artifacts.Artifact;
 
-import de.intevation.artifacts.Artifact;
+import de.intevation.flys.artifacts.access.FlowVelocityAccess;
+
+import de.intevation.flys.artifacts.model.RiverFactory;
+
 import de.intevation.flys.model.DischargeZone;
 import de.intevation.flys.model.FlowVelocityModel;
 import de.intevation.flys.model.FlowVelocityModelValue;
 import de.intevation.flys.model.River;
 
-import de.intevation.flys.artifacts.access.FlowVelocityAccess;
-import de.intevation.flys.utils.FLYSUtils;
+import org.apache.log4j.Logger;
 
 
 public class FlowVelocityCalculation extends Calculation {
@@ -80,7 +83,17 @@
         FlowVelocityAccess  access,
         List<DischargeZone> zones
     ) {
-        River river = FLYSUtils.getRiver(access.getArtifact());
+        String riverName = access.getRiver();
+        if (riverName == null) {
+            logger.warn("No river name found");
+            return Collections.<FlowVelocityModel>emptyList();
+        }
+
+        River river = RiverFactory.getRiver(riverName);
+        if (river == null) {
+            logger.warn("No such river: " + riverName);
+            return Collections.<FlowVelocityModel>emptyList();
+        }
 
         List<FlowVelocityModel> models = new ArrayList<FlowVelocityModel>();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeDischargeCurveFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,57 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+
+import de.intevation.artifactdatabase.state.DefaultFacet;
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.flys.artifacts.model.WQKms;
+
+import de.intevation.flys.model.Gauge;
+
+/**
+ * A Facet that returns discharge curve data at a gauge
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeDischargeCurveFacet
+extends      DefaultFacet
+{
+    private Gauge gauge;
+    private String river;
+
+    public GaugeDischargeCurveFacet(String river, Gauge gauge) {
+        super(0, "facet.gauge.discharge_curve", "facet.gauge.discharge_curve");
+        this.river = river;
+        this.gauge = gauge;
+    }
+
+    @Override
+    public Object getData(Artifact art, CallContext context) {
+
+        DischargeTables dt = new DischargeTables(river, gauge.getName());
+
+        Map<String, double [][]> map = dt.getValues(100d);
+
+        double [][] values = map.get(name);
+        if (values == null) {
+            return null;
+        }
+        double [] kms = new double[values[0].length];
+        Arrays.fill(kms, gauge.getStation().doubleValue());
+        return new WQKms(kms, values[0], values[1], gauge.getName());
+    }
+
+    @Override
+    public Facet deepCopy() {
+        GaugeDischargeCurveFacet copy =
+            new GaugeDischargeCurveFacet(this.river, this.gauge);
+        copy.set(this);
+        return copy;
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeFinder.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeFinder.java	Fri Sep 28 12:15:40 2012 +0200
@@ -84,6 +84,10 @@
         return null;
     }
 
+    public List<GaugeRange> getGauges() {
+        return gauges;
+    }
+
     public boolean loadDischargeSectors(Session session, int riverId) {
 
         SQLQuery query = session.createSQLQuery(SQL_DISCHARGE_SECTORS)
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeFinderFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeFinderFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -28,6 +28,7 @@
     public static final String SQL_GAUGES =
         "SELECT" +
         "    g.id AS gauge_id," +
+        "    g.name AS name," +
         "    r.a  AS a," +
         "    r.b  AS b " +
         "FROM gauges g" +
@@ -89,6 +90,7 @@
     ) {
         SQLQuery query = session.createSQLQuery(SQL_GAUGES)
             .addScalar("gauge_id", StandardBasicTypes.INTEGER)
+            .addScalar("name",     StandardBasicTypes.STRING)
             .addScalar("a",        StandardBasicTypes.DOUBLE)
             .addScalar("b",        StandardBasicTypes.DOUBLE);
 
@@ -105,9 +107,10 @@
 
         for (Object [] row: list) {
             int    gaugeId = (Integer)row[0];
-            double start   = (Double) row[1];
-            double end     = (Double) row[2];
-            GaugeRange gauge = new GaugeRange(start, end, gaugeId);
+            String name    = (String) row[1];
+            double start   = (Double) row[2];
+            double end     = (Double) row[3];
+            GaugeRange gauge = new GaugeRange(start, end, name, gaugeId);
             gauges.add(gauge);
         }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeRange.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/GaugeRange.java	Fri Sep 28 12:15:40 2012 +0200
@@ -25,6 +25,8 @@
         }
     } // class Sector
 
+    protected String name;
+
     protected int gaugeId;
 
     protected Map<String, Double> mainValues;
@@ -34,7 +36,17 @@
     }
 
     public GaugeRange(double start, double end, int gaugeId) {
+        this(start, end, null, gaugeId);
+    }
+
+    public GaugeRange(
+        double start,
+        double end,
+        String name,
+        int    gaugeId
+    ) {
         super(start, end);
+        this.name = name;
         this.gaugeId = gaugeId;
         mainValues = new HashMap<String, Double>();
         sectors = new ArrayList<Sector>(3);
@@ -95,6 +107,14 @@
         return sectors.size();
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public String toString() {
         StringBuilder sb = new StringBuilder("sectors: [");
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/HYKFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/HYKFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,20 +1,17 @@
 package de.intevation.flys.artifacts.model;
 
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.DataProvider;
+import de.intevation.flys.artifacts.HYKArtifact;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+import de.intevation.flys.model.FastCrossSectionLine;
+
 import java.util.List;
 
 import org.apache.log4j.Logger;
 
-import de.intevation.artifacts.Artifact;
-import de.intevation.artifacts.CallContext;
-import de.intevation.artifacts.DataProvider;
-
-import de.intevation.artifactdatabase.state.Facet;
-
-import de.intevation.flys.artifacts.HYKArtifact;
-
-import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
-import de.intevation.flys.model.FastCrossSectionLine;
-
 
 /**
  * Trival Facet for HYKs
@@ -26,7 +23,6 @@
     /** House logger. */
     private static Logger logger = Logger.getLogger(HYKFacet.class);
 
-
     /** Trivial constructor, set (maybe localized) description. */
     public HYKFacet(int idx, String description) {
         super(idx, HYK, description, ComputeType.FEED, null, null);
@@ -40,7 +36,8 @@
      * @param art artifact to get data from.
      * @param context ignored
      */
-     public Object getData(Artifact art, CallContext context) {
+     @Override
+    public Object getData(Artifact art, CallContext context) {
         logger.debug("HYKFacet.getData");
 
         String dataKey = CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA;
@@ -54,6 +51,11 @@
         FastCrossSectionLine crossSection = (FastCrossSectionLine) providers.get(0)
             .provideData(dataKey, null, context);
 
+        if(crossSection == null) {
+            logger.debug("getData: crossSection is null");
+            return null;
+        }
+
         double km = crossSection.getKm();
         logger.debug("HYKFacet.getData: Master Cross Section is at km: " + km);
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-package de.intevation.flys.artifacts.model;
-
-import java.math.BigDecimal;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.hibernate.Session;
-import org.hibernate.Query;
-
-import de.intevation.flys.backend.SessionHolder;
-
-import de.intevation.flys.model.Gauge;
-import de.intevation.flys.model.MainValue;
-
-
-/**
- * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
- */
-public class MainValuesFactory {
-
-    private static Logger logger = Logger.getLogger(MainValuesFactory.class);
-
-    public static List<MainValue> getMainValues(Gauge gauge) {
-        Session session = SessionHolder.HOLDER.get();
-
-        Query query = session.createQuery(
-            "from MainValue where gauge=:gauge");
-        query.setParameter("gauge", gauge);
-
-        return query.list();
-    }
-
-
-    /**
-     * Returns an array of [days, qs] necessary to create duration curves.
-     *
-     * @param gauge The selected gauge.
-     *
-     * @return a 2dim array of [days, qs] where days is an int[] and qs is
-     * an double[].
-     */
-    public static Object[] getDurationCurveData(Gauge gauge) {
-        Session session = SessionHolder.HOLDER.get();
-
-        Query query = session.createQuery(
-            "select cast(nmv.name as integer) as days, mv.value as q " +
-            "from MainValue as mv " +
-            "join mv.mainValue as nmv " +
-            "join nmv.type mvt " +
-            "where mvt.name = 'D' and mv.gauge.id = :gauge_id " +
-            "order by days");
-
-        query.setParameter("gauge_id", gauge.getId());
-
-        List<Object> results = query.list();
-        int[]        days    = new int[results.size()];
-        double[]     qs      = new double[results.size()];
-
-        int idx = 0;
-
-        for (Object obj: results) {
-            Object[] arr = (Object[]) obj;
-
-            try {
-                int  day = ((Integer)    arr[0]).intValue();
-                double q = ((BigDecimal) arr[1]).doubleValue();
-
-                days[idx] = day;
-                qs[idx++] = q;
-            }
-            catch (NumberFormatException nfe) {
-                logger.warn(nfe, nfe);
-            }
-        }
-
-        return new Object[] { days, qs };
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -28,11 +28,12 @@
 implements   FacetTypes {
 
     /** Own logger. */
-    private static Logger logger = Logger.getLogger(RelativePointFacet.class);
+    private static Logger logger = Logger.getLogger(MainValuesQFacet.class);
 
     /** Do we want MainValues at Gauge (not interpolated)? */
     protected boolean isAtGauge;
 
+
     /** Trivial Constructor. */
     public MainValuesQFacet(String name, String description, boolean atGauge) {
         this.description = description;
@@ -41,6 +42,7 @@
         this.isAtGauge   = atGauge;
     }
 
+
     /**
      * Set the hit-point in Q where a line drawn from the axis would hit the
      * curve in WQDay (if hit).
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -25,7 +25,7 @@
 implements   FacetTypes {
 
     /** Own logger. */
-    private static Logger logger = Logger.getLogger(RelativePointFacet.class);
+    private static Logger logger = Logger.getLogger(MainValuesWFacet.class);
 
     /** Do we want MainValues at Gauge (not interpolated)? */
     protected boolean isAtGauge;
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -63,7 +63,7 @@
                 singles.add(s);
             }
             else {
-                logger.warn("Cannot find Sngle by id: " + id);
+                logger.warn("Cannot find Single by id: " + id);
                 // TODO ADD WARNING
             }
         }
@@ -95,7 +95,7 @@
 
 
     protected CalculationResult buildCalculationResult(
-        BedHeightAccess          access,
+        BedHeightAccess       access,
         List<BedHeightSingle> singles,
         List<BedHeightEpoch>  epochs
     ) {
@@ -146,12 +146,24 @@
             single.getDescription());
 
         for (BedHeightSingleValue value: values) {
-            data.addKM(value.getStation().doubleValue());
-            data.addMiddleHeight(value.getHeight().doubleValue());
-            data.addUncertainty(value.getUncertainty().doubleValue());
-            data.addSoundingWidth(value.getSoundingWidth().doubleValue());
-            data.addDataGap(value.getDataGap().doubleValue());
-            data.addWidth(value.getWidth().doubleValue());
+            if (value.getHeight() != null) {
+                data.addAll(value.getStation().doubleValue(),
+                    value.getHeight().doubleValue(),
+                    value.getUncertainty().doubleValue(),
+                    value.getSoundingWidth().doubleValue(),
+                    value.getDataGap().doubleValue(),
+                    value.getWidth().doubleValue(),
+                    false);
+             }
+            else {
+                data.addAll(value.getStation().doubleValue(),
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    true);
+            }
         }
 
         logger.debug("Single contains " + values.size() + " values");
@@ -160,6 +172,7 @@
     }
 
 
+    /** Create MiddleBedHeightData to return. */
     protected MiddleBedHeightData prepareEpochData(
         BedHeightEpoch epoch,
         double kmLo,
@@ -181,7 +194,14 @@
 
         for (BedHeightEpochValue value: values) {
             data.addKM(value.getStation().doubleValue());
-            data.addMiddleHeight(value.getHeight().doubleValue());
+            if (value.getHeight() != null) {
+                data.addMiddleHeight(value.getHeight().doubleValue());
+                data.addIsEmpty(false);
+            }
+            else {
+                data.addMiddleHeight(Double.NaN);
+                data.addIsEmpty(true);
+            }
         }
 
         logger.debug("Epoch contains " + values.size() + " values");
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightData.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightData.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,15 +2,22 @@
 
 import java.io.Serializable;
 
+import java.util.ArrayList;
+
 import gnu.trove.TDoubleArrayList;
 
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.flys.artifacts.resources.Resources;
 
+import org.apache.log4j.Logger;
+
 
 public class MiddleBedHeightData implements Serializable {
 
+    /** Very private logger. */
+    private static final Logger logger = Logger.getLogger(MiddleBedHeightData.class);
+
     public static final String I18N_SINGLE_NAME = "facet.bedheight_middle.single";
     public static final String I18N_EPOCH_NAME  = "facet.bedheight_middle.epoch";
 
@@ -25,6 +32,7 @@
     private TDoubleArrayList soundingWidth;
     private TDoubleArrayList dataGap;
     private TDoubleArrayList width;
+    private ArrayList empty;
 
 
     protected MiddleBedHeightData(int start, int end, String eval, String desc) {
@@ -39,6 +47,18 @@
         this.soundingWidth = new TDoubleArrayList();
         this.dataGap       = new TDoubleArrayList();
         this.width         = new TDoubleArrayList();
+        this.empty         = new ArrayList();
+    }
+
+    public void addAll(double station, double height, double uncertainty,
+        double soundingWidth, double dataGap, double width, boolean isEmpty) {
+        addKM(station);
+        addMiddleHeight(height);
+        addUncertainty(uncertainty);
+        addSoundingWidth(soundingWidth);
+        addDataGap(dataGap);
+        addWidth(width);
+        addIsEmpty(isEmpty);
     }
 
 
@@ -59,7 +79,7 @@
     }
 
 
-    public void addKM(double km) {
+    protected void addKM(double km) {
         this.km.add(km);
     }
 
@@ -67,7 +87,7 @@
         return km.get(idx);
     }
 
-    public void addMiddleHeight(double middleHeight) {
+    protected void addMiddleHeight(double middleHeight) {
         this.middleHeight.add(middleHeight);
     }
 
@@ -75,7 +95,7 @@
         return middleHeight.get(idx);
     }
 
-    public void addUncertainty(double uncertainty) {
+    protected void addUncertainty(double uncertainty) {
         this.uncertainty.add(uncertainty);
     }
 
@@ -83,7 +103,7 @@
         return uncertainty.get(idx);
     }
 
-    public void addSoundingWidth(double soundingWidth) {
+    protected void addSoundingWidth(double soundingWidth) {
         this.soundingWidth.add(soundingWidth);
     }
 
@@ -91,7 +111,7 @@
         return soundingWidth.get(idx);
     }
 
-    public void addDataGap(double gap) {
+    protected void addDataGap(double gap) {
         this.dataGap.add(gap);
     }
 
@@ -99,7 +119,16 @@
         return dataGap.get(idx);
     }
 
-    public void addWidth(double width) {
+    protected void addIsEmpty(boolean empty) {
+        this.empty.add(empty);
+    }
+
+    public boolean isEmpty(int idx) {
+        return (Boolean) empty.get(idx);
+    }
+
+
+    protected void addWidth(double width) {
         this.width.add(width);
     }
 
@@ -112,12 +141,22 @@
     }
 
 
+    /**
+     * Get the points, ready to be drawn
+     * @return [[km1, km2,...],[height1,height2,...]]
+     */
     public double[][] getMiddleHeightsPoints() {
         double[][] points = new double[2][size()];
 
         for (int i = 0, n = size(); i < n; i++) {
-            points[0][i] = getKM(i);
-            points[1][i] = getMiddleHeight(i);
+            if (isEmpty(i)) {
+                points[0][i] = getKM(i);
+                points[1][i] = Double.NaN;
+            }
+            else {
+                points[0][i] = getKM(i);
+                points[1][i] = getMiddleHeight(i);
+            }
         }
 
         return points;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Module.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,25 @@
+package de.intevation.flys.artifacts.model;
+
+/**
+ * Represents a Module as is is loaded from the config
+ */
+public class Module {
+
+    private String name;
+    private boolean selected;
+
+    public Module(String name, boolean selected) {
+        this.name = name;
+        this.selected = selected;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public boolean isSelected() {
+        return this.selected;
+    }
+}
+
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Parameters.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Parameters.java	Fri Sep 28 12:15:40 2012 +0200
@@ -97,6 +97,20 @@
         return invalid;
     }
 
+    public boolean set(int row, String [] names, double [] values) {
+        boolean success = true;
+        for (int i = 0; i < names.length; ++i) {
+            int idx = columnIndex(names[i]);
+            if (idx >= 0) {
+                columns[idx].setQuick(row, values[i]);
+            }
+            else {
+                success = false;
+            }
+        }
+        return success;
+    }
+
     public int size() {
         return columns[0].size();
     }
@@ -121,6 +135,13 @@
         return indices;
     }
 
+    public double getValue(int row, String column) {
+        int idx = columnIndex(column);
+        return idx >= 0
+            ? columns[idx].getQuick(row)
+            : Double.NaN;
+    }
+
     public double [] get(int row, String [] columns) {
         return get(row, columns, new double[columns.length]);
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Fri Sep 28 12:15:40 2012 +0200
@@ -212,6 +212,35 @@
         return root != null ? root.findQ(pos) : Double.NaN;
     }
 
+    protected Node head() {
+        Node head = root;
+        while (head.left != null) {
+            head = head.left;
+        }
+        return head;
+    }
+
+    public List<Range> findSegments(double a, double b) {
+        if (a > b) { double t = a; a = b; b = t; }
+        return findSegments(new Range(a, b));
+    }
+
+    public List<Range> findSegments(Range range) {
+        List<Range> segments = new ArrayList<Range>();
+
+        // Linear scan should be good enough here.
+        for (Node curr = head(); curr != null; curr = curr.next) {
+            if (!range.disjoint(curr.a, curr.b)) {
+                Range r = new Range(curr.a, curr.b);
+                if (r.clip(range)) {
+                    segments.add(r);
+                }
+            }
+        }
+
+        return segments;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QSectorFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,66 @@
+package de.intevation.flys.artifacts.model;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.QSectorArtifact;
+
+import de.intevation.artifactdatabase.state.DefaultFacet;
+import de.intevation.artifactdatabase.state.Facet;
+
+
+/**
+ * Facet to access QSector that where added by user.
+ */
+public class QSectorFacet
+extends      DefaultFacet
+{
+    /** Logger for this class. */
+    private static final Logger logger = Logger.getLogger(QSectorFacet.class);
+
+
+    /**
+     * Trivial Constructor.
+     */
+    public QSectorFacet() {
+    }
+
+
+    /**
+     * Trivial Constructor for a QSectorFacet.
+     *
+     * @param index       Database-Index to use.
+     * @param name        Name (~type) of Facet.
+     * @param description Description of Facet.
+     */
+    public QSectorFacet(int index, String name, String description) {
+        super(index, name, description);
+    }
+
+
+    /**
+     * Get List of QSector for river from Artifact.
+     *
+     * @param artifact (QSector-)Artifact to query for list of QSector.
+     * @param context  Ignored.
+     */
+    @Override
+    public Object getData(Artifact artifact, CallContext context) {
+        QSectorArtifact qsectorArtifact = (QSectorArtifact) artifact;
+        double currentKm =
+            ((Double)context.getContextValue("currentKm")).doubleValue();
+        return qsectorArtifact.getQSectors(currentKm, context);
+    }
+
+
+    /** Do a deep copy. */
+    @Override
+    public Facet deepCopy() {
+        QSectorFacet copy = new QSectorFacet();
+        copy.set(this);
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/QW.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,35 @@
+package de.intevation.flys.artifacts.model;
+
+import java.io.Serializable;
+
+public class QW
+implements   Serializable
+{
+    protected double q;
+    protected double w;
+
+    public QW() {
+    }
+
+    public QW(double q, double w) {
+        this.q = q;
+        this.w = w;
+    }
+
+    public double getQ() {
+        return q;
+    }
+
+    public void setQ(double q) {
+        this.q = q;
+    }
+
+    public double getW() {
+        return w;
+    }
+
+    public void setW(double w) {
+        this.w = w;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/QWDDateRange.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,24 @@
+package de.intevation.flys.artifacts.model;
+
+
+import java.io.Serializable;
+
+import de.intevation.flys.artifacts.model.fixings.QWD;
+
+public class QWDDateRange
+implements   Serializable
+{
+
+    public QWD qwd;
+    public DateRange dateRange;
+
+    public QWDDateRange(QWD qwd, DateRange dr) {
+        this.qwd = qwd;
+        this.dateRange = dr;
+    }
+
+    public QWD getQWD() {
+        return qwd;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Range.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Range.java	Fri Sep 28 12:15:40 2012 +0200
@@ -12,6 +12,11 @@
     public Range() {
     }
 
+    public Range(Range other) {
+        start = other.start;
+        end   = other.end;
+    }
+
     public Range(double start, double end) {
         this.start = start;
         this.end   = end;
@@ -25,6 +30,10 @@
         return end;
     }
 
+    public boolean disjoint(double ostart, double oend) {
+        return start > oend || ostart > end;
+    }
+
     public boolean disjoint(Range other) {
         return start > other.end || other.start > end;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/RangeWithValues.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/RangeWithValues.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,41 +1,32 @@
 package de.intevation.flys.artifacts.model;
 
-import java.io.Serializable;
-
+import java.util.Arrays;
 
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
-public class RangeWithValues implements Serializable {
+public class RangeWithValues extends Range {
 
-    protected double   lower;
-    protected double   upper;
     protected double[] values;
 
-
     public RangeWithValues() {
     }
 
-
     public RangeWithValues(double lower, double upper, double[] values) {
-        this.lower  = lower;
-        this.upper  = upper;
+        super(lower, upper);
         this.values = values;
     }
 
-
-    public double getLower() {
-        return lower;
-    }
-
-
-    public double getUpper() {
-        return upper;
-    }
-
-
     public double[] getValues() {
         return values;
     }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("start=").append(start)
+            .append(" end=" ).append(end)
+            .append(" values=[").append(Arrays.toString(values)).append(']')
+            .toString();
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/RelativePointFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/RelativePointFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -41,7 +41,7 @@
         // TODO here and in reference curve calc: Do warn if more than 1
         // provider found or (way better) handle it.
         Object wqdays = null;
-        double km = 0d;
+        double km     = 0d;
         List<DataProvider> providers = context.
             getDataProvider(DurationCurveFacet.BB_DURATIONCURVE);
         if (providers.size() < 1) {
@@ -93,7 +93,7 @@
             double day = 0d;
             int mod = (wIncreases) ? -1 : +1;
             if (idx != 0 && idx <= wqday.size()-1) {
-                day = Linear.linear(w, wqday.getW(idx +mod), wqday.getW(idx),
+                day = Linear.linear(w, wqday.getW(idx+mod), wqday.getW(idx),
                     wqday.getDay(idx+mod), wqday.getDay(idx));
             }
 
@@ -102,7 +102,6 @@
         logger.warn("not wqkms / w / day found");
         // TODO better signal failure.
         return new Point2D.Double(0d, 0d);
-        //return null;
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/SQOverview.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/SQOverview.java	Fri Sep 28 12:15:40 2012 +0200
@@ -23,6 +23,7 @@
 public class SQOverview
 implements   Serializable
 {
+    private static Logger log = Logger.getLogger(SQOverview.class);
 
     /**
      * Serial version UId.
@@ -79,8 +80,6 @@
         }
     };
 
-    private static Logger log = Logger.getLogger(FixingsOverview.class);
-
     public static final double EPSILON = 1e-4;
 
     public static final String DATE_FORMAT = "dd.MM.yyyy";
@@ -95,7 +94,7 @@
         "    JOIN gewaesser g " +
         "       ON s.gewaesserid = g.gewaesserid " +
         "WHERE" +
-        "    m.q IS NOT NULL AND" +
+        "    m.q_bpegel IS NOT NULL AND" +
         "    g.name = :name " +
         "ORDER by" +
         "    s.km, m.datum";
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Segment.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Segment.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,20 +1,34 @@
 package de.intevation.flys.artifacts.model;
 
-import java.util.List;
-import java.util.ArrayList;
+import de.intevation.flys.model.DischargeTable;
+import de.intevation.flys.model.Gauge;
+import de.intevation.flys.model.River;
+
+import de.intevation.flys.utils.DoubleUtil;
 
 import java.io.Serializable;
 
-import org.apache.log4j.Logger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
-import gnu.trove.TDoubleArrayList;
-
-import de.intevation.flys.utils.DoubleUtil;
+import org.apache.log4j.Logger;
 
 public class Segment
 implements   Serializable
 {
-    private static Logger logger = Logger.getLogger(Segment.class);
+    private static Logger log = Logger.getLogger(Segment.class);
+
+    public static final Comparator<Segment> REF_CMP =
+        new Comparator<Segment>() {
+            @Override
+            public int compare(Segment a, Segment b) {
+                double d = a.referencePoint - b.referencePoint;
+                if (d < 0d) return -1;
+                return d > 0d ? +1 : 0;
+            }
+        };
 
     protected double    from;
     protected double    to;
@@ -39,6 +53,13 @@
         return from < to;
     }
 
+    public boolean inside(double km) {
+        return from < to
+            ? km >= from && km <= to
+            : km >= to   && km <= from;
+    }
+
+    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("Segment: [");
         sb.append("from: ").append(from).append("; to: ")
@@ -58,7 +79,13 @@
     }
 
     public void backup() {
-        backup = (double [])values.clone();
+        backup = values != null
+            ? (double [])values.clone()
+            : null;
+    }
+
+    public double [] getBackup() {
+        return backup;
     }
 
     public double getFrom() {
@@ -81,6 +108,10 @@
         return values;
     }
 
+    public int numValues() {
+        return values.length;
+    }
+
     public void setReferencePoint(double referencePoint) {
         this.referencePoint = referencePoint;
     }
@@ -91,36 +122,89 @@
 
     public static List<Segment> parseSegments(String input) {
 
-        ArrayList<Segment> segments = new ArrayList<Segment>();
-
-        TDoubleArrayList vs = new TDoubleArrayList();
+        final List<Segment> segments = new ArrayList<Segment>();
 
-        for (String segmentStr: input.split(":")) {
-            String [] parts = segmentStr.split(";");
-            if (parts.length < 3) {
-                logger.warn("invalid segment: '" + segmentStr + "'");
-                continue;
-            }
-            try {
-                double from = Double.parseDouble(parts[0].trim());
-                double to   = Double.parseDouble(parts[1].trim());
-
-                vs.clear();
-
-                for (String valueStr: parts[2].split(",")) {
-                    vs.add(DoubleUtil.round(
-                        Double.parseDouble(valueStr.trim())));
-                }
-
-                double [] values = vs.toNativeArray();
+        DoubleUtil.parseSegments(input, new DoubleUtil.SegmentCallback() {
+            @Override
+            public void newSegment(double from, double to, double [] values) {
                 segments.add(new Segment(from, to, values));
             }
-            catch (NumberFormatException nfe) {
-                logger.warn("invalid segment: '" + segmentStr + "'");
-            }
-        }
+        });
 
         return segments;
     }
+
+    public static boolean setReferencePointConvertQ(
+        List<Segment> segments,
+        River         river,
+        boolean       isQ,
+        Calculation   report
+    ) {
+        int numResults = -1;
+
+        boolean success = true;
+
+        // assign reference points
+        for (Segment segment: segments) {
+            Gauge gauge = river.maxOverlap(segment.getFrom(), segment.getTo());
+
+            if (gauge == null) {
+                log.warn("no gauge found. Defaults to mid point.");
+                segment.setReferencePoint(
+                    0.5*(segment.getFrom()+segment.getTo()));
+            }
+            else {
+                double ref = gauge.getStation().doubleValue();
+                log.debug(
+                    "reference gauge: " + gauge.getName() +
+                    " (km " + ref + ")");
+                segment.setReferencePoint(ref);
+            }
+
+            double [] values = segment.values;
+
+            if (numResults == -1) {
+                numResults = values.length;
+            }
+            else if (numResults != values.length) {
+                log.warn("wrong length of values");
+                return false;
+            }
+
+            // convert to Q if needed
+            if (!isQ && gauge != null) {
+
+                DischargeTable dt = gauge.fetchMasterDischargeTable();
+
+                double [][] table =
+                    DischargeTables.loadDischargeTableValues(dt, 1);
+
+                // need the original values for naming
+                segment.backup();
+
+                for (int i = 0; i < values.length; ++i) {
+                    double w = values[i] / 100.0;
+                    double [] qs = DischargeTables.getQsForW(table, w);
+                    if (qs.length == 0) {
+                        log.warn("No Qs found for W = " + values[i]);
+                        report.addProblem("cannot.find.w.for.q", values[i]);
+                        values[i] = Double.NaN;
+                        success = false;
+                    }
+                    else {
+                        values[i] = qs[0];
+                        if (qs.length > 1) {
+                            log.warn(
+                                "More than one Q found for W = " + values[i]);
+                        }
+                    }
+                }
+            }
+        } // for all segments
+
+        Collections.sort(segments, Segment.REF_CMP);
+
+        return success;
+    }
 }
 // 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/StaticBedHeightCacheKey.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,28 @@
+package de.intevation.flys.artifacts.model;
+
+import java.io.Serializable;
+
+public class StaticBedHeightCacheKey implements Serializable {
+    public static final String CACHE_NAME = "bedheight-value-table-static";
+
+    private int time;
+    private int height_id;
+
+    public StaticBedHeightCacheKey(int column, int wst_id) {
+        this.height_id  = wst_id;
+        this.time  = column;
+    }
+
+    public int hashCode() {
+        return (height_id << 8) | time;
+    }
+
+    public boolean equals(Object other) {
+        if (!(other instanceof StaticBedHeightCacheKey)) {
+            return false;
+        }
+        StaticBedHeightCacheKey o = (StaticBedHeightCacheKey) other;
+        return this.height_id == o.height_id && this.time == o.time;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKmsFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKmsFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -16,12 +16,14 @@
 
 import de.intevation.flys.backend.SessionHolder;
 
+
 /**
  * Factory to access ready-made WKms for other (than computed) 'kinds' of
  * WST-data.
  */
 public class WKmsFactory
 {
+    /** Private logger to use here. */
     private static Logger log = Logger.getLogger(WKmsFactory.class);
 
     /** Query to get km and ws for wst_id and column_pos. */
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -42,7 +42,8 @@
     public Object getData(Artifact artifact, CallContext context) {
         WQKmsInterpolArtifact interpolData =
             (WQKmsInterpolArtifact) artifact;
-        return interpolData.getWQAtKm(10);
+        Double currentKm = (Double)context.getContextValue("currentKm");
+        return interpolData.getWQAtKm(currentKm);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQTimerange.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQTimerange.java	Fri Sep 28 12:15:40 2012 +0200
@@ -36,7 +36,7 @@
 
 
     public Timerange[] getTimeranges() {
-        return (Timerange[]) ts.toArray(new Timerange[ts.size()]);
+        return ts.toArray(new Timerange[ts.size()]);
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WaterlevelFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WaterlevelFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,7 @@
 import de.intevation.flys.artifacts.FLYSArtifact;
 
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+import de.intevation.flys.artifacts.math.Linear;
 
 import org.apache.log4j.Logger;
 
@@ -29,7 +30,6 @@
         ComputeType type,
         String      stateID,
         String      hash
-
     ) {
         super(index, name, description, type, hash, stateID);
     }
@@ -37,6 +37,9 @@
     public WaterlevelFacet() {
     }
 
+    protected WQKms [] getWQKms(CalculationResult res) {
+        return (WQKms [])res.getData();
+    }
 
     /**
      * Get waterlevel data.
@@ -49,14 +52,62 @@
                 " /stateId: " + stateId);
         }
 
-        FLYSArtifact winfo = (FLYSArtifact)artifact;
+        FLYSArtifact winfo = (FLYSArtifact) artifact;
 
         CalculationResult res = (CalculationResult)
             winfo.compute(context, hash, stateId, type, false);
 
-        WQKms [] wqkms = (WQKms [])res.getData();
+        if (res == null) {
+            logger.error("WaterlevelFacet.getData: null result");
+            return null;
+        }
 
-        return wqkms[index];
+        if (winfo == null) {
+            logger.error("WaterlevelFacet.getData: artifact is null");
+            return null;
+        }
+
+        WQKms [] wqkms = getWQKms(res);
+        Object KM = context.getContextValue("currentKm");
+        if (KM != null) {
+            logger.debug("interpolate at given km");
+            // TODO handle exact match.
+
+            WQKms wqkmsI = wqkms[index];
+            double km = (Double)KM;
+
+            // TODO employ DataUtils interface to TDoubleArraList
+            int size = wqkmsI.size();
+            boolean kmIncreasing = wqkmsI.getKm(0) < wqkmsI.getKm(size-1);
+            int mod = kmIncreasing ? +1 : -1;
+            int idx = 0;
+            if (!kmIncreasing) {
+                while (idx < size && wqkmsI.getKm(idx) < km) {
+                    idx++;
+                }
+            }
+            else {
+                idx = size-1;
+                while (idx > 0 && wqkmsI.getKm(idx) > km) {
+                    idx--;
+                }
+            }
+            WQKms resultWQKms = new WQKms();
+            if (idx != -1 && idx < size) {
+                double inW = Linear.linear(
+                    km,
+                    wqkmsI.getKm(idx), wqkmsI.getKm(idx-mod),
+                    wqkmsI.getW(idx), wqkmsI.getW(idx-mod));
+                double inQ = Linear.linear(
+                    km,
+                    wqkmsI.getKm(idx), wqkmsI.getKm(idx-mod),
+                    wqkmsI.getQ(idx), wqkmsI.getQ(idx-mod));
+                resultWQKms.add(inW, inQ, km);
+            }
+            return resultWQKms;
+        }
+
+        return wqkms != null ? wqkms[index] : null;
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1217,5 +1217,46 @@
         double q2 = columns[index  ].getQRangeTree().findQ(km);
         return Linear.weight(weight, q1, q2);
     }
+
+    public double [][] interpolateTabulated(double km) {
+        return interpolateTabulated(km, new double[2][columns.length]);
+    }
+
+    public double [][] interpolateTabulated(double km, double [][] result) {
+
+        int rowIndex = Collections.binarySearch(rows, new Row(km));
+
+        if (rowIndex >= 0) {
+            // Direct hit -> copy ws.
+            Row row = rows.get(rowIndex);
+            System.arraycopy(
+                row.ws, 0, result[0], 0,
+                Math.min(row.ws.length, result[0].length));
+        }
+        else {
+            rowIndex = -rowIndex -1;
+            if (rowIndex < 1 || rowIndex >= rows.size()) {
+                // Out of bounds.
+                return null;
+            }
+            // Interpolate ws.
+            Row r1 = rows.get(rowIndex-1);
+            Row r2 = rows.get(rowIndex);
+            double factor = Linear.factor(km, r1.km, r2.km);
+            Linear.weight(factor, r1.ws, r2.ws, result[0]);
+        }
+
+        double [] qs = result[1];
+        for (int i = Math.min(qs.length, columns.length)-1; i >= 0; --i) {
+            qs[i] = columns[i].getQRangeTree().findQ(km);
+        }
+        return result;
+    }
+
+    public List<Range> findSegments(double km1, double km2) {
+        return columns.length != 0
+            ? columns[columns.length-1].getQRangeTree().findSegments(km1, km2)
+            : Collections.<Range>emptyList();
+    }
 }
 // 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/Curve.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,107 @@
+package de.intevation.flys.artifacts.model.extreme;
+
+import de.intevation.flys.artifacts.math.Function;
+import de.intevation.flys.artifacts.math.NaNFunction;
+import de.intevation.flys.artifacts.math.UnivariateRealFunctionFunction;
+
+import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
+
+import java.io.Serializable;
+
+import java.lang.ref.SoftReference;
+
+import org.apache.commons.math.analysis.interpolation.SplineInterpolator;
+
+import org.apache.commons.math.exception.MathIllegalArgumentException;
+
+import org.apache.log4j.Logger;
+
+public class Curve
+implements   Serializable, Function
+{
+    private static Logger log = Logger.getLogger(Curve.class);
+
+    protected double [] qs;
+    protected double [] ws;
+    protected String    function;
+    protected double [] coeffs;
+
+    // The spline is pretty heavy weight so cache it with a soft ref only.
+    protected transient SoftReference<Function> spline;
+    protected transient Function                extrapolation;
+
+    public Curve() {
+    }
+
+    public Curve(
+        double [] qs,
+        double [] ws,
+        String    function,
+        double [] coeffs
+    ) {
+        this.qs       = qs;
+        this.ws       = ws;
+        this.function = function;
+        this.coeffs   = coeffs;
+    }
+
+    public double [] getQs() {
+        return qs;
+    }
+
+    public double [] getWs() {
+        return ws;
+    }
+
+    public String getFunction() {
+        return function;
+    }
+
+    public double [] getCoeffs() {
+        return coeffs;
+    }
+
+    @Override
+    public double value(double x) {
+        if (x < qs[0]) return Double.NaN;
+        return (x <= qs[qs.length-1]
+            ? getSpline()
+            : getExtrapolation()).value(x);
+    }
+
+    protected synchronized Function getExtrapolation() {
+        if (extrapolation == null) {
+            de.intevation.flys.artifacts.math.fitting.Function
+                f = FunctionFactory.getInstance().getFunction(function);
+
+            extrapolation = f != null
+                ? f.instantiate(coeffs)
+                : NaNFunction.INSTANCE;
+        }
+        return extrapolation;
+    }
+
+    protected synchronized Function getSpline() {
+        Function sp;
+        if (spline != null) {
+            if ((sp = spline.get()) != null) {
+                return sp;
+            }
+        }
+        spline = new SoftReference<Function>(sp = createSpline());
+        return sp;
+    }
+
+    protected Function createSpline() {
+        SplineInterpolator interpolator = new SplineInterpolator();
+        try {
+            return new UnivariateRealFunctionFunction(
+                interpolator.interpolate(qs, ws));
+        }
+        catch (MathIllegalArgumentException miae) {
+            log.debug("creation on spline failed", miae);
+            return NaNFunction.INSTANCE;
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,162 @@
+package de.intevation.flys.artifacts.model.extreme;
+
+import de.intevation.flys.artifacts.access.ExtremeAccess;
+
+import de.intevation.flys.artifacts.math.fitting.Function;
+import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
+
+import de.intevation.flys.artifacts.model.Calculation;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.RangeWithValues;
+import de.intevation.flys.artifacts.model.RiverFactory;
+import de.intevation.flys.artifacts.model.WstValueTable;
+import de.intevation.flys.artifacts.model.WstValueTableFactory;
+
+import de.intevation.flys.model.River;
+
+import de.intevation.flys.utils.DoubleUtil;
+
+import java.util.List;
+
+public class ExtremeCalculation
+extends      Calculation
+{
+    protected String                river;
+    protected String                function;
+    protected double                from;
+    protected double                to;
+    protected double                step;
+    protected double                percent;
+    protected List<RangeWithValues> ranges;
+
+    public ExtremeCalculation() {
+    }
+
+    public ExtremeCalculation(ExtremeAccess access) {
+        String                river    = access.getRiver();
+        String                function = access.getFunction();
+        Double                from     = access.getFrom();
+        Double                to       = access.getTo();
+        Double                step     = access.getStep();
+        Double                percent  = access.getPercent();
+        List<RangeWithValues> ranges   = access.getRanges();
+
+        if (river == null) {
+            // TODO: i18n
+            addProblem("extreme.no.river");
+        }
+
+        if (function == null) {
+            // TODO: i18n
+            addProblem("extreme.no.function");
+        }
+
+        if (from == null) {
+            // TODO: i18n
+            addProblem("extreme.no.from");
+        }
+
+        if (to == null) {
+            // TODO: i18n
+            addProblem("extreme.no.to");
+        }
+
+        if (step == null) {
+            // TODO: i18n
+            addProblem("extreme.no.step");
+        }
+
+        if (percent == null) {
+            // TODO: i18n
+            addProblem("extreme.no.percent");
+        }
+
+        if (ranges == null) {
+            // TODO: i18n
+            addProblem("extreme.no.ranges");
+        }
+
+        if (!hasProblems()) {
+            this.river    = river;
+            this.function = function;
+            this.from     = Math.min(from, to);
+            this.to       = Math.max(from, to);
+            this.step     = Math.max(0.001d, Math.abs(step)/1000d);
+            this.percent  = Math.max(0d, Math.min(100d, percent));
+            this.ranges   = ranges;
+        }
+    }
+
+    public CalculationResult calculate() {
+
+        WstValueTable wst = null;
+
+        River river = RiverFactory.getRiver(this.river);
+        if (river == null) {
+            // TODO: i18n
+            addProblem("extreme.no.such.river", this.river);
+        }
+        else {
+            wst = WstValueTableFactory.getTable(river);
+            if (wst == null) {
+                // TODO: i18n
+                addProblem("extreme.no.wst.table");
+            }
+        }
+
+        Function function =
+            FunctionFactory.getInstance().getFunction(this.function);
+        if (function == null) {
+            // TODO: i18n
+            addProblem("extreme.no.such.function", this.function);
+        }
+
+        return hasProblems()
+            ? new CalculationResult(this)
+            : innerCalculate(wst, function);
+    }
+
+    protected CalculationResult innerCalculate(
+        WstValueTable wst,
+        Function      function
+    ) {
+        RangeWithValues range = null;
+
+        KMs: for (double km = from; km <= to; km += step) {
+            double currentKm = DoubleUtil.round(km);
+
+            if (range == null || !range.inside(currentKm)) {
+                for (RangeWithValues r: ranges) {
+                    if (r.inside(currentKm)) {
+                        range = r;
+                        break;
+                    }
+                }
+                // TODO: i18n
+                addProblem(currentKm, "extreme.no.range");
+                continue KMs;
+            }
+
+            double [][] wqs = wst.interpolateTabulated(currentKm);
+            if (wqs == null) {
+                // TODO: i18n
+                addProblem(currentKm, "extreme.no.raw.data");
+                continue;
+            }
+
+            // XXX: This should not be necessary for model data.
+            if (!DoubleUtil.isValid(wqs)) {
+                // TODO: i18n
+                addProblem(currentKm, "extreme.invalid.data");
+                continue;
+            }
+            // TODO: Implement extraction of points for curve fitting.
+            // TODO: Implement curve fitting.
+            // TODO: Implement generating Curve object per km.
+        }
+
+        ExtremeResult result = new ExtremeResult();
+        return new CalculationResult(result, this);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,11 @@
+package de.intevation.flys.artifacts.model.extreme;
+
+import java.io.Serializable;
+
+public class ExtremeResult
+implements   Serializable
+{
+    public ExtremeResult() {
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/Fitting.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/Fitting.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,8 +1,5 @@
 package de.intevation.flys.artifacts.model.fixings;
 
-import de.intevation.flys.artifacts.math.Outlier.IndexedValue;
-import de.intevation.flys.artifacts.math.Outlier.Outliers;
-
 import de.intevation.flys.artifacts.math.Outlier;
 
 import de.intevation.flys.artifacts.math.fitting.Function;
@@ -40,18 +37,18 @@
         }
     };
 
-    protected boolean       checkOutliers;
-    protected Function      function;
-    protected QWDFactory    qwdFactory;
-    protected double        chiSqr;
-    protected double []     parameters;
-    protected ArrayList<QW> removed;
-    protected QWD []        referenced;
-    protected double        standardDeviation;
+    protected boolean        checkOutliers;
+    protected Function       function;
+    protected QWDFactory     qwdFactory;
+    protected double         chiSqr;
+    protected double []      parameters;
+    protected ArrayList<QWI> removed;
+    protected QWD []         referenced;
+    protected double         standardDeviation;
 
 
     public Fitting() {
-        removed = new ArrayList<QW>();
+        removed = new ArrayList<QWI>();
     }
 
     public Fitting(Function function) {
@@ -105,12 +102,12 @@
         return !removed.isEmpty();
     }
 
-    public List<QW> getOutliers() {
+    public List<QWI> getOutliers() {
         return removed;
     }
 
-    public QW [] outliersToArray() {
-        return removed.toArray(new QW[removed.size()]);
+    public QWI [] outliersToArray() {
+        return removed.toArray(new QWI[removed.size()]);
     }
 
     public QWD [] referencedToArray() {
@@ -120,7 +117,7 @@
     public double getMaxQ() {
         double maxQ = -Double.MAX_VALUE;
         if (referenced != null) {
-            for (QW qw: referenced) {
+            for (QWI qw: referenced) {
                 if (qw.getQ() > maxQ) {
                     maxQ = qw.getQ();
                 }
@@ -157,7 +154,7 @@
             return false;
         }
 
-        List<IndexedValue> inputs = new ArrayList<IndexedValue>(xs.size());
+        List<Double> inputs = new ArrayList<Double>(xs.size());
 
         de.intevation.flys.artifacts.math.Function instance = null;
 
@@ -204,27 +201,23 @@
             for (int i = 0, N = xs.size(); i < N; ++i) {
                 double y = instance.value(xs.getQuick(i));
                 if (Double.isNaN(y)) {
-                    continue;
+                    y = Double.MAX_VALUE;
                 }
-                inputs.add(new IndexedValue(i, ys.getQuick(i) - y));
+                inputs.add(Double.valueOf(ys.getQuick(i) - y));
             }
 
-            Outliers outliers = Outlier.findOutliers(inputs);
+            Integer outlier = Outlier.findOutlier(inputs);
 
-            if (!outliers.hasOutliers()) {
+            if (outlier == null) {
                 break;
             }
 
-            List<IndexedValue> rem = outliers.getRemoved();
-
-            for (int i = rem.size()-1; i >= 0; --i) {
-                int idx = rem.get(i).getIndex();
-                removed.add(
-                    qwdFactory.create(
-                        xs.getQuick(idx), ys.getQuick(idx)));
-                xs.remove(idx);
-                ys.remove(idx);
-            }
+            int idx = outlier.intValue();
+            removed.add(
+                qwdFactory.create(
+                    xs.getQuick(idx), ys.getQuick(idx)));
+            xs.remove(idx);
+            ys.remove(idx);
         }
 
         StandardDeviation stdDev = new StandardDeviation();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,293 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
+
+import de.intevation.flys.artifacts.math.fitting.Function;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DateRange;
+
+import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
+
+import de.intevation.flys.artifacts.model.FixingsOverview.Fixing.Filter;
+
+import de.intevation.flys.artifacts.model.FixingsOverview.Fixing;
+import de.intevation.flys.artifacts.model.FixingsOverview.IdsFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.KmFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.SectorFilter;
+
+import de.intevation.flys.artifacts.model.FixingsOverview;
+import de.intevation.flys.artifacts.model.Parameters;
+import de.intevation.flys.artifacts.model.Range;
+
+import de.intevation.flys.utils.DateAverager;
+import de.intevation.flys.utils.KMIndex;
+
+import gnu.trove.TIntIntHashMap;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
+
+import org.apache.log4j.Logger;
+
+public class FixAnalysisCalculation
+extends      FixCalculation
+{
+    private static Logger log = Logger.getLogger(FixAnalysisCalculation.class);
+
+    protected DateRange    referencePeriod;
+    protected DateRange [] analysisPeriods;
+
+    public FixAnalysisCalculation() {
+    }
+
+    public FixAnalysisCalculation(FixAnalysisAccess access) {
+        super(access);
+
+        DateRange    referencePeriod = access.getReferencePeriod();
+        DateRange [] analysisPeriods = access.getAnalysisPeriods();
+
+        if (referencePeriod == null) {
+            addProblem("fix.missing.reference.period");
+        }
+
+        if (analysisPeriods == null || analysisPeriods.length < 1) {
+            addProblem("fix.missing.analysis.periods");
+        }
+
+        if (!hasProblems()) {
+            this.referencePeriod = referencePeriod;
+            this.analysisPeriods = analysisPeriods;
+        }
+    }
+
+    @Override
+    public CalculationResult innerCalculate(
+        FixingsOverview overview,
+        Function        func
+    ) {
+        ColumnCache cc = new ColumnCache();
+
+        FitResult fitResult = doFitting(overview, cc, func);
+
+        if (fitResult == null) {
+            return new CalculationResult(this);
+        }
+
+        KMIndex<AnalysisPeriod []> analysisPeriods =
+            calculateAnalysisPeriods(
+                func,
+                fitResult.getParameters(),
+                overview,
+                cc);
+
+        analysisPeriods.sort();
+
+        FixAnalysisResult far = new FixAnalysisResult(
+            fitResult.getParameters(),
+            fitResult.getReferenced(),
+            fitResult.getOutliers(),
+            analysisPeriods);
+
+        return new CalculationResult(far, this);
+    }
+
+    @Override
+    protected Filter createFilter() {
+        Filter ids = super.createFilter();
+        DateRangeFilter rdf = new DateRangeFilter(
+            referencePeriod.getFrom(),
+            referencePeriod.getTo());
+        return new AndFilter().add(rdf).add(ids);
+    }
+
+    protected KMIndex<AnalysisPeriod []> calculateAnalysisPeriods(
+        Function        function,
+        Parameters      parameters,
+        FixingsOverview overview,
+        ColumnCache cc
+    ) {
+        Range range = new Range(from, to);
+
+        int kmIndex   = parameters.columnIndex("km");
+        int maxQIndex = parameters.columnIndex("max_q");
+
+        double [] wq = new double[2];
+
+        int [] parameterIndices =
+            parameters.columnIndices(function.getParameterNames());
+
+        double [] parameterValues = new double[parameterIndices.length];
+
+        DateAverager dateAverager = new DateAverager();
+
+        KMIndex<AnalysisPeriod []> results =
+            new KMIndex<AnalysisPeriod []>(parameters.size());
+
+        IdsFilter idsFilter = new IdsFilter(events);
+
+        TIntIntHashMap [] col2indices =
+            new TIntIntHashMap[analysisPeriods.length];
+
+        for (int i = 0; i < analysisPeriods.length; ++i) {
+            col2indices[i] = new TIntIntHashMap();
+        }
+
+        for (int row = 0, R = parameters.size(); row < R; ++row) {
+            double km = parameters.get(row, kmIndex);
+            parameters.get(row, parameterIndices, parameterValues);
+
+            // This is the paraterized function for a given km.
+            de.intevation.flys.artifacts.math.Function instance =
+                function.instantiate(parameterValues);
+
+            KmFilter kmFilter = new KmFilter(km);
+
+            ArrayList<AnalysisPeriod> periodResults =
+                new ArrayList<AnalysisPeriod>(analysisPeriods.length);
+
+            for (int ap = 0; ap < analysisPeriods.length; ++ap) {
+                DateRange analysisPeriod = analysisPeriods[ap];
+                TIntIntHashMap col2index = col2indices[ap];
+
+                DateRangeFilter drf = new DateRangeFilter(
+                    analysisPeriod.getFrom(),
+                    analysisPeriod.getTo());
+
+                QWD []    qSectorAverages = new QWD[4];
+                double [] qSectorStdDevs  = new double[4];
+
+                ArrayList<QWD> allQWDs = new ArrayList<QWD>();
+
+                // for all Q sectors.
+                for (int qSector = qSectorStart; qSector < qSectorEnd; ++qSector) {
+
+                    Filter filter = new AndFilter()
+                        .add(kmFilter)
+                        .add(new SectorFilter(qSector))
+                        .add(drf)
+                        .add(idsFilter);
+
+                    List<Fixing.Column> metas = overview.filter(range, filter);
+
+                    if (metas.isEmpty()) {
+                        // No fixings for km and analysis period
+                        continue;
+                    }
+
+                    double sumQ = 0.0;
+                    double sumW = 0.0;
+
+                    StandardDeviation stdDev = new StandardDeviation();
+
+                    List<QWD> qwds = new ArrayList<QWD>(metas.size());
+
+                    dateAverager.clear();
+
+                    for (Fixing.Column meta: metas) {
+                        if (meta.findQSector(km) != qSector) {
+                            // Ignore not matching sectors.
+                            continue;
+                        }
+
+                        Column column = cc.getColumn(meta);
+                        if (column == null || !column.getQW(km, wq)) {
+                            continue;
+                        }
+
+                        double fw = instance.value(wq[1]);
+                        if (Double.isNaN(fw)) {
+                            continue;
+                        }
+
+                        double dw = (wq[0] - fw)*100.0;
+
+                        stdDev.increment(dw);
+
+                        Date date = column.getDate();
+                        String description = column.getDescription();
+
+                        QWD qwd = new QWD(
+                            wq[1], wq[0],
+                            description,
+                            date, true,
+                            dw, getIndex(col2index, column.getIndex()));
+
+                        qwds.add(qwd);
+
+                        sumW += wq[0];
+                        sumQ += wq[1];
+
+                        dateAverager.add(date);
+                    }
+
+                    // Calulate average per Q sector.
+                    int N = qwds.size();
+                    if (N > 0) {
+                        allQWDs.addAll(qwds);
+                        double avgW = sumW / N;
+                        double avgQ = sumQ / N;
+
+                        double avgFw = instance.value(avgQ);
+                        if (!Double.isNaN(avgFw)) {
+                            double avgDw = (avgW - avgFw)*100.0;
+                            Date avgDate = dateAverager.getAverage();
+
+                            String avgDescription = "avg.deltawt." + qSector;
+
+                            QWD avgQWD = new QWD(
+                                avgQ, avgW, avgDescription, avgDate, true, avgDw, 0);
+
+                            qSectorAverages[qSector] = avgQWD;
+                        }
+                        qSectorStdDevs[qSector] = stdDev.getResult();
+                    }
+                    else {
+                        qSectorStdDevs[qSector] = Double.NaN;
+                    }
+                } // for all Q sectors
+
+                QWD [] aqwds = allQWDs.toArray(new QWD[allQWDs.size()]);
+
+                AnalysisPeriod periodResult = new AnalysisPeriod(
+                    analysisPeriod,
+                    aqwds,
+                    qSectorAverages,
+                    qSectorStdDevs);
+                periodResults.add(periodResult);
+            }
+
+            double maxQ = -Double.MAX_VALUE;
+            for (AnalysisPeriod ap: periodResults) {
+                double q = ap.getMaxQ();
+                if (q > maxQ) {
+                    maxQ = q;
+                }
+            }
+
+            double oldMaxQ = parameters.get(row, maxQIndex);
+            if (oldMaxQ < maxQ) {
+                parameters.set(row, maxQIndex, maxQ);
+            }
+
+            results.add(km, periodResults.toArray(
+                new AnalysisPeriod[periodResults.size()]));
+        }
+
+        return results;
+    }
+
+    private static final int getIndex(TIntIntHashMap map, int colIdx) {
+        if (map.containsKey(colIdx)) {
+            return map.get(colIdx);
+        }
+        int index = map.size();
+        map.put(colIdx, index);
+        return index;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisEventsFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisEventsFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,8 +5,6 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
-
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
@@ -61,14 +59,13 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
             double currentKm =
                 ((Double)context.getContextValue("currentKm")).doubleValue();
 
@@ -86,8 +83,18 @@
                 logger.debug("getData: periods == null");
                 return null;
             }
-            QWD[] qwdData = periods[index].getQWDs();
-            return qwdData;
+            int ndx = index >> 8;
+            QWD[] qwdData = periods[ndx].getQWDs();
+            if (qwdData == null) {
+                return null;
+            }
+            int ndy = index & 255;
+            for (int i = 0; i < qwdData.length; i++) {
+                if (qwdData[i].getIndex() == ndy) {
+                    return qwdData[i];
+                }
+            }
+            return null;
         }
         else {
             logger.debug("Not an instance of FixationArtifact.");
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisPeriodsFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisPeriodsFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,7 +5,7 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
@@ -62,14 +62,14 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
+            FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
             double currentKm =
                 ((Double)context.getContextValue("currentKm")).doubleValue();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,77 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.TreeSet;
+
+import de.intevation.flys.artifacts.model.Parameters;
+
+import de.intevation.flys.utils.KMIndex;
+
+public class FixAnalysisResult
+extends      FixResult
+{
+    protected KMIndex<AnalysisPeriod []> analysisPeriods;
+
+    public FixAnalysisResult() {
+    }
+
+    public FixAnalysisResult(
+        Parameters                 parameters,
+        KMIndex<QWD []>            referenced,
+        KMIndex<QWI []>            outliers,
+        KMIndex<AnalysisPeriod []> analysisPeriods
+    ) {
+        super(parameters, referenced, outliers);
+        this.analysisPeriods = analysisPeriods;
+    }
+
+    public int getUsedSectorsInAnalysisPeriods() {
+        int result = 0;
+        for (KMIndex.Entry<AnalysisPeriod []> entry: analysisPeriods) {
+            for (AnalysisPeriod period: entry.getValue()) {
+                for (int i = 0; i < 4; ++i) {
+                    result |= period.getQSectorAverage(i) != null
+                        ? (1 << i)
+                        : 0;
+                }
+                // XXX: Stop early on result == ~(~0 << 4)) ?
+            }
+        }
+        return result;
+    }
+
+    public Collection<Date> getReferenceEventsDates() {
+        TreeSet<Date> dates = new TreeSet<Date>();
+        for (KMIndex.Entry<QWD []> entry: referenced) {
+            QWD [] values = entry.getValue();
+            for (int i = 0; i < values.length; i++) {
+                dates.add(values[i].date);
+            }
+        }
+        return dates;
+    }
+
+    public Collection<Date> getAnalysisEventsDates(int analysisPeriod) {
+        TreeSet<Date> dates = new TreeSet<Date>();
+        for (KMIndex.Entry<AnalysisPeriod []> entry: analysisPeriods) {
+            QWD [] qwds = entry.getValue()[analysisPeriod].getQWDs();
+            if (qwds == null) {
+                continue;
+            }
+            for (int i = 0; i < qwds.length; i++) {
+                dates.add(qwds[i].date);
+            }
+        }
+        return dates;
+    }
+
+    public KMIndex<AnalysisPeriod []> getAnalysisPeriods() {
+        return analysisPeriods;
+    }
+
+    public void setAnalysisPeriods(KMIndex<AnalysisPeriod []> analysisPeriods) {
+        this.analysisPeriods = analysisPeriods;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAvSectorFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAvSectorFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,12 +5,14 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
 
+import de.intevation.flys.artifacts.model.QWDDateRange;
+
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
 
 import de.intevation.flys.utils.KMIndex;
@@ -60,14 +62,14 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
+            FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
 
             double currentKm =
                 ((Double)context.getContextValue("currentKm")).doubleValue();
@@ -103,7 +105,7 @@
             if (qwdData == null) {
                 return null;
             }
-            return qwdData[sectorNdx];
+            return new QWDDateRange(qwdData[sectorNdx], periods[periodNdx].getDateRange());
         }
         else {
             logger.warn("Artifact is no instance of FLYSArtifact.");
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,33 +1,26 @@
 package de.intevation.flys.artifacts.model.fixings;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.artifacts.common.utils.StringUtils;
+
+import de.intevation.flys.artifacts.access.FixAccess;
 
 import de.intevation.flys.artifacts.math.fitting.Function;
 import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
 
 import de.intevation.flys.artifacts.model.Calculation;
 import de.intevation.flys.artifacts.model.CalculationResult;
-import de.intevation.flys.artifacts.model.DateRange;
 import de.intevation.flys.artifacts.model.FixingsColumn;
 import de.intevation.flys.artifacts.model.FixingsColumnFactory;
 
-import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
-
 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing.Filter;
 
 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing;
 import de.intevation.flys.artifacts.model.FixingsOverview.IdsFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.KmFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.SectorFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
 
 import de.intevation.flys.artifacts.model.FixingsOverview;
 import de.intevation.flys.artifacts.model.FixingsOverviewFactory;
 import de.intevation.flys.artifacts.model.Parameters;
-import de.intevation.flys.artifacts.model.Range;
 
-import de.intevation.flys.utils.DateAverager;
 import de.intevation.flys.utils.DoubleUtil;
 import de.intevation.flys.utils.KMIndex;
 
@@ -37,45 +30,150 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
-
 import org.apache.log4j.Logger;
 
-public class FixCalculation
-extends      Calculation
+public abstract class FixCalculation
+extends               Calculation
 {
     private static Logger log = Logger.getLogger(FixCalculation.class);
 
     public static final double EPSILON = 1e-4;
 
-    protected String       river;
-    protected double       from;
-    protected double       to;
-    protected double       step;
-    protected boolean      preprocessing;
-    protected String       function;
-    protected int []       events;
-    protected DateRange    referencePeriod;
-    protected DateRange [] analysisPeriods;
-    protected int          qSectorStart;
-    protected int          qSectorEnd;
+    public static final String [] STANDARD_COLUMNS = {
+        "km", "chi_sqr", "max_q", "std-dev"
+    };
+
+    protected static class FitResult {
+
+        protected Parameters      parameters;
+        protected KMIndex<QWD []> referenced;
+        protected KMIndex<QWI []> outliers;
+
+        public FitResult() {
+        }
+
+        public FitResult(
+            Parameters      parameters,
+            KMIndex<QWD []> referenced,
+            KMIndex<QWI []> outliers
+        ) {
+            this.parameters = parameters;
+            this.referenced = referenced;
+            this.outliers   = outliers;
+        }
+
+        public Parameters getParameters() {
+            return parameters;
+        }
+
+        public KMIndex<QWD []> getReferenced() {
+            return referenced;
+        }
+
+        public KMIndex<QWI []> getOutliers() {
+            return outliers;
+        }
+    } // class FitResult
+
+    /** Helper class to bundle the meta information of a column
+     *  and the real data.
+     */
+    protected static class Column {
+
+        protected Fixing.Column meta;
+        protected FixingsColumn data;
+        protected int           index;
+
+        public Column() {
+        }
+
+        public Column(Fixing.Column meta, FixingsColumn data, int index) {
+            this.meta  = meta;
+            this.data  = data;
+            this.index = index;
+        }
+
+        public Date getDate() {
+            return meta.getStartTime();
+        }
+
+        public String getDescription() {
+            return meta.getDescription();
+        }
+
+        public int getIndex() {
+            return index;
+        }
+
+        public boolean getQW(
+            double    km,
+            double [] qs,
+            double [] ws,
+            int       index
+        ) {
+            qs[index] = data.getQ(km);
+            return data.getW(km, ws, index);
+        }
+
+        public boolean getQW(double km, double [] wq) {
+            data.getW(km, wq, 0);
+            if (Double.isNaN(wq[0])) return false;
+            wq[1] = data.getQ(km);
+            return !Double.isNaN(wq[1]);
+        }
+    } // class Column
+
+    /**
+     * Helper class to find the data belonging to meta info more quickly.
+     */
+    protected static class ColumnCache {
+
+        protected Map<Integer, Column> columns;
+
+        public ColumnCache() {
+            columns = new HashMap<Integer, Column>();
+        }
+
+        public Column getColumn(Fixing.Column meta) {
+            Integer key = meta.getId();
+            Column column = columns.get(key);
+            if (column == null) {
+                FixingsColumn data = FixingsColumnFactory
+                    .getInstance()
+                    .getColumnData(meta);
+                if (data != null) {
+                    column = new Column(meta, data, columns.size());
+                    columns.put(key, column);
+                }
+            }
+            return column;
+        }
+    } // class ColumnCache
+
+
+    protected String  river;
+    protected double  from;
+    protected double  to;
+    protected double  step;
+    protected boolean preprocessing;
+    protected String  function;
+    protected int []  events;
+    protected int     qSectorStart;
+    protected int     qSectorEnd;
 
     public FixCalculation() {
     }
 
-    public FixCalculation(FixationArtifactAccess access) {
-
-        String       river           = access.getRiver();
-        Double       from            = access.getFrom();
-        Double       to              = access.getTo();
-        Double       step            = access.getStep();
-        String       function        = access.getFunction();
-        int []       events          = access.getEvents();
-        DateRange    referencePeriod = access.getReferencePeriod();
-        DateRange [] analysisPeriods = access.getAnalysisPeriods();
-        Integer      qSectorStart    = access.getQSectorStart();
-        Integer      qSectorEnd      = access.getQSectorEnd();
-        Boolean      preprocessing   = access.getPreprocessing();
+    public FixCalculation(FixAccess access) {
+        String  river         = access.getRiver();
+        Double  from          = access.getFrom();
+        Double  to            = access.getTo();
+        Double  step          = access.getStep();
+        String  function      = access.getFunction();
+        int []  events        = access.getEvents();
+        Integer qSectorStart  = access.getQSectorStart();
+        Integer qSectorEnd    = access.getQSectorEnd();
+        Boolean preprocessing = access.getPreprocessing();
 
         if (river == null) {
             addProblem("fix.missing.river");
@@ -101,14 +199,6 @@
             addProblem("fix.missing.events");
         }
 
-        if (referencePeriod == null) {
-            addProblem("fix.missing.reference.period");
-        }
-
-        if (analysisPeriods == null || analysisPeriods.length < 1) {
-            addProblem("fix.missing.analysis.periods");
-        }
-
         if (qSectorStart == null) {
             addProblem("fix.missing.qstart.sector");
         }
@@ -122,51 +212,74 @@
         }
 
         if (!hasProblems()) {
-            this.river           = river;
-            this.from            = from;
-            this.to              = to;
-            this.step            = step;
-            this.function        = function;
-            this.events          = events;
-            this.referencePeriod = referencePeriod;
-            this.analysisPeriods = analysisPeriods;
-            this.qSectorStart    = qSectorStart;
-            this.qSectorEnd      = qSectorEnd;
-            this.preprocessing   = preprocessing;
+            this.river         = river;
+            this.from          = from;
+            this.to            = to;
+            this.step          = step;
+            this.function      = function;
+            this.events        = events;
+            this.qSectorStart  = qSectorStart;
+            this.qSectorEnd    = qSectorEnd;
+            this.preprocessing = preprocessing;
         }
     }
 
-    public CalculationResult calculate() {
-
-        boolean debug = log.isDebugEnabled();
+    protected static String toString(
+        String [] parameterNames,
+        double [] values
+    ) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < parameterNames.length; ++i) {
+            if (i > 0) sb.append(", ");
+            sb.append(parameterNames[i]).append(": ").append(values[i]);
+        }
+        return sb.toString();
+    }
 
-        FixingsOverview overview =
-            FixingsOverviewFactory.getOverview(river);
+    protected Filter createFilter() {
+        return new IdsFilter(events);
+    }
 
-        if (overview == null) {
-            addProblem("fix.no.overview.available");
+    protected List<Column> getEventColumns(
+        FixingsOverview overview,
+        ColumnCache     cc
+    ) {
+        FixingsColumnFactory fcf = FixingsColumnFactory.getInstance();
+
+        Filter filter = createFilter();
+
+        List<Fixing.Column> metas = overview.filter(null, filter);
+
+        List<Column> columns = new ArrayList<Column>(metas.size());
+
+        for (Fixing.Column meta: metas) {
+
+            Column data = cc.getColumn(meta);
+            if (data == null) {
+                addProblem("fix.cannot.load.data");
+            }
+            else {
+                columns.add(data);
+            }
         }
 
-        Function func = FunctionFactory.getInstance()
-            .getFunction(function);
+        return columns;
+    }
 
-        if (func == null) {
-            addProblem("fix.invalid.function.name");
-        }
+    protected FitResult doFitting(
+        FixingsOverview overview,
+        ColumnCache     cc,
+        Function        func
+    ) {
+        boolean debug = log.isDebugEnabled();
 
-        if (hasProblems()) {
-            return new CalculationResult(this);
-        }
-
-        final List<Column> eventColumns = getEventColumns(overview);
+        final List<Column> eventColumns = getEventColumns(overview, cc);
 
         if (eventColumns.size() < 2) {
             addProblem("fix.too.less.data.columns");
-            return new CalculationResult(this);
+            return null;
         }
 
-        double [] kms = DoubleUtil.explode(from, to, step / 1000.0);
-
         final double  [] qs = new double[eventColumns.size()];
         final double  [] ws = new double[qs.length];
         final boolean [] interpolated = new boolean[ws.length];
@@ -185,7 +298,8 @@
                             column.getDescription(),
                             column.getDate(),
                             interpolated[i],
-                            0d);
+                            0d,
+                            column.getIndex());
                     }
                 }
                 log.warn("cannot find column for (" + q + ", " + w + ")");
@@ -198,15 +312,18 @@
         String [] parameterNames = func.getParameterNames();
 
         Parameters results =
-            new Parameters(createColumnNames(parameterNames));
+            new Parameters(
+                StringUtils.join(STANDARD_COLUMNS, parameterNames));
 
         boolean invalid = false;
 
+        double [] kms = DoubleUtil.explode(from, to, step / 1000.0);
+
         if (debug) {
             log.debug("number of kms: " + kms.length);
         }
 
-        KMIndex<QW []>  outliers   = new KMIndex<QW []>();
+        KMIndex<QWI []> outliers   = new KMIndex<QWI []>();
         KMIndex<QWD []> referenced = new KMIndex<QWD []>(kms.length);
 
         int kmIndex             = results.columnIndex("km");
@@ -263,355 +380,40 @@
             results.removeNaNs();
         }
 
-        KMIndex<AnalysisPeriod []> analysisPeriods =
-            calculateAnalysisPeriods(func, results, overview);
-
         outliers.sort();
         referenced.sort();
-        analysisPeriods.sort();
-
-        FixResult fr = new FixResult(
-            results,
-            referenced, outliers,
-            analysisPeriods);
-
-        return new CalculationResult(fr, this);
-    }
-
-    protected String toString(String [] parameterNames, double [] values) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < parameterNames.length; ++i) {
-            if (i > 0) sb.append(", ");
-            sb.append(parameterNames[i]).append(": ").append(values[i]);
-        }
-        return sb.toString();
-    }
-
-    protected List<Column> getEventColumns(FixingsOverview overview) {
 
-        FixingsColumnFactory fcf = FixingsColumnFactory.getInstance();
-
-        IdsFilter ids = new IdsFilter(events);
-        DateRangeFilter rdf = new DateRangeFilter(
-            referencePeriod.getFrom(),
-            referencePeriod.getTo());
-        Filter filter = new AndFilter().add(rdf).add(ids);
-
-        List<Fixing.Column> metas = overview.filter(null, filter);
-
-        List<Column> columns = new ArrayList<Column>(metas.size());
-
-        for (Fixing.Column meta: metas) {
-
-            FixingsColumn data = fcf.getColumnData(meta);
-            if (data == null) {
-                addProblem("fix.cannot.load.data");
-            }
-            else {
-                columns.add(new Column(meta, data));
-            }
-        }
-
-        return columns;
+        return new FitResult(
+            results,
+            referenced,
+            outliers);
     }
 
-
-    protected KMIndex<AnalysisPeriod []> calculateAnalysisPeriods(
-        Function        function,
-        Parameters      parameters,
-        FixingsOverview overview
-    ) {
-        Range range = new Range(from, to);
-
-        int kmIndex   = parameters.columnIndex("km");
-        int maxQIndex = parameters.columnIndex("max_q");
-
-        ColumnCache cc = new ColumnCache();
-
-        double [] wq = new double[2];
-
-        int [] parameterIndices =
-            parameters.columnIndices(function.getParameterNames());
-
-        double [] parameterValues = new double[parameterIndices.length];
-
-        DateAverager dateAverager = new DateAverager();
-
-        KMIndex<AnalysisPeriod []> results =
-            new KMIndex<AnalysisPeriod []>(parameters.size());
-
-        IdsFilter idsFilter = new IdsFilter(events);
-
-        for (int row = 0, R = parameters.size(); row < R; ++row) {
-            double km = parameters.get(row, kmIndex);
-            parameters.get(row, parameterIndices, parameterValues);
-
-            // This is the paraterized function for a given km.
-            de.intevation.flys.artifacts.math.Function instance =
-                function.instantiate(parameterValues);
-
-            KmFilter kmFilter = new KmFilter(km);
-
-            ArrayList<AnalysisPeriod> periodResults =
-                new ArrayList<AnalysisPeriod>(analysisPeriods.length);
-
-            for (DateRange analysisPeriod: analysisPeriods) {
-                DateRangeFilter drf = new DateRangeFilter(
-                    analysisPeriod.getFrom(),
-                    analysisPeriod.getTo());
-
-                QWD []    qSectorAverages = new QWD[4];
-                double [] qSectorStdDevs  = new double[4];
-
-                ArrayList<QWD> allQWDs = new ArrayList<QWD>();
-
-                // for all Q sectors.
-                for (int qSector = qSectorStart; qSector < qSectorEnd; ++qSector) {
-
-                    Filter filter = new AndFilter()
-                        .add(kmFilter)
-                        .add(new SectorFilter(qSector))
-                        .add(drf)
-                        .add(idsFilter);
-
-                    List<Fixing.Column> metas = overview.filter(range, filter);
-
-                    if (metas.isEmpty()) {
-                        // No fixings for km and analysis period
-                        continue;
-                    }
-
-                    double sumQ = 0.0;
-                    double sumW = 0.0;
-
-                    StandardDeviation stdDev = new StandardDeviation();
-
-                    List<QWD> qwds = new ArrayList<QWD>(metas.size());
-
-                    dateAverager.clear();
+    public CalculationResult calculate() {
+        FixingsOverview overview =
+            FixingsOverviewFactory.getOverview(river);
 
-                    for (Fixing.Column meta: metas) {
-                        if (meta.findQSector(km) != qSector) {
-                            // Ignore not matching sectors.
-                            continue;
-                        }
-
-                        Column column = cc.getColumn(meta);
-                        if (column == null || !column.getQW(km, wq)) {
-                            continue;
-                        }
-
-                        double fw = instance.value(wq[1]);
-                        if (Double.isNaN(fw)) {
-                            continue;
-                        }
-
-                        double dw = (wq[0] - fw)*100.0;
-
-                        stdDev.increment(dw);
-
-                        Date date = column.getDate();
-                        String description = column.getDescription();
-
-                        QWD qwd = new QWD(
-                            wq[1], wq[0], description, date, true, dw);
-
-                        qwds.add(qwd);
-
-                        sumW += wq[0];
-                        sumQ += wq[1];
-
-                        dateAverager.add(date);
-                    }
-
-                    // Calulate average per Q sector.
-                    int N = qwds.size();
-                    if (N > 0) {
-                        allQWDs.addAll(qwds);
-                        double avgW = sumW / N;
-                        double avgQ = sumQ / N;
-
-                        double avgFw = instance.value(avgQ);
-                        if (!Double.isNaN(avgFw)) {
-                            double avgDw = (avgW - avgFw)*100.0;
-                            Date avgDate = dateAverager.getAverage();
-
-                            String avgDescription = "avg.deltawt." + qSector;
-
-                            QWD avgQWD = new QWD(
-                                avgQ, avgW, avgDescription, avgDate, true, avgDw);
-
-                            qSectorAverages[qSector] = avgQWD;
-                        }
-                        qSectorStdDevs[qSector] = stdDev.getResult();
-                    }
-                    else {
-                        qSectorStdDevs[qSector] = Double.NaN;
-                    }
-                } // for all Q sectors
-
-                QWD [] aqwds = allQWDs.toArray(new QWD[allQWDs.size()]);
-
-                AnalysisPeriod periodResult = new AnalysisPeriod(
-                    analysisPeriod,
-                    aqwds,
-                    qSectorAverages,
-                    qSectorStdDevs);
-                periodResults.add(periodResult);
-            }
-
-            double maxQ = -Double.MAX_VALUE;
-            for (AnalysisPeriod ap: periodResults) {
-                double q = ap.getMaxQ();
-                if (q > maxQ) {
-                    maxQ = q;
-                }
-            }
-
-            double oldMaxQ = parameters.get(row, maxQIndex);
-            if (oldMaxQ < maxQ) {
-                parameters.set(row, maxQIndex, maxQ);
-            }
-
-            results.add(km, periodResults.toArray(
-                new AnalysisPeriod[periodResults.size()]));
+        if (overview == null) {
+            addProblem("fix.no.overview.available");
         }
 
-        return results;
-    }
-
-    /** Helper class to bundle the meta information of a column
-     *  and the real data.
-     */
-    protected static class Column {
-
-        protected Fixing.Column meta;
-        protected FixingsColumn data;
-
-        public Column() {
-        }
-
-        public Column(Fixing.Column meta, FixingsColumn data) {
-            this.meta = meta;
-            this.data = data;
-        }
-
-        public Date getDate() {
-            return meta.getStartTime();
-        }
-
-        public String getDescription() {
-            return meta.getDescription();
-        }
+        Function func = FunctionFactory.getInstance()
+            .getFunction(function);
 
-        public boolean getQW(
-            double    km,
-            double [] qs,
-            double [] ws,
-            int       index
-        ) {
-            qs[index] = data.getQ(km);
-            return data.getW(km, ws, index);
-        }
-
-        public boolean getQW(double km, double [] wq) {
-            data.getW(km, wq, 0);
-            if (Double.isNaN(wq[0])) return false;
-            wq[1] = data.getQ(km);
-            return !Double.isNaN(wq[1]);
-        }
-    } // class Column
-
-
-    /**
-     * Helper class to find the data belonging to meta info more quickly.
-     */
-    public static class ColumnCache {
-
-        protected Map<Integer, Column> columns;
-
-        public ColumnCache() {
-            columns = new HashMap<Integer, Column>();
+        if (func == null) {
+            addProblem("fix.invalid.function.name");
         }
 
-        public Column getColumn(Fixing.Column meta) {
-            Integer key = meta.getId();
-            Column column = columns.get(key);
-            if (column == null) {
-                FixingsColumn data = FixingsColumnFactory
-                    .getInstance()
-                    .getColumnData(meta);
-                if (data != null) {
-                    column = new Column(meta, data);
-                    columns.put(key, column);
-                }
-            }
-            return column;
-        }
-    } // class ColumnCache
-
-    /** Fetch meta and data columns for analysis periods. */
-    protected Column [][] getAnalysisColumns(FixingsOverview overview) {
-
-        boolean debug = log.isDebugEnabled();
-        if (debug) {
-            log.debug("number analysis periods: " + analysisPeriods.length);
+        if (hasProblems()) {
+            return new CalculationResult(this);
         }
 
-        Column columns [][] = new Column[analysisPeriods.length][];
-
-        Range range = new Range(from, to);
-        SectorRangeFilter sectorRangeFilter =
-            new SectorRangeFilter(qSectorStart, qSectorEnd);
-
-        FixingsColumnFactory fcf = FixingsColumnFactory.getInstance();
-
-        for (int i = 0; i < columns.length; ++i) {
-
-            // Construct filter for period.
-            DateRange period = analysisPeriods[i];
-
-            AndFilter filter = new AndFilter();
-
-            DateRangeFilter dateRangeFilter =
-                new DateRangeFilter(period.getFrom(), period.getTo());
-
-            filter.add(dateRangeFilter);
-            filter.add(sectorRangeFilter);
-
-            List<Fixing.Column> metaCols = overview.filter(range, filter);
-
-            if (debug) {
-                log.debug("number of filtered columns: " + metaCols.size());
-            }
-
-            ArrayList<Column> cols = new ArrayList<Column>(metaCols.size());
-
-            // Only use columns which have data.
-            for (Fixing.Column meta: metaCols) {
-                FixingsColumn data = fcf.getColumnData(meta);
-                if (data != null) {
-                    cols.add(new Column(meta, data));
-                }
-            }
-
-            if (debug) {
-                log.debug("failed loading: " + (metaCols.size()-cols.size()));
-            }
-            columns[i] = cols.toArray(new Column[cols.size()]);
-        }
-
-        return columns;
+        return innerCalculate(overview, func);
     }
 
-    protected static String [] createColumnNames(String [] parameters) {
-        String [] result = new String[parameters.length + 4];
-        result[0] = "km";
-        result[1] = "chi_sqr";
-        result[2] = "max_q";
-        result[3] = "std-dev";
-        System.arraycopy(parameters, 0, result, 4, parameters.length);
-        return result;
-    }
+    protected abstract CalculationResult innerCalculate(
+        FixingsOverview overview,
+        Function        function
+    );
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixDerivateFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixDerivateFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,7 +5,7 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.math.fitting.Function;
 import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
@@ -68,14 +68,14 @@
         }
 
         FLYSArtifact flys = (FLYSArtifact)artifact;
-        FixationArtifactAccess access = new FixationArtifactAccess(flys);
+        FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
         CalculationResult res =
             (CalculationResult) flys.compute(context,
                                              ComputeType.ADVANCE,
                                              false);
 
-        FixResult result = (FixResult) res.getData();
+        FixAnalysisResult result = (FixAnalysisResult) res.getData();
         double currentKm =
             ((Double)context.getContextValue("currentKm")).doubleValue();
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixDeviationFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixDeviationFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,7 +4,7 @@
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
@@ -28,6 +28,7 @@
     /** House logger. */
     private static Logger logger = Logger.getLogger(FixDeviationFacet.class);
 
+    public static final String [] STD_DEV_COLUMN = { "std-dev" };
 
     /** Trivial Constructor. */
     public FixDeviationFacet() {
@@ -59,23 +60,23 @@
         logger.debug("FixDeviationFacet.getData");
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
+            FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
             double currentKm =
                 ((Double)context.getContextValue("currentKm")).doubleValue();
 
             Parameters params = result.getParameters();
 
             double[] stdDev =
-                params.interpolate("km", currentKm, new String[] {"std-dev"});
+                params.interpolate("km", currentKm, STD_DEV_COLUMN);
 
-            if(stdDev == null) {
+            if (stdDev == null) {
                 logger.warn("getData: stdDev == null at km " + currentKm);
                 return null;
             }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixFacetUtils.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixFacetUtils.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,8 +4,10 @@
 
 public final class FixFacetUtils {
 
+    public static final String [] MAX_Q_COLUMN = { "max_q" };
+
     public static double getMaxQ(Parameters params, double km) {
-        double [] maxQ = params.interpolate("km", km, new String[] { "max_q" });
+        double [] maxQ = params.interpolate("km", km, MAX_Q_COLUMN);
         if (maxQ == null) {
             return 1000d;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAnalysisFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAnalysisFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,22 +1,16 @@
 package de.intevation.flys.artifacts.model.fixings;
 
+import org.apache.log4j.Logger;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
-
 import de.intevation.flys.artifacts.FLYSArtifact;
-
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
-
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
-
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
-
 import de.intevation.flys.utils.KMIndex;
 
-import org.apache.log4j.Logger;
-
 /**
  * Facet to show average W values for Q sectors.
  *
@@ -63,23 +57,35 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
 
             KMIndex<AnalysisPeriod []> kmPeriods = result.getAnalysisPeriods();
-
             if (kmPeriods == null) {
                 logger.warn("No analysis periods found.");
                 return null;
             }
+            int periodNdx = index >> 8;
+            int qwdNdx = index & 255;
+            KMIndex<QWD> resPeriods =
+                    new KMIndex<QWD>();
+            for (KMIndex.Entry<AnalysisPeriod[]> entry: kmPeriods) {
+                AnalysisPeriod ap = entry.getValue()[periodNdx];
+                QWD[] qwds = ap.qwds;
+                for(int i = 0; i < qwds.length; i++) {
+                    if(qwds[i].getIndex() == qwdNdx) {
+                        resPeriods.add(entry.getKm(), qwds[i]);
+                    }
+                }
+            }
 
-            return kmPeriods;
+
+            return resPeriods;
         }
         else {
             logger.warn("Artifact is no instance of FLYSArtifact.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalAvSectorFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,97 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+import de.intevation.flys.utils.KMIndex;
+
+public class FixLongitudinalAvSectorFacet
+extends DataFacet
+implements FacetTypes {
+
+    /** House logger. */
+    private static Logger logger =
+        Logger.getLogger(FixLongitudinalAvSectorFacet.class);
+
+    /** Trivial Constructor. */
+    public FixLongitudinalAvSectorFacet() {
+    }
+
+
+    public FixLongitudinalAvSectorFacet(
+        int ndx,
+        String name,
+        String description)
+    {
+        super(
+            ndx,
+            name,
+            description,
+            ComputeType.ADVANCE,
+            null,
+            null);
+    }
+
+
+    /**
+     * Returns the data this facet requires.
+     *
+     * @param artifact the owner artifact.
+     * @param context  the CallContext.
+     *
+     * @return the data as KMIndex.
+     */
+    @Override
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("FixLongitudinalAvSectorFacet.getData");
+
+        if (artifact instanceof FLYSArtifact) {
+            FLYSArtifact flys = (FLYSArtifact)artifact;
+
+            CalculationResult res =
+                (CalculationResult) flys.compute(context,
+                                                 ComputeType.ADVANCE,
+                                                 false);
+
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
+
+            KMIndex<AnalysisPeriod []> kmPeriods = result.getAnalysisPeriods();
+            if (kmPeriods == null) {
+                logger.warn("No analysis periods found.");
+                return null;
+            }
+            int periodNdx = index >> 2;
+            KMIndex<AnalysisPeriod> resPeriods =
+                    new KMIndex<AnalysisPeriod>();
+            for (KMIndex.Entry<AnalysisPeriod[]> entry: kmPeriods) {
+                AnalysisPeriod ap = entry.getValue()[periodNdx];
+                resPeriods.add(entry.getKm(), ap);
+            }
+
+            return resPeriods;
+        }
+        else {
+            logger.warn("Artifact is no instance of FLYSArtifact.");
+            return null;
+        }
+    }
+
+
+    /**
+     * Create a deep copy of this Facet.
+     * @return a deep copy.
+     */
+    @Override
+    public FixLongitudinalAvSectorFacet deepCopy() {
+        FixLongitudinalAvSectorFacet copy = new FixLongitudinalAvSectorFacet();
+        copy.set(this);
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalDeviationFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalDeviationFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,7 +5,7 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
@@ -64,14 +64,14 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
+            FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
 
             KMIndex<AnalysisPeriod []> kmPeriods = result.getAnalysisPeriods();
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalReferenceFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixLongitudinalReferenceFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,7 +5,7 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
@@ -64,14 +64,14 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
+            FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
                                                  ComputeType.ADVANCE,
                                                  false);
 
-            FixResult result = (FixResult) res.getData();
+            FixAnalysisResult result = (FixAnalysisResult) res.getData();
 
             KMIndex<QWD []> kmReference = result.getReferenced();
 
@@ -80,7 +80,18 @@
                 return null;
             }
 
-            return kmReference;
+            int qwdNdx = index & 255;
+            KMIndex<QWD> resReference =
+                    new KMIndex<QWD>();
+            for (KMIndex.Entry<QWD[]> entry: kmReference) {
+                QWD[] qwds = entry.getValue();
+                for(int i = 0; i < qwds.length; i++) {
+                    if(qwds[i].getIndex() == qwdNdx) {
+                        resReference.add(entry.getKm(), qwds[i]);
+                    }
+                }
+            }
+            return resReference;
         }
         else {
             logger.warn("Artifact is no instance of FLYSArtifact.");
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixOutlierFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixOutlierFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,22 +1,16 @@
 package de.intevation.flys.artifacts.model.fixings;
 
+import org.apache.log4j.Logger;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
-
 import de.intevation.flys.artifacts.FLYSArtifact;
-
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
-
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
-
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
-
 import de.intevation.flys.utils.KMIndex;
 
-import org.apache.log4j.Logger;
-
 /**
  * Facet to show the outliers in a fix calculation.
  *
@@ -49,10 +43,11 @@
     /**
      * Returns the data this facet requires.
      *
-     * @param artifact the owner artifact.
-     * @param context  the CallContext (ignored).
+     * @param artifact the owner artifact; needs to be a FLYSArtifact.
+     * @param context  the CallContext; required to retrieve the value of
+     * <i>currentKm</i>.
      *
-     * @return the data.
+     * @return an array of QW objects or null.
      */
     @Override
     public Object getData(Artifact artifact, CallContext context) {
@@ -60,7 +55,6 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
@@ -71,19 +65,27 @@
             double currentKm =
                 ((Double)context.getContextValue("currentKm")).doubleValue();
 
-            KMIndex<QW []> kmQWs = result.getOutliers();
+            KMIndex<QWI []>       kmQWs    = result.getOutliers();
+            KMIndex.Entry<QWI []> qwsEntry = kmQWs.binarySearch(currentKm);
 
-            KMIndex.Entry<QW []> qwsEntry = kmQWs.binarySearch(currentKm);
-            QW[] qws = null;
-            if(qwsEntry != null) {
+            QWI [] qws = null;
+            if (qwsEntry != null) {
                 qws = qwsEntry.getValue();
+
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Found " + (qws != null ? qws.length : 0)
+                        + " KMIndex.Entry for km " + currentKm);
+                }
             }
+            else {
+                logger.debug("Found no KMIndex.Entry for km " + currentKm);
+            }
+
             return qws;
         }
-        else {
-            logger.debug("Not an instance of FixationArtifact.");
-            return null;
-        }
+
+        logger.warn("Not an instance of FLYSArtifact.");
+        return null;
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,162 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import de.intevation.flys.artifacts.access.FixRealizingAccess;
+
+import de.intevation.flys.artifacts.math.fitting.Function;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.FixingsOverview;
+import de.intevation.flys.artifacts.model.RiverFactory;
+import de.intevation.flys.artifacts.model.Segment;
+import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.artifacts.model.Parameters;
+
+import de.intevation.flys.model.River;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class FixRealizingCalculation
+extends      FixCalculation
+{
+    private static Logger log =
+        Logger.getLogger(FixRealizingCalculation.class);
+
+    protected boolean       isQ;
+    protected List<Segment> segments;
+
+    public FixRealizingCalculation() {
+    }
+
+    public FixRealizingCalculation(FixRealizingAccess access) {
+        super(access);
+
+        Boolean       isQ      = access.isQ();
+        List<Segment> segments = access.getSegments();
+
+        if (isQ == null) {
+            // TODO: i18n
+            addProblem("fix.realize.missing.is.q");
+        }
+
+        if (segments == null || segments.isEmpty()) {
+            // TODO: i18n
+            addProblem("fix.realize.missing.segments");
+        }
+
+        River r = RiverFactory.getRiver(river);
+
+        if (r == null) {
+            // TODO: i18n
+            addProblem("fix.no.such.river");
+        }
+
+        if (!hasProblems()) {
+            this.isQ      = isQ;
+            this.segments = segments;
+
+            // Convert from W to Q
+            Segment.setReferencePointConvertQ(segments, r, isQ, this);
+        }
+    }
+
+    @Override
+    protected CalculationResult innerCalculate(
+        FixingsOverview overview,
+        Function        func
+    ) {
+        ColumnCache cc = new ColumnCache();
+        FitResult fitResult = doFitting(overview, cc, func);
+
+        if (fitResult == null) {
+            return new CalculationResult(this);
+        }
+
+        Segment segment = segments.get(0);
+        int numResults = segment.numValues();
+
+        WQKms [] results = new WQKms[numResults];
+        for (int i = 0; i < results.length; ++i) {
+            results[i] = new WQKms();
+        }
+
+        Parameters parameters = fitResult.getParameters();
+
+        int kmIndex = parameters.columnIndex("km");
+        int [] parameterIndices =
+            parameters.columnIndices(func.getParameterNames());
+
+        double [] parameterValues = new double[parameterIndices.length];
+
+        for (int row = 0, R = parameters.size(); row < R; ++row) {
+            double km = parameters.get(row, kmIndex);
+
+            if (!segment.inside(km)) {
+                Segment nextSeg = null;
+                for (Segment seg: segments) {
+                    if (seg.inside(km)) {
+                        nextSeg = seg;
+                        break;
+                    }
+                }
+                if (nextSeg == null) {
+                    // TODO: i18n
+                    addProblem(km, "fix.cannot.find.segment");
+                    continue;
+                }
+                segment = nextSeg;
+            }
+
+            parameters.get(row, parameterIndices, parameterValues);
+
+            de.intevation.flys.artifacts.math.Function instance =
+                func.instantiate(parameterValues);
+
+            double [] values = segment.getValues();
+            for (int i = 0; i < numResults; ++i) {
+                double q = values[i];
+                double w = instance.value(q);
+
+                if (Double.isNaN(w)) {
+                    // TODO: i18n
+                    addProblem(km, "fix.cannot.calculate.function", q);
+                }
+                else {
+                    results[i].add(w, q, km);
+                }
+            }
+        }
+
+        // name the curves
+        for (int i = 0; i < results.length; ++i) {
+            results[i].setName(createName(i));
+        }
+
+        FixRealizingResult frr = new FixRealizingResult(
+            parameters,
+            fitResult.getReferenced(),
+            fitResult.getOutliers(),
+            results);
+
+        return new CalculationResult(frr, this);
+    }
+
+    protected String createName(int index) {
+        // TODO: i18n
+        StringBuilder sb = new StringBuilder(isQ ? "Q" : "W");
+        sb.append(" benutzerdefiniert (");
+        for (int i = 0, N = segments.size(); i < N; ++i) {
+            if (i > 0) {
+                sb.append("; ");
+            }
+            Segment segment = segments.get(i);
+            double [] backup = segment.getBackup();
+            double [] values = segment.getValues();
+            sb.append((backup != null ? backup : values)[index]);
+        }
+        sb.append(')');
+        return sb.toString();
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixRealizingResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,35 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import de.intevation.flys.artifacts.model.WQKms;
+
+import de.intevation.flys.artifacts.model.Parameters;
+
+import de.intevation.flys.utils.KMIndex;
+
+public class FixRealizingResult
+extends      FixResult
+{
+    public WQKms [] wqkms;
+
+    public FixRealizingResult() {
+    }
+
+    public FixRealizingResult(
+        Parameters      parameters,
+        KMIndex<QWD []> referenced,
+        KMIndex<QWI []> outliers,
+        WQKms []        wqkms
+    ) {
+        super(parameters, referenced, outliers);
+        this.wqkms = wqkms;
+    }
+
+    public WQKms [] getWQKms() {
+        return wqkms;
+    }
+
+    public void setWQKms(WQKms [] wqkms) {
+        this.wqkms = wqkms;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixReferenceEventsFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixReferenceEventsFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,22 +1,16 @@
 package de.intevation.flys.artifacts.model.fixings;
 
+import org.apache.log4j.Logger;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
-
 import de.intevation.flys.artifacts.FLYSArtifact;
-
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
-
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
-
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
-
 import de.intevation.flys.utils.KMIndex;
 
-import org.apache.log4j.Logger;
-
 
 /**
  * Facet to show W values for Q values at km for a date.
@@ -62,7 +56,6 @@
 
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
@@ -77,9 +70,16 @@
             KMIndex.Entry<QWD []> kmQWsEntry = kmQWs.binarySearch(currentKm);
             QWD[] qwds = null;
             if (kmQWsEntry != null) {
+                int ndx = index & 255;
                 qwds = kmQWsEntry.getValue();
+                for (int i = 0; i < qwds.length; i++) {
+                    if (qwds[i].getIndex() == ndx) {
+                        return qwds[i];
+                    }
+                }
+                return null;
             }
-            return qwds;
+            return null;
         }
         else {
             logger.debug("Not an instance of FixationArtifact.");
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixResult.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -9,55 +9,21 @@
 public class FixResult
 implements   Serializable
 {
-    protected Parameters                 parameters;
-    protected KMIndex<QWD []>            referenced;
-    protected KMIndex<QW []>             outliers;
-    protected KMIndex<AnalysisPeriod []> analysisPeriods;
+    protected Parameters      parameters;
+    protected KMIndex<QWD []> referenced;
+    protected KMIndex<QWI []> outliers;
 
     public FixResult() {
     }
 
     public FixResult(
-        Parameters                 parameters,
-        KMIndex<QWD []>            referenced,
-        KMIndex<QW []>             outliers,
-        KMIndex<AnalysisPeriod []> analysisPeriods
+        Parameters      parameters,
+        KMIndex<QWD []> referenced,
+        KMIndex<QWI []> outliers
     ) {
-        this.parameters      = parameters;
-        this.referenced      = referenced;
-        this.outliers        = outliers;
-        this.analysisPeriods = analysisPeriods;
-    }
-
-    public int getUsedSectorsInAnalysisPeriods() {
-        int result = 0;
-        for (KMIndex.Entry<AnalysisPeriod []> entry: analysisPeriods) {
-            for (AnalysisPeriod period: entry.getValue()) {
-                for (int i = 0; i < 4; ++i) {
-                    result |= period.getQSectorAverage(i) != null
-                        ? (1 << i)
-                        : 0;
-                }
-                // XXX: Stop early on result == ~(~0 << 4)) ?
-            }
-        }
-        return result;
-    }
-
-    public Parameters getParameters() {
-        return parameters;
-    }
-
-    public void setParameters(Parameters parameters) {
         this.parameters = parameters;
-    }
-
-    public KMIndex<AnalysisPeriod []> getAnalysisPeriods() {
-        return analysisPeriods;
-    }
-
-    public void setAnalysisPeriods(KMIndex<AnalysisPeriod []> analysisPeriods) {
-        this.analysisPeriods = analysisPeriods;
+        this.referenced = referenced;
+        this.outliers   = outliers;
     }
 
     public KMIndex<QWD []> getReferenced() {
@@ -68,12 +34,20 @@
         this.referenced = referenced;
     }
 
-    public KMIndex<QW []> getOutliers() {
+    public KMIndex<QWI []> getOutliers() {
         return outliers;
     }
 
-    public void setOutliers(KMIndex<QW []> outliers) {
+    public void setOutliers(KMIndex<QWI []> outliers) {
         this.outliers = outliers;
     }
+
+    public Parameters getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(Parameters parameters) {
+        this.parameters = parameters;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixWQCurveFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixWQCurveFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,7 +5,7 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 
 import de.intevation.flys.artifacts.math.fitting.Function;
 import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
@@ -61,7 +61,7 @@
         logger.debug("FixWQCurveFacet.getData");
         if (artifact instanceof FLYSArtifact) {
             FLYSArtifact flys = (FLYSArtifact)artifact;
-            FixationArtifactAccess access = new FixationArtifactAccess(flys);
+            FixAnalysisAccess access = new FixAnalysisAccess(flys);
 
             CalculationResult res =
                 (CalculationResult) flys.compute(context,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixWaterlevelFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,49 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.artifacts.model.WaterlevelFacet;
+
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+public class FixWaterlevelFacet
+extends      WaterlevelFacet
+{
+    public FixWaterlevelFacet() {
+    }
+
+    public FixWaterlevelFacet(int index, String name, String description) {
+        super(index, name, description, ComputeType.ADVANCE, null, null);
+    }
+
+    public FixWaterlevelFacet(
+        int         index,
+        String      name,
+        String      description,
+        ComputeType type,
+        String      stateID,
+        String      hash
+    ) {
+        super(index, name, description, type, hash, stateID);
+    }
+
+    @Override
+    protected WQKms [] getWQKms(CalculationResult res) {
+        FixRealizingResult fr = (FixRealizingResult)res.getData();
+        return fr != null ? fr.getWQKms() : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        FixWaterlevelFacet copy = new FixWaterlevelFacet();
+        copy.set(this);
+        copy.type    = type;
+        copy.hash    = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QW.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-package de.intevation.flys.artifacts.model.fixings;
-
-import java.util.Date;
-
-import java.io.Serializable;
-
-public class QW
-implements   Serializable
-{
-    protected double  q;
-    protected double  w;
-    protected String  description;
-    protected Date    date;
-    protected boolean interpolated;
-
-    public QW() {
-    }
-
-    public QW(double q, double w) {
-        this.q = q;
-        this.w = w;
-    }
-
-    public QW(
-        double  q,
-        double  w,
-        String  description,
-        Date    date,
-        boolean interpolated
-    ) {
-        this(q, w);
-        this.description  = description;
-        this.date         = date;
-        this.interpolated = interpolated;
-    }
-
-    public double getQ() {
-        return q;
-    }
-
-    public void setQ(double q) {
-        this.q = q;
-    }
-
-    public double getW() {
-        return w;
-    }
-
-    public void setW(double w) {
-        this.w = w;
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public void setDate(Date date) {
-        this.date = date;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public boolean getInterpolated() {
-        return interpolated;
-    }
-
-    public void setInterpolated(boolean interpolated) {
-        this.interpolated = interpolated;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,7 +3,7 @@
 import java.util.Date;
 
 public class QWD
-extends      QW
+extends      QWI
 {
     protected double deltaW;
 
@@ -20,9 +20,10 @@
         String  description,
         Date    date,
         boolean interpolated,
-        double  deltaW
+        double  deltaW,
+        int     index
     ) {
-        super(q, w, description, date, interpolated);
+        super(q, w, description, date, interpolated, index);
         this.deltaW = deltaW;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWI.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,69 @@
+package de.intevation.flys.artifacts.model.fixings;
+
+import de.intevation.flys.artifacts.model.QW;
+
+import java.util.Date;
+
+public class QWI
+extends      QW
+{
+    protected String  description;
+    protected Date    date;
+    protected boolean interpolated;
+    protected int     index;
+
+    public QWI() {
+    }
+
+    public QWI(double q, double w) {
+        super(q, w);
+    }
+
+    public QWI(
+        double  q,
+        double  w,
+        String  description,
+        Date    date,
+        boolean interpolated,
+        int     index
+    ) {
+        super(q, w);
+        this.description  = description;
+        this.date         = date;
+        this.interpolated = interpolated;
+        this.index        = index;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public boolean getInterpolated() {
+        return interpolated;
+    }
+
+    public void setInterpolated(boolean interpolated) {
+        this.interpolated = interpolated;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/map/WMSLayerFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/map/WMSLayerFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -29,6 +29,7 @@
     protected String       hash;
     protected String       url;
     protected Envelope     extent;
+    protected Envelope     originalExtent;
     protected String       srid;
 
 
@@ -108,6 +109,16 @@
     }
 
 
+    public void setOriginalExtent(Envelope originalExtent) {
+        this.originalExtent = originalExtent;
+    }
+
+
+    public Envelope getOriginalExtent() {
+        return originalExtent;
+    }
+
+
     public void setSrid(String srid) {
         if (srid != null) {
             this.srid = srid;
@@ -140,8 +151,8 @@
         ec.addAttr(facet, "url", url, true);
         ec.addAttr(facet, "layers", layers.get(0), true);
         ec.addAttr(facet, "srid", srid != null ? srid : "", true);
-        ec.addAttr(facet, "extent", extent != null
-            ? GeometryUtils.jtsBoundsToOLBounds(extent)
+        ec.addAttr(facet, "extent", originalExtent != null
+            ? GeometryUtils.jtsBoundsToOLBounds(originalExtent)
             : "", true);
         ec.addAttr(facet, "queryable", String.valueOf(isQueryable()), true);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDensityFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,60 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+/**
+ * Facet for serving bed density data.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class BedDensityFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger logger = Logger.getLogger(BedDensityFacet.class);
+
+    public BedDensityFacet() {
+    }
+
+    public BedDensityFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed density at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        int ndx = index >> 8;
+        Object[] data =
+            ((BedQualityResult[]) res.getData())[ndx].getParameters(); // TODO CAST TO SPECIFIC CLASS
+
+        int ndy = index & 255;
+        return data != null && data.length > ndy ? data[ndy] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedDensityFacet copy = new BedDensityFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,59 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+/**
+ * Facet for serving bed diameter data.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class BedDiameterFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger logger = Logger.getLogger(BedDiameterFacet.class);
+
+    public BedDiameterFacet() {
+    }
+
+    public BedDiameterFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed diameter at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        int ndx = index >> 8;
+        Object[] data = ((BedQualityResult[]) res.getData())[ndx].getBedResults(); // TODO CAST TO SPECIFIC CLASS
+
+        int ndy = index & 255;
+        return data != null && data.length > ndy ? data[ndy] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedDiameterFacet copy = new BedDiameterFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiameterResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,64 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+
+public class BedDiameterResult
+extends BedQualityDiameterResult
+{
+    protected TDoubleArrayList diameterCap;
+    protected TDoubleArrayList diameterSub;
+
+    public BedDiameterResult (
+        String type,
+        TDoubleArrayList diameterCap,
+        TDoubleArrayList diameterSub,
+        TDoubleArrayList km
+    ) {
+        super(type, km);
+        this.diameterCap = diameterCap;
+        this.diameterSub = diameterSub;
+    }
+
+    public double getDiameterCap(int ndx) {
+        if (diameterCap != null) {
+            return this.diameterCap.get(ndx);
+        }
+        return Double.NaN;
+    }
+
+    public double getDiameterSub(int ndx) {
+        if (diameterSub != null) {
+            return this.diameterSub.get(ndx);
+        }
+        return Double.NaN;
+    }
+
+    public double getDiameterCap(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return diameterCap.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double getDiameterSub(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return diameterSub.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double[][] getDiameterCapData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            diameterCap.toNativeArray()
+        };
+    }
+
+    public double[][] getDiameterSubData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            diameterSub.toNativeArray()
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,187 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.BedDifferencesAccess;
+import de.intevation.flys.artifacts.model.Calculation;
+import de.intevation.flys.artifacts.model.CalculationResult;
+
+
+public class BedDiffCalculation
+extends Calculation
+{
+
+    private static final Logger logger = Logger
+        .getLogger(BedDiffCalculation.class);
+
+    protected String river;
+    protected String yearEpoch;
+    protected FLYSArtifact[][] artifacts;
+
+    public BedDiffCalculation() {
+    }
+
+    public CalculationResult calculate(BedDifferencesAccess access) {
+        logger.info("BedDiffCalculation.calculate");
+
+        String river = access.getRiver();
+        String yearEpoch = access.getYearEpoch();
+        FLYSArtifact[][] artifacts = access.getDifferenceArtifacts();
+
+        logger.debug("got artifacts: " + artifacts.length + "; " + artifacts[0].length);
+        if (river == null) {
+            // TODO: i18n
+            addProblem("minfo.missing.river");
+        }
+
+        if (yearEpoch == null) {
+            addProblem("minfo.missing.year_epoch");
+        }
+
+        if (artifacts == null) {
+            addProblem("minfo.missing.differences");
+        }
+
+        if (!hasProblems()) {
+            this.river = river;
+            this.yearEpoch = yearEpoch;
+            this.artifacts = artifacts;
+            return internalCalculate();
+        }
+
+        return new CalculationResult();
+    }
+
+    private CalculationResult internalCalculate() {
+
+        if (yearEpoch.equals("year")) {
+            List<BedDiffYearResult> results =
+                new LinkedList<BedDiffYearResult>();
+
+            for (int i = 0; i < artifacts.length; i++) {
+                BedHeight[] pair =
+                    getHeightPair(artifacts[i][0], artifacts[i][1], "single");
+                BedDiffYearResult res = calculateYearDifference(pair);
+                results.add(res);
+            }
+            return new CalculationResult(
+                results.toArray(new BedDiffYearResult[results.size()]), this);
+        }
+        if (yearEpoch.equals("epoch")) {
+            List<BedDiffEpochResult> results =
+                new LinkedList<BedDiffEpochResult>();
+            for (int i = 0; i < artifacts.length; i++) {
+                BedHeight[] pair =
+                    getHeightPair(artifacts[i][0], artifacts[i][1], "epoch");
+                BedDiffEpochResult res = calculateEpochDifference(pair);
+                results.add(res);
+            }
+            return new CalculationResult(
+                results.toArray(new BedDiffEpochResult[results.size()]), this);
+        }
+
+       return new CalculationResult();
+    }
+
+    private BedHeight[] getHeightPair(
+        FLYSArtifact art1,
+        FLYSArtifact art2,
+        String type
+    ) {
+        int id1 = BedDifferencesAccess.getHeightId(art1);
+        int id2 = BedDifferencesAccess.getHeightId(art2);
+
+        BedHeight[] heights = new BedHeight[2];
+        heights[0] = BedHeightFactory.getHeight(type, id1, 0);
+        heights[1] = BedHeightFactory.getHeight(type, id2, 0);
+        return heights;
+    }
+
+    private BedDiffEpochResult calculateEpochDifference(BedHeight[] pair) {
+
+        TDoubleArrayList stations = pair[0].getStations();
+        TDoubleArrayList diffRes = new TDoubleArrayList();
+        TDoubleArrayList kms = new TDoubleArrayList();
+        TDoubleArrayList heights1 = new TDoubleArrayList();
+        TDoubleArrayList heights2 = new TDoubleArrayList();
+
+        for (int i = 0; i < stations.size(); i++) {
+            if (!Double.isNaN(pair[0].getHeight(stations.get(i))) &&
+                !Double.isNaN(pair[1].getHeight(stations.get(i)))) {
+                double hDiff =
+                    pair[0].getHeight(stations.get(i)) -
+                    pair[1].getHeight(stations.get(i));
+                diffRes.add(hDiff);
+                kms.add(stations.get(i));
+                heights1.add(pair[0].getHeight(stations.get(i)));
+                heights2.add(pair[1].getHeight(stations.get(i)));
+            }
+        }
+        Date start = ((BedHeightEpoch)pair[0]).getStart();
+        Date end = ((BedHeightEpoch)pair[1]).getEnd();
+        return new BedDiffEpochResult(kms, diffRes, heights1, heights2, start, end);
+    }
+
+    private BedDiffYearResult calculateYearDifference(BedHeight[] pair) {
+
+        TDoubleArrayList stations = pair[0].getStations();
+        TDoubleArrayList diffRes = new TDoubleArrayList();
+        TDoubleArrayList kms = new TDoubleArrayList();
+        TDoubleArrayList morphs = new TDoubleArrayList();
+        TDoubleArrayList absolute = new TDoubleArrayList();
+        TDoubleArrayList gap = new TDoubleArrayList();
+        TDoubleArrayList heights1 = new TDoubleArrayList();
+        TDoubleArrayList heights2 = new TDoubleArrayList();
+
+        BedHeightSingle s1 = (BedHeightSingle)pair[0];
+        BedHeightSingle s2 = (BedHeightSingle)pair[1];
+        int range = s1.getYear() - s2.getYear();
+        if (range  < 0) {
+            range = range * -1;
+        }
+        for (int i = 0; i < stations.size(); i++) {
+            if (!Double.isNaN(s1.getHeight(stations.get(i))) &&
+                !Double.isNaN(s2.getHeight(stations.get(i)))) {
+                double hDiff =
+                    s1.getHeight(stations.get(i)) -
+                    s2.getHeight(stations.get(i));
+                diffRes.add(hDiff);
+                double km = stations.get(i);
+                kms.add(km);
+                if (s1.getMorphWidth(km) >
+                    s2.getMorphWidth(km)) {
+                    morphs.add(s1.getMorphWidth(km));
+                }
+                else {
+                    morphs.add(s2.getMorphWidth(km));
+                }
+                if (s1.getDataGap(km) > s2.getDataGap(km)) {
+                    gap.add(s1.getDataGap(km));
+                }
+                else {
+                    gap.add(s2.getDataGap(km));
+                }
+                absolute.add((hDiff / range) * 100);
+                heights1.add(s1.getHeight(km));
+                heights2.add(s2.getHeight(km));
+            }
+        }
+        return new BedDiffYearResult(
+            kms,
+            diffRes,
+            heights1,
+            heights2,
+            morphs,
+            absolute,
+            gap,
+            s1.getYear(),
+            s2.getYear());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,52 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+public class BedDiffEpochFacet
+extends DataFacet
+{
+    private static Logger logger = Logger.getLogger(BedDensityFacet.class);
+
+    public BedDiffEpochFacet() {
+    }
+
+    public BedDiffEpochFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed density at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        Object[] data =
+            (BedDiffEpochResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS
+
+        return data != null && data.length > index ? data[index] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedDiffEpochFacet copy = new BedDiffEpochFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,39 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.Date;
+
+import gnu.trove.TDoubleArrayList;
+
+
+public class BedDiffEpochResult
+extends BedDifferencesResult
+{
+
+    protected Date start;
+    protected Date end;
+
+    public BedDiffEpochResult () {
+        super();
+    }
+
+    public BedDiffEpochResult (
+        TDoubleArrayList kms,
+        TDoubleArrayList differences,
+        TDoubleArrayList heights1,
+        TDoubleArrayList heights2,
+        Date start,
+        Date end
+    ) {
+        super(kms, differences, heights1, heights2);
+        this.start = start;
+        this.end = end;
+    }
+
+    public Date getStart() {
+        return this.start;
+    }
+
+    public Date getEnd() {
+        return this.end;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,52 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+public class BedDiffYearFacet
+extends DataFacet
+{
+    private static Logger logger = Logger.getLogger(BedDiffYearFacet.class);
+
+    public BedDiffYearFacet() {
+    }
+
+    public BedDiffYearFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed density at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        Object[] data =
+            (BedDiffYearResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS
+
+        return data != null && data.length > index ? data[index] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedDiffYearFacet copy = new BedDiffYearFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,77 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+
+public class BedDiffYearResult
+extends BedDifferencesResult
+{
+
+    protected TDoubleArrayList bedHeights;
+    protected TDoubleArrayList dataGap;
+    protected TDoubleArrayList morphWidth;
+    protected int start;
+    protected int end;
+
+    public BedDiffYearResult () {
+        super();
+        this.bedHeights = new TDoubleArrayList();
+        this.dataGap = new TDoubleArrayList();
+        this.morphWidth = new TDoubleArrayList();
+        this.start = -1;
+        this.end = -1;
+    }
+
+    public BedDiffYearResult(
+        TDoubleArrayList kms,
+        TDoubleArrayList differences,
+        TDoubleArrayList heights1,
+        TDoubleArrayList heights2,
+        TDoubleArrayList morphWidth,
+        TDoubleArrayList bedHeights,
+        TDoubleArrayList dataGap,
+        int start,
+        int end
+    ) {
+        super(kms, differences, heights1, heights2);
+        this.bedHeights = bedHeights;
+        this.dataGap = dataGap;
+        this.morphWidth = morphWidth;
+        this.start = start;
+        this.end = end;
+    }
+
+    public TDoubleArrayList getBedHeights() {
+        return this.bedHeights;
+    }
+
+    public TDoubleArrayList getDataGap() {
+        return this.dataGap;
+    }
+
+    public TDoubleArrayList getMorphWidth() {
+        return this.morphWidth;
+    }
+
+    public int getStart() {
+        return this.start;
+    }
+
+    public int getEnd() {
+        return this.end;
+    }
+
+    public double[][] getMorphWidthData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            morphWidth.toNativeArray()
+        };
+    }
+
+    public double[][] getHeightPerYearData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            bedHeights.toNativeArray()
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,71 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.io.Serializable;
+
+
+public class BedDifferencesResult
+implements Serializable
+{
+
+    protected TDoubleArrayList kms;
+    protected TDoubleArrayList differences;
+    protected TDoubleArrayList height1;
+    protected TDoubleArrayList height2;
+
+    public BedDifferencesResult () {
+        kms = new TDoubleArrayList();
+        differences = new TDoubleArrayList();
+
+    }
+
+    public BedDifferencesResult(
+        TDoubleArrayList kms,
+        TDoubleArrayList differences,
+        TDoubleArrayList heights1,
+        TDoubleArrayList heights2
+    ) {
+        this.kms = kms;
+        this.differences = differences;
+        this.height1 = heights1;
+        this.height2 = heights2;
+    }
+
+    public TDoubleArrayList getKms() {
+        return this.kms;
+    }
+
+    public TDoubleArrayList getDifferences() {
+        return this.differences;
+    }
+
+    public double[][] getDifferencesData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            differences.toNativeArray()
+        };
+    }
+
+    public TDoubleArrayList getHeights1() {
+        return this.height1;
+    }
+
+    public TDoubleArrayList getHeights2() {
+        return this.height2;
+    }
+
+    public double[][] getHeights1Data() {
+        return new double[][] {
+            kms.toNativeArray(),
+            height1.toNativeArray()
+        };
+    }
+
+    public double[][] getHeights2Data() {
+        return new double[][] {
+            kms.toNativeArray(),
+            height2.toNativeArray()
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeight.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,109 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import gnu.trove.TDoubleArrayList;
+import de.intevation.flys.artifacts.model.NamedObjectImpl;
+
+public class BedHeight
+extends NamedObjectImpl
+{
+    private static Logger log = Logger.getLogger(BedHeight.class);
+
+    protected TDoubleArrayList heights;
+    protected TDoubleArrayList station;
+
+    public BedHeight() {
+        heights = new TDoubleArrayList();
+        station = new TDoubleArrayList();
+    }
+
+    public BedHeight(String name) {
+        super(name);
+        heights = new TDoubleArrayList();
+        station = new TDoubleArrayList();
+    }
+
+    public BedHeight(int capacity) {
+        this(capacity, "");
+    }
+
+    public BedHeight(int capacity, String name) {
+        super(name);
+        heights = new TDoubleArrayList(capacity);
+        station = new TDoubleArrayList(capacity);
+    }
+
+    public void add(double value, double station) {
+        this.heights.add(value);
+        this.station.add(station);
+    }
+
+    public int size() {
+        return heights.size();
+    }
+
+    public double getHeight(int idx) {
+        return heights.getQuick(idx);
+    }
+
+    public double [] getHeights() {
+        return heights.toNativeArray();
+    }
+
+    public double [] get(int idx) {
+        return get(idx, new double [3]);
+    }
+
+    public double [] get(int idx, double [] dst) {
+        dst[0] = heights.getQuick(idx);
+        dst[1] = station.getQuick(idx);
+        return dst;
+    }
+
+   public double minHeights() {
+        return heights.min();
+    }
+
+    public TDoubleArrayList getStations() {
+        return this.station;
+    }
+
+    public double getHeight(double station) {
+        if (this.station.indexOf(station) >= 0) {
+            return this.heights.get(this.station.indexOf(station));
+        }
+        return Double.NaN;
+    }
+
+
+    public static void removeNaNs(TDoubleArrayList [] arrays) {
+
+        int dest = 0;
+
+        int A = arrays.length;
+        int N = arrays[0].size();
+
+        OUTER: for (int i = 0; i < N; ++i) {
+            for (int j = 0; j < A; ++j) {
+                TDoubleArrayList a = arrays[j];
+                double v = a.getQuick(i);
+                if (Double.isNaN(v)) {
+                    continue OUTER;
+                }
+                a.setQuick(dest, v);
+            }
+            ++dest;
+        }
+
+        if (dest < N) {
+            for (int i = 0; i < A; ++i) {
+                arrays[i].remove(dest, N-dest);
+            }
+        }
+    }
+
+    public void removeNaNs() {
+        removeNaNs(new TDoubleArrayList [] { heights });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightEpoch.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,42 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.Date;
+
+
+public class BedHeightEpoch
+extends BedHeight
+{
+
+    protected Date start;
+    protected Date end;
+
+    public BedHeightEpoch() {
+        this.start = new Date();
+        this.end = new Date();
+    }
+
+    public BedHeightEpoch(String name) {
+        super(name);
+        this.start = new Date();
+        this.end = new Date();
+    }
+
+    public void add(
+        double value,
+        double station,
+        Date start,
+        Date end
+    ) {
+        super.add(value, station);
+        this.start = start;
+        this.end = end;
+    }
+
+    public Date getStart() {
+        return start;
+    }
+
+    public Date getEnd() {
+        return end;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,48 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.BedHeightsArtifact;
+import de.intevation.flys.artifacts.model.BlackboardDataFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+
+public class BedHeightFacet
+extends      BlackboardDataFacet
+implements   FacetTypes {
+
+    public BedHeightFacet(String description) {
+        this(STATIC_BEDHEIGHT, description);
+    }
+
+    public BedHeightFacet(String name, String description) {
+        this.name = name;
+        this.description = description;
+        this.index = 0;
+    }
+
+    /**
+     * Returns the data this facet requires.
+     *
+     * @param artifact the owner artifact.
+     * @param context  the CallContext (ignored).
+     *
+     * @return the data.
+     */
+    @Override
+    public Object getData(Artifact artifact, CallContext context) {
+        BedHeightsArtifact staticData =
+            (BedHeightsArtifact) artifact;
+        return staticData.getHeight();
+    }
+    /**
+     * Create a deep copy of this Facet.
+     * @return a deep copy.
+     */
+    @Override
+    public BedHeightFacet deepCopy() {
+        BedHeightFacet copy = new BedHeightFacet(description);
+        copy.set(this);
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,179 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+
+import java.util.Date;
+import java.util.List;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.type.StandardBasicTypes;
+
+import de.intevation.flys.artifacts.cache.CacheFactory;
+import de.intevation.flys.artifacts.model.StaticBedHeightCacheKey;
+import de.intevation.flys.backend.SessionHolder;
+
+public class BedHeightFactory {
+    /** Private logger to use here. */
+    private static Logger log = Logger.getLogger(BedHeightFactory.class);
+
+    /** Query to get km and ws for wst_id and column_pos. */
+    public static final String SQL_SELECT_SINGLE =
+        "SELECT bhsv.height, bhsv.station, bhsv.data_gap, bhsv.sounding_width, bhs.year " +
+        "   FROM bed_height_single bhs" +
+        "       JOIN bed_height_single_values bhsv on bhsv.bed_height_single_id = bhs.id" +
+        "   WHERE bhs.id = :height_id";
+
+    /** Query to get name for wst_id and column_pos. */
+    public static final String SQL_SELECT_EPOCH =
+        "SELECT bv.height, bv.station, ti.start_time, ti.stop_time" +
+        "   FROM bed_height_epoch b" +
+        "       JOIN bed_height_epoch_values bv ON b.id = bv.bed_height_epoch_id" +
+        "       JOIN time_intervals ti ON b.time_interval_id = ti.id" +
+        "   WHERE b.id = :height_id";
+
+    /** Query to get name (description) for wst_id. */
+    public static final String SQL_SELECT_DESCR_SINGLE =
+        "SELECT description FROM bed_height_single "+
+        "WHERE id = :height_id";
+
+    /** Query to get name (description) for wst_id. */
+    public static final String SQL_SELECT_DESCR_EPOCH =
+        "SELECT description from bed_height_epoch "+
+        "WHERE id = :height_id";
+
+
+    private BedHeightFactory() {
+    }
+
+
+    /**
+     * Get WKms for given column and wst_id, caring about the cache.
+     */
+    public static BedHeight getHeight(String type, int height_id, int time) {
+        log.debug("BedHeightFactory.getHeight");
+        Cache cache = CacheFactory.getCache(StaticBedHeightCacheKey.CACHE_NAME);
+
+        StaticBedHeightCacheKey cacheKey;
+
+        if (cache != null) {
+            cacheKey = new StaticBedHeightCacheKey(height_id, time);
+            Element element = cache.get(cacheKey);
+            if (element != null) {
+                log.debug("Got static bedheight values from cache");
+                return (BedHeight)element.getValue();
+            }
+        }
+        else {
+            cacheKey = null;
+        }
+
+        BedHeight values = getBedHeightUncached(type, height_id, time);
+
+        if (values != null && cacheKey != null) {
+            log.debug("Store static bed height values in cache.");
+            Element element = new Element(cacheKey, values);
+            cache.put(element);
+        }
+        return values;
+    }
+
+    /** Get name for a WKms. */
+    public static String getHeightName(String type, int height_id) {
+        log.debug("BedHeightFactory.getHeightName height_id/" + height_id);
+
+        String name = null;
+        Session session = SessionHolder.HOLDER.get();
+
+        SQLQuery nameQuery = null;
+        if (type.equals("single")) {
+            nameQuery = session.createSQLQuery(SQL_SELECT_DESCR_SINGLE)
+                .addScalar("description", StandardBasicTypes.STRING);
+            nameQuery.setInteger("height_id", height_id);
+        }
+        else if (type.equals("epoch")) {
+            nameQuery = session.createSQLQuery(SQL_SELECT_DESCR_EPOCH)
+                .addScalar("description", StandardBasicTypes.STRING);
+            nameQuery.setInteger("height_id", height_id);
+        }
+        else {
+            return "none";
+        }
+        List<String> names = nameQuery.list();
+        if (names.size() >= 1) {
+            name = names.get(0);
+        }
+
+        return name;
+    }
+
+
+    /**
+     * Get WKms from db.
+     * @param column the position columns value
+     * @param wst_id database id of the wst
+     * @return according WKms.
+     */
+    public static BedHeight getBedHeightUncached(
+        String type,
+        int height_id,
+        int time)
+    {
+        if (log.isDebugEnabled()) {
+            log.debug("BedHeightFactory.getBedHeightUncached");
+        }
+
+        Session session = SessionHolder.HOLDER.get();
+        SQLQuery sqlQuery = null;
+        if (type.equals("single")) {
+            BedHeightSingle height =
+                new BedHeightSingle(getHeightName(type, height_id));
+            sqlQuery = session.createSQLQuery(SQL_SELECT_SINGLE)
+                .addScalar("height", StandardBasicTypes.DOUBLE)
+                .addScalar("station", StandardBasicTypes.DOUBLE)
+                .addScalar("data_gap", StandardBasicTypes.DOUBLE)
+                .addScalar("sounding_width", StandardBasicTypes.DOUBLE)
+                .addScalar("year", StandardBasicTypes.INTEGER);
+            sqlQuery.setInteger("height_id", height_id);
+            List<Object []> results = sqlQuery.list();
+
+            for (int i = 0; i < results.size(); i++) {
+                Object[] row = results.get(i);
+                log.debug("got station: " + (Double)row[1]);
+                height.add(
+                    (Double) row[0],
+                    (Double) row[1],
+                    (Double) row[2],
+                    (Double) row[3],
+                    (Integer) row[4]);
+            }
+            return height;
+        }
+        else if (type.equals("epoch")) {
+            BedHeightEpoch height =
+                new BedHeightEpoch(getHeightName(type, height_id));
+            sqlQuery = session.createSQLQuery(SQL_SELECT_EPOCH)
+                .addScalar("height", StandardBasicTypes.DOUBLE)
+                .addScalar("station", StandardBasicTypes.DOUBLE)
+                .addScalar("start_time", StandardBasicTypes.DATE)
+                .addScalar("stop_time", StandardBasicTypes.DATE);
+            sqlQuery.setInteger("height_id", height_id);
+            List<Object []> results = sqlQuery.list();
+
+            for (int i = 0; i < results.size(); i++) {
+                Object[] row = results.get(i);
+                height.add(
+                    (Double) row[0],
+                    (Double) row[1],
+                    (Date) row[2],
+                    (Date)row[3]);
+            }
+            return height;
+        }
+        return new BedHeight();
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeightSingle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,66 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+
+public class BedHeightSingle
+extends BedHeight
+{
+
+    protected int year;
+    protected TDoubleArrayList data_gap;
+    protected TDoubleArrayList morphWidth;
+
+    public BedHeightSingle() {
+        super();
+        this.year = -1;
+        data_gap = new TDoubleArrayList();
+        morphWidth = new TDoubleArrayList();
+    }
+
+    public BedHeightSingle(String name) {
+        super(name);
+        this.year = -1;
+        data_gap = new TDoubleArrayList();
+        morphWidth = new TDoubleArrayList();
+    }
+
+    public void add(
+        double value,
+        double station,
+        double gap,
+        double width,
+        int year
+    ) {
+        super.add(value, station);
+        this.year = year;
+        this.data_gap.add(gap);
+        this.morphWidth.add(width);
+    }
+
+    public int getYear() {
+        return this.year;
+    }
+
+    public double getMorphWidth(int idx) {
+        return this.morphWidth.get(idx);
+    }
+
+    public double getDataGap(int idx) {
+        return this.data_gap.get(idx);
+    }
+
+    public double getMorphWidth(double station) {
+        if (this.station.indexOf(station) >= 0) {
+            return this.morphWidth.get(this.station.indexOf(station));
+        }
+        return Double.NaN;
+    }
+
+    public double getDataGap(double station) {
+        if (this.station.indexOf(station) >= 0) {
+            return this.getDataGap(this.station.indexOf(station));
+        }
+        return Double.NaN;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedOverview.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,200 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.io.Serializable;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.type.StandardBasicTypes;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import de.intevation.flys.utils.KMIndex;
+
+public class BedOverview
+implements Serializable
+{
+    /**
+     * Serial version UId.
+     */
+    private static final long serialVersionUID = -7967134407371364911L;
+
+    public interface Filter {
+        boolean accept(KMIndex<List<Date>> entry);
+
+    } // interface Filter
+
+
+    public static final Filter ACCEPT = new Filter() {
+        public boolean accept(KMIndex<List<Date>> entry) {
+            return true;
+        }
+    };
+
+    public static class KmFilter implements Filter {
+
+        protected double km;
+
+        public KmFilter (double km) {
+            this.km = km;
+        }
+        public boolean accept(KMIndex<List<Date>> list) {
+            for (KMIndex.Entry<List<Date>> e: list){
+                if (e.getKm() == km) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    };
+
+    public static class DateFilter implements Filter {
+
+        protected Date date;
+
+        public DateFilter (Date date) {
+            this.date = date;
+        }
+
+        public boolean accept(KMIndex<List<Date>> list) {
+            for (KMIndex.Entry<List<Date>> e: list){
+                if (e.getValue().equals(this.date)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    };
+
+    private static Logger log = Logger.getLogger(BedOverview.class);
+
+    public static final double EPSILON = 1e-4;
+
+    public static final String DATE_FORMAT = "dd.MM.yyyy";
+
+    public static final String SQL_SQ =
+        "SELECT" +
+        "    so.km    AS km," +
+        "    so.datum AS datum " +
+        "FROM sohltest so " +
+        "    JOIN station s" +
+        "       ON so.stationid = s.stationid " +
+        "    JOIN gewaesser g " +
+        "       ON s.gewaesserid = g.gewaesserid " +
+        "WHERE" +
+        "    g.name = :name AND" +
+        "    so.km IS NOT NULL " +
+        "ORDER by" +
+        "    so.km, so.datum";
+
+    protected String       riverName;
+
+    protected KMIndex<List<Date>> entries;
+
+    public BedOverview() {
+        entries = new KMIndex<List<Date>>();
+    }
+
+    public BedOverview(String riverName) {
+        this();
+        this.riverName = riverName;
+    }
+
+    private static final boolean epsilonEquals(double a, double b) {
+        return Math.abs(a - b) < EPSILON;
+    }
+
+    protected void loadData(Session session) {
+        SQLQuery query = session.createSQLQuery(SQL_SQ)
+            .addScalar("km",    StandardBasicTypes.DOUBLE)
+            .addScalar("datum", StandardBasicTypes.DATE);
+
+        query.setString("name", riverName);
+
+        List<Object []> list = query.list();
+
+        if (list.isEmpty()) {
+            log.warn("No river '" + riverName + "' found.");
+        }
+
+        Double prevKm = -Double.MAX_VALUE;
+        List<Date> dates = new ArrayList<Date>();
+
+        for (Object [] row: list) {
+            Double km = (Double)row[0];
+            if (!epsilonEquals(km, prevKm) && !dates.isEmpty()) {
+                entries.add(prevKm, dates);
+                dates = new ArrayList<Date>();
+            }
+            dates.add((Date)row[1]);
+            prevKm = km;
+        }
+
+        if (!dates.isEmpty()) {
+            entries.add(prevKm, dates);
+        }
+    }
+
+    public boolean load(Session session) {
+
+        loadData(session);
+
+        return true;
+    }
+
+
+    public void generateOverview(Document document) {
+        generateOverview(document, ACCEPT);
+    }
+
+    public KMIndex<List<Date>> filter(Filter f) {
+        // TODO: Apply filter
+        return entries;
+    }
+
+    public void generateOverview(
+        Document document,
+        Filter   filter
+    ) {
+        KMIndex<List<Date>> filtered = filter(ACCEPT);
+
+        Element sqElement = document.createElement("bed");
+
+        Element riverElement = document.createElement("river");
+
+        riverElement.setAttribute("name", riverName);
+
+        sqElement.appendChild(riverElement);
+
+        SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
+
+        Element kmE = document.createElement("km");
+
+        for (KMIndex.Entry<List<Date>> e: filtered) {
+
+            List<Date> dates = e.getValue();
+
+            if (!dates.isEmpty()) {
+                Element dEs = document.createElement("dates");
+
+                for (Date d: dates) {
+                    Element dE = document.createElement("date");
+
+                    dE.setAttribute("value", df.format(d));
+
+                    dEs.appendChild(dE);
+                }
+
+                kmE.appendChild(dEs);
+            }
+        }
+
+        sqElement.appendChild(kmE);
+
+        document.appendChild(sqElement);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedOverviewFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,70 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+import org.hibernate.Session;
+
+import de.intevation.flys.artifacts.cache.CacheFactory;
+import de.intevation.flys.backend.SedDBSessionHolder;
+
+public class BedOverviewFactory {
+
+    private static Logger log = Logger.getLogger(BedOverviewFactory.class);
+
+    public static final String CACHE_NAME = "sq-overviews";
+
+    private BedOverviewFactory() {
+    }
+
+
+    public static BedOverview getOverview(String river) {
+
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug(
+                "Looking for bed overview for river '" + river + "'");
+        }
+
+        Cache cache = CacheFactory.getCache(CACHE_NAME);
+
+        if (cache == null) {
+            if (debug) {
+                log.debug("Cache not configured.");
+            }
+            return getUncached(river);
+        }
+
+        String key = "bed-over-" + river;
+
+        Element element = cache.get(key);
+
+        if (element != null) {
+            if (debug) {
+                log.debug("Overview found in cache");
+            }
+            return (BedOverview)element.getValue();
+        }
+
+        BedOverview overview = getUncached(river);
+
+        if (overview != null) {
+            if (debug) {
+                log.debug("Store overview in cache.");
+            }
+            cache.put(new Element(key, overview));
+        }
+
+        return overview;
+    }
+
+    public static BedOverview getUncached(String river) {
+        BedOverview overview = new BedOverview(river);
+
+        Session session = SedDBSessionHolder.HOLDER.get();
+
+        return overview.load(session) ? overview : null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedParametersResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,106 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.io.Serializable;
+
+
+public class BedParametersResult
+implements Serializable
+{
+    protected TDoubleArrayList porosityCap;
+    protected TDoubleArrayList porositySub;
+    protected TDoubleArrayList loadDensityCap;
+    protected TDoubleArrayList loadDensitySub;
+    protected TDoubleArrayList kms;
+
+    public BedParametersResult() {
+
+    }
+
+    public BedParametersResult(
+        TDoubleArrayList kms,
+        TDoubleArrayList porosityCap,
+        TDoubleArrayList porositySub,
+        TDoubleArrayList densityCap,
+        TDoubleArrayList densitySub
+    ) {
+        this.kms = kms;
+        this.porosityCap = porosityCap;
+        this.porositySub = porositySub;
+        this.loadDensityCap = densityCap;
+        this.loadDensitySub = densitySub;
+    }
+
+    public double getPorosityCap(int ndx) {
+        return porosityCap.get(ndx);
+    }
+
+    public double getPorositySub(int ndx) {
+        return porositySub.get(ndx);
+    }
+
+    public double getLoadDensityCap(int ndx) {
+        return loadDensityCap.get(ndx);
+    }
+
+    public double getLoadDensitySub(int ndx) {
+        return loadDensitySub.get(ndx);
+    }
+
+    public double getPorosityCap(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return porosityCap.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double getPorositySub(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return porositySub.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double getLoadDensityCap(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return loadDensityCap.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double getLoadDensitySub(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return loadDensitySub.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double[][] getPorosityCapData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            porosityCap.toNativeArray()
+        };
+    }
+
+    public double[][] getPorositySubData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            porositySub.toNativeArray()
+        };
+    }
+
+    public double[][] getDensityCapData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            loadDensityCap.toNativeArray()
+        };
+    }
+
+    public double[][] getDensitySubData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            loadDensitySub.toNativeArray()
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedPorosityFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,59 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+/**
+ * Facet for serving bed porosity data.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class BedPorosityFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger logger = Logger.getLogger(BedPorosityFacet.class);
+
+    public BedPorosityFacet() {
+    }
+
+    public BedPorosityFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed porosity at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        int ndx = index >> 8;
+        Object[] data = ((BedQualityResult[]) res.getData())[ndx].getParameters(); // TODO CAST TO SPECIFIC CLASS
+
+        int ndy = index & 255;
+        return data != null && data.length > ndy ? data[ndy] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedPorosityFacet copy = new BedPorosityFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,331 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.artifacts.access.BedQualityAccess;
+import de.intevation.flys.artifacts.model.Calculation;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DateRange;
+import de.intevation.flys.backend.SedDBSessionHolder;
+
+
+public class BedQualityCalculation extends Calculation {
+
+    private static final Logger logger = Logger
+        .getLogger(BedQualityCalculation.class);
+
+    protected String river;
+    protected double from;
+    protected double to;
+    protected List<String> bedDiameter;
+    protected List<String> bedloadDiameter;
+    protected List<DateRange> ranges;
+
+    public BedQualityCalculation() {
+    }
+
+    public CalculationResult calculate(BedQualityAccess access) {
+        logger.info("BedQualityCalculation.calculate");
+
+        String river = access.getRiver();
+        Double from = access.getFrom();
+        Double to = access.getTo();
+        List<String> bedDiameter = access.getBedDiameter();
+        List<String> bedloadDiameter = access.getBedloadDiameter();
+        List<DateRange> ranges = access.getDateRanges();
+
+        if (river == null) {
+            // TODO: i18n
+            addProblem("minfo.missing.river");
+        }
+
+        if (from == null) {
+            // TODO: i18n
+            addProblem("minfo.missing.from");
+        }
+
+        if (to == null) {
+            // TODO: i18n
+            addProblem("minfo.missing.to");
+        }
+
+        if (ranges == null) {
+            // TODO: i18n
+            addProblem("minfo.missing.periods");
+        }
+
+        if (!hasProblems()) {
+            this.river = river;
+            this.from = from;
+            this.to = to;
+            this.ranges = ranges;
+            this.bedDiameter = bedDiameter;
+            this.bedloadDiameter = bedloadDiameter;
+
+            SedDBSessionHolder.acquire();
+            try {
+                return internalCalculate();
+            }
+            finally {
+                SedDBSessionHolder.release();
+            }
+        }
+
+        return new CalculationResult();
+    }
+
+    protected CalculationResult internalCalculate() {
+
+        List<BedQualityResult> results = new LinkedList<BedQualityResult>();
+        // Calculate for all time periods.
+        for (DateRange dr : ranges) {
+            QualityMeasurements loadMeasurements =
+                QualityMeasurementFactory.getBedloadMeasurements(
+                    river,
+                    from,
+                    to,
+                    dr.getFrom(),
+                    dr.getTo());
+            QualityMeasurements bedMeasurements =
+                QualityMeasurementFactory.getBedMeasurements(
+                    river,
+                    from,
+                    to,
+                    dr.getFrom(),
+                    dr.getTo());
+            BedQualityResult result = new BedQualityResult();
+            result.setDateRange(dr);
+            if (bedDiameter != null) {
+                result.add(calculateBedParameter(bedMeasurements, dr));
+                for (String bd : bedDiameter) {
+                    BedDiameterResult bedResult =
+                        calculateBed(bedMeasurements, bd, dr);
+
+                    // Avoid adding empty result sets.
+                    if (!bedResult.isEmpty()) {
+                        result.add(bedResult);
+                    }
+                }
+            }
+            if (bedloadDiameter != null) {
+                for (String bld : bedloadDiameter) {
+                    BedloadDiameterResult loadResult =
+                        calculateBedload(loadMeasurements, bld, dr);
+                    result.add(loadResult);
+                }
+            }
+            results.add(result);
+        }
+
+        return new CalculationResult(
+            results.toArray(new BedQualityResult[results.size()]), this);
+    }
+
+    private BedParametersResult calculateBedParameter(
+        QualityMeasurements qm,
+        DateRange dr
+    ) {
+        List<Double> kms = qm.getKms();
+        QualityMeasurements capFiltered = filterCapMeasurements(qm);
+        QualityMeasurements subFiltered = filterSubMeasurements(qm);
+        TDoubleArrayList location = new TDoubleArrayList();
+        TDoubleArrayList porosityCap = new TDoubleArrayList();
+        TDoubleArrayList porositySub = new TDoubleArrayList();
+        TDoubleArrayList densityCap = new TDoubleArrayList();
+        TDoubleArrayList densitySub = new TDoubleArrayList();
+
+        for(double km : kms) {
+            double[] pCap = calculatePorosity(capFiltered, km);
+            double[] pSub = calculatePorosity(subFiltered, km);
+            double[] dCap = calculateDensity(capFiltered, pCap);
+            double[] dSub = calculateDensity(subFiltered, pSub);
+
+            double pCapRes = 0d;
+            double pSubRes = 0d;
+            double dCapRes = 0d;
+            double dSubRes = 0d;
+            for (int i = 0; i < pCap.length; i++) {
+                pCapRes += pCap[i];
+                dCapRes += dCap[i];
+            }
+            for (int i = 0; i < pSub.length; i++) {
+                pSubRes += pSub[i];
+                dSubRes += dSub[i];
+            }
+            location.add(km);
+            porosityCap.add((pCapRes / pCap.length) * 100 );
+            porositySub.add((pSubRes / pSub.length) * 100);
+            densityCap.add((dCapRes / dCap.length) / 1000);
+            densitySub.add((dSubRes / dSub.length) / 1000);
+
+        }
+
+        return new BedParametersResult(
+            location,
+            porosityCap,
+            porositySub,
+            densityCap,
+            densitySub);
+    }
+
+    protected BedDiameterResult calculateBed(
+        QualityMeasurements qm,
+        String diameter,
+        DateRange range
+    ) {
+        List<Double> kms = qm.getKms();
+        TDoubleArrayList location = new TDoubleArrayList();
+        TDoubleArrayList avDiameterCap = new TDoubleArrayList();
+        TDoubleArrayList avDiameterSub = new TDoubleArrayList();
+        for (double km : kms) {
+            //Filter cap and sub measurements.
+            QualityMeasurements capFiltered = filterCapMeasurements(qm);
+            QualityMeasurements subFiltered = filterSubMeasurements(qm);
+
+            List<QualityMeasurement> cm = capFiltered.getMeasurements(km);
+            List<QualityMeasurement> sm = subFiltered.getMeasurements(km);
+
+            double avCap = calculateAverage(cm, diameter);
+            double avSub = calculateAverage(sm, diameter);
+            location.add(km);
+            avDiameterCap.add(avCap);
+            avDiameterSub.add(avSub);
+        }
+        return new BedDiameterResult(
+            diameter,
+            avDiameterCap,
+            avDiameterSub,
+            location);
+    }
+
+    private double[] calculateDensity(
+        QualityMeasurements capFiltered,
+        double[] porosity
+    ) {
+        double[] density = new double[porosity.length];
+        for (int i = 0; i < porosity.length; i++) {
+            density[i] = (1 - porosity[i]) * 2650;
+        }
+        return density;
+    }
+
+    private double[] calculatePorosity(
+        QualityMeasurements capFiltered,
+        double km
+    ) {
+        List<QualityMeasurement> list = capFiltered.getMeasurements(km);
+        double[] results = new double[list.size()];
+        int i = 0;
+        for (QualityMeasurement qm : list) {
+            double deviation = calculateDeviation(qm);
+            double p = calculateP(qm);
+            double porosity = 0.353 - 0.068 * deviation + 0.146 * p;
+            results[i] = porosity;
+            i++;
+        }
+
+        return results;
+    }
+
+    protected BedloadDiameterResult calculateBedload(
+        QualityMeasurements qm,
+        String diameter,
+        DateRange range
+    ) {
+        List<Double> kms = qm.getKms();
+        TDoubleArrayList location = new TDoubleArrayList();
+        TDoubleArrayList avDiameter = new TDoubleArrayList();
+        for (double km : kms) {
+            List<QualityMeasurement> measurements = qm.getMeasurements(km);
+            double mid = calculateAverage(measurements, diameter);
+            location.add(km);
+            avDiameter.add(mid);
+        }
+        return new BedloadDiameterResult(
+            diameter,
+            avDiameter,
+            location,
+            range);
+    }
+
+    protected double calculateAverage(
+        List<QualityMeasurement> list,
+        String diameter
+    ) {
+        double av = 0;
+        for (QualityMeasurement qm : list) {
+            av += qm.getDiameter(diameter);
+        }
+        return av/list.size();
+    }
+
+    protected QualityMeasurements filterCapMeasurements(
+        QualityMeasurements qms
+    ) {
+        List<QualityMeasurement> result = new LinkedList<QualityMeasurement>();
+        for (QualityMeasurement qm : qms.getMeasurements()) {
+            if (qm.getDepth1() == 0d && qm.getDepth2() <= 0.3) {
+                result.add(qm);
+            }
+        }
+        return new QualityMeasurements(result);
+    }
+
+    protected QualityMeasurements filterSubMeasurements(
+        QualityMeasurements qms
+    ) {
+        List<QualityMeasurement> result = new LinkedList<QualityMeasurement>();
+        for (QualityMeasurement qm : qms.getMeasurements()) {
+            if (qm.getDepth1() > 0d && qm.getDepth2() <= 0.5) {
+                result.add(qm);
+            }
+        }
+        return new QualityMeasurements(result);
+    }
+
+    public double calculateDeviation(QualityMeasurement qm) {
+        Map<String, Double> dm = qm.getAllDiameter();
+        double phiM = 0;
+        double[] phis = new double[dm.size()];
+        double[] ps = new double[dm.size()];
+        int i = 0;
+        for (String key : dm.keySet()) {
+            double d = dm.get(key);
+            double phi = -Math.log(d)/Math.log(2);
+            phis[i] = phi;
+            double p = calculateWeight(qm, key);
+            ps[i] = p;
+            phiM += phi * p;
+            i++;
+        }
+
+        double sig = 0d;
+        for (i = 0; i < dm.size(); i++) {
+            sig += ps[i] * Math.exp(phis[i] - phiM);
+        }
+        double deviation = Math.sqrt(sig);
+        return deviation;
+    }
+
+    protected double calculateP(QualityMeasurement qm) {
+        return calculateWeight(qm, "dmin");
+    }
+
+    public double calculateWeight(QualityMeasurement qm, String diameter) {
+        Map<String, Double> dm = qm.getAllDiameter();
+        double value = qm.getDiameter(diameter);
+
+        double sum = 0d;
+        for (Double d : dm.values()) {
+            sum =+ d.doubleValue();
+        }
+        double weight = sum/100*value;
+        return weight;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityDiameterResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,61 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.io.Serializable;
+
+public class BedQualityDiameterResult implements Serializable {
+
+    public static enum DIAMETER_TYPE {
+        D90,
+        D84,
+        D80,
+        D75,
+        D70,
+        D60,
+        D50,
+        D40,
+        D30,
+        D25,
+        D20,
+        D16,
+        D10,
+        DMIN,
+        DMAX
+    }
+
+    protected DIAMETER_TYPE type;
+    protected TDoubleArrayList kms;
+    protected boolean empty;
+
+    public BedQualityDiameterResult () {
+        empty = true;
+    }
+
+    public BedQualityDiameterResult (
+        String type,
+        TDoubleArrayList km
+    ) {
+        if (km.size() > 0) {
+            empty = false;
+        }
+        this.type = DIAMETER_TYPE.valueOf(type.toUpperCase());
+        this.kms = km;
+    }
+
+    public DIAMETER_TYPE getType() {
+        return this.type;
+    }
+
+    public TDoubleArrayList getKms() {
+        return this.kms;
+    }
+
+    public void setType(DIAMETER_TYPE type) {
+        this.type = type;
+    }
+
+    public boolean isEmpty() {
+        return empty;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,69 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.intevation.flys.artifacts.model.DateRange;
+
+public class BedQualityResult
+implements Serializable
+{
+
+    protected List<BedDiameterResult> bedResults;
+    protected List<BedloadDiameterResult> bedloadResults;
+    protected List<BedParametersResult> bedParameters;
+    protected DateRange dateRange;
+
+    public BedQualityResult () {
+        bedResults = new LinkedList<BedDiameterResult>();
+        bedloadResults = new LinkedList<BedloadDiameterResult>();
+        bedParameters = new LinkedList<BedParametersResult>();
+    };
+
+    public BedQualityResult (
+        List<BedDiameterResult> bedResults,
+        List<BedloadDiameterResult> bedloadResults,
+        List<BedParametersResult> bedParameters,
+        DateRange range
+    ) {
+        this.dateRange = range;
+        this.bedResults = bedResults;
+        this.bedloadResults = bedloadResults;
+        this.bedParameters = bedParameters;
+    }
+
+    public BedParametersResult[] getParameters() {
+        return bedParameters.toArray(
+            new BedParametersResult[bedParameters.size()]);
+    }
+
+    public BedDiameterResult[] getBedResults() {
+        return bedResults.toArray(new BedDiameterResult[bedResults.size()]);
+    }
+
+    public BedloadDiameterResult[] getBedloadResults() {
+        return bedloadResults.toArray(
+            new BedloadDiameterResult[bedloadResults.size()]);
+    }
+
+    public void add(BedloadDiameterResult result) {
+        bedloadResults.add(result);
+    }
+
+    public void add(BedDiameterResult result) {
+        bedResults.add(result);
+    }
+
+    public void add(BedParametersResult result) {
+        bedParameters.add(result);
+    }
+
+    public DateRange getDateRange() {
+        return dateRange;
+    }
+
+    public void setDateRange(DateRange range) {
+        this.dateRange = range;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,61 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+/**
+ * Facet for serving bedload diameter data.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class BedloadDiameterFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger logger = Logger.getLogger(BedloadDiameterFacet.class);
+
+    public BedloadDiameterFacet() {
+        // required for clone operation deepCopy()
+    }
+
+    public BedloadDiameterFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bedload diameter at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        int ndx = index >> 8;
+        Object[] data =
+            ((BedQualityResult[]) res.getData())[ndx].getBedloadResults(); // TODO CAST TO SPECIFIC CLASS
+
+        int ndy = index & 255;
+        return data != null && data.length > ndy ? data[ndy] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedloadDiameterFacet copy = new BedloadDiameterFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadDiameterResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,42 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import de.intevation.flys.artifacts.model.DateRange;
+import gnu.trove.TDoubleArrayList;
+
+
+public class BedloadDiameterResult
+extends BedQualityDiameterResult
+{
+    protected TDoubleArrayList diameter;
+
+    public BedloadDiameterResult(
+        String type,
+        TDoubleArrayList diameter,
+        TDoubleArrayList km,
+        DateRange range
+    ) {
+        super (type, km);
+        this.diameter = diameter;
+    }
+
+    public double getDiameter(int ndx) {
+        if (diameter != null) {
+            return this.diameter.get(ndx);
+        }
+        return Double.NaN;
+    }
+
+    public double getDiameter(double km) {
+        if (kms.indexOf(km) >= 0) {
+            return diameter.get(kms.indexOf(km));
+        }
+        return Double.NaN;
+    }
+
+    public double[][] getDiameterData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            diameter.toNativeArray()
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadOverview.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,199 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.io.Serializable;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.type.StandardBasicTypes;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import de.intevation.flys.utils.KMIndex;
+
+public class BedloadOverview implements Serializable {
+
+    private static Logger log = Logger.getLogger(BedloadOverview.class);
+
+    /**
+     * Serial version UId.
+     */
+    private static final long serialVersionUID = -7607668985959407096L;
+
+    public interface Filter {
+        boolean accept(KMIndex<List<Date>> entry);
+
+    } // interface Filter
+
+
+    public static final Filter ACCEPT = new Filter() {
+        public boolean accept(KMIndex<List<Date>> entry) {
+            return true;
+        }
+    };
+
+    public static class KmFilter implements Filter {
+
+        protected double km;
+
+        public KmFilter (double km) {
+            this.km = km;
+        }
+        public boolean accept(KMIndex<List<Date>> list) {
+            for (KMIndex.Entry<List<Date>> e: list){
+                if (e.getKm() == km) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    };
+
+    public static class DateFilter implements Filter {
+
+        protected Date date;
+
+        public DateFilter (Date date) {
+            this.date = date;
+        }
+
+        public boolean accept(KMIndex<List<Date>> list) {
+            for (KMIndex.Entry<List<Date>> e: list){
+                if (e.getValue().equals(this.date)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    };
+
+    public static final double EPSILON = 1e-4;
+
+    public static final String DATE_FORMAT = "dd.MM.yyyy";
+
+    public static final String SQL_SQ =
+        "SELECT" +
+        "    m.km    AS km," +
+        "    m.datum AS datum " +
+        "FROM messung m " +
+        "    JOIN station s" +
+        "       ON m.stationid = s.stationid " +
+        "    JOIN gewaesser g " +
+        "       ON s.gewaesserid = g.gewaesserid " +
+        "WHERE" +
+        "    g.name = :name AND " +
+        "    m.km IS NOT NULL " +
+        "ORDER by" +
+        "    m.km, m.datum";
+
+    protected String       riverName;
+
+    protected KMIndex<List<Date>> entries;
+
+    public BedloadOverview() {
+        entries = new KMIndex<List<Date>>();
+    }
+
+    public BedloadOverview(String riverName) {
+        this();
+        this.riverName = riverName;
+    }
+
+    private static final boolean epsilonEquals(double a, double b) {
+        return Math.abs(a - b) < EPSILON;
+    }
+
+    protected void loadData(Session session) {
+        SQLQuery query = session.createSQLQuery(SQL_SQ)
+            .addScalar("km",    StandardBasicTypes.DOUBLE)
+            .addScalar("datum", StandardBasicTypes.DATE);
+
+        query.setString("name", riverName);
+
+        List<Object []> list = query.list();
+
+        if (list.isEmpty()) {
+            log.warn("No river '" + riverName + "' found.");
+        }
+
+        Double prevKm = -Double.MAX_VALUE;
+        List<Date> dates = new ArrayList<Date>();
+
+        for (Object [] row: list) {
+            Double km = (Double)row[0];
+            if (!epsilonEquals(km, prevKm) && !dates.isEmpty()) {
+                entries.add(prevKm, dates);
+                dates = new ArrayList<Date>();
+            }
+            dates.add((Date)row[1]);
+            prevKm = km;
+        }
+
+        if (!dates.isEmpty()) {
+            entries.add(prevKm, dates);
+        }
+    }
+
+    public boolean load(Session session) {
+
+        loadData(session);
+
+        return true;
+    }
+
+
+    public void generateOverview(Document document) {
+        generateOverview(document, ACCEPT);
+    }
+
+    public KMIndex<List<Date>> filter(Filter f) {
+        // TODO: Apply filter
+        return entries;
+    }
+
+    public void generateOverview(
+        Document document,
+        Filter   filter
+    ) {
+        KMIndex<List<Date>> filtered = filter(ACCEPT);
+
+        Element sqElement = document.createElement("bedload");
+
+        Element riverElement = document.createElement("river");
+
+        riverElement.setAttribute("name", riverName);
+
+        sqElement.appendChild(riverElement);
+
+        SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
+
+        Element kmE = document.createElement("km");
+
+        for (KMIndex.Entry<List<Date>> e: filtered) {
+
+            List<Date> dates = e.getValue();
+
+            if (!dates.isEmpty()) {
+                Element dEs = document.createElement("dates");
+
+                for (Date d: dates) {
+                    Element dE = document.createElement("date");
+
+                    dE.setAttribute("value", df.format(d));
+
+                    dEs.appendChild(dE);
+                }
+
+                kmE.appendChild(dEs);
+            }
+        }
+
+        sqElement.appendChild(kmE);
+
+        document.appendChild(sqElement);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedloadOverviewFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,70 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+import org.hibernate.Session;
+
+import de.intevation.flys.artifacts.cache.CacheFactory;
+import de.intevation.flys.backend.SedDBSessionHolder;
+
+public class BedloadOverviewFactory {
+
+    private static Logger log = Logger.getLogger(BedloadOverviewFactory.class);
+
+    public static final String CACHE_NAME = "sq-overviews";
+
+    private BedloadOverviewFactory() {
+    }
+
+
+    public static BedloadOverview getOverview(String river) {
+
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug(
+                "Looking for bedload overview for river '" + river + "'");
+        }
+
+        Cache cache = CacheFactory.getCache(CACHE_NAME);
+
+        if (cache == null) {
+            if (debug) {
+                log.debug("Cache not configured.");
+            }
+            return getUncached(river);
+        }
+
+        String key = "bedload-over-" + river;
+
+        Element element = cache.get(key);
+
+        if (element != null) {
+            if (debug) {
+                log.debug("Overview found in cache");
+            }
+            return (BedloadOverview)element.getValue();
+        }
+
+        BedloadOverview overview = getUncached(river);
+
+        if (overview != null) {
+            if (debug) {
+                log.debug("Store overview in cache.");
+            }
+            cache.put(new Element(key, overview));
+        }
+
+        return overview;
+    }
+
+    public static BedloadOverview getUncached(String river) {
+        BedloadOverview overview = new BedloadOverview(river);
+
+        Session session = SedDBSessionHolder.HOLDER.get();
+
+        return overview.load(session) ? overview : null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurement.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,80 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.Date;
+import java.util.Map;
+
+
+public class QualityMeasurement {
+
+    private double              km;
+    private Date                date;
+    private double              depth1;
+    private double              depth2;
+    private Map<String, Double> charDiameter;
+
+    public QualityMeasurement() {
+
+    }
+
+    public QualityMeasurement(
+        double km,
+        Date date,
+        double depth1,
+        double depth2,
+        Map<String, Double> diameter) {
+        this.setKm(km);
+        this.setDate(date);
+        this.depth1 = depth1;
+        this.depth2 = depth2;
+        this.setDiameter(diameter);
+    }
+
+    public double getKm() {
+        return km;
+    }
+
+    public void setKm(double km) {
+        this.km = km;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public Map<String, Double> getAllDiameter() {
+        return charDiameter;
+    }
+
+    public void setDiameter(Map<String, Double> charDiameter) {
+        this.charDiameter = charDiameter;
+    }
+
+    public double getDiameter(String key) {
+        return charDiameter.get(key);
+    }
+
+    public void setDiameter(String key, double value) {
+        charDiameter.put(key, value);
+    }
+
+    public double getDepth1() {
+        return depth1;
+    }
+
+    public void setDepth1(double depth1) {
+        this.depth1 = depth1;
+    }
+
+    public double getDepth2() {
+        return depth2;
+    }
+
+    public void setDepth2(double depth2) {
+        this.depth2 = depth2;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,203 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.transform.BasicTransformerAdapter;
+import org.hibernate.type.StandardBasicTypes;
+
+import de.intevation.flys.backend.SedDBSessionHolder;
+
+
+public class QualityMeasurementFactory {
+
+    private static Logger logger = Logger.getLogger(QualityMeasurementFactory.class);
+
+    private static final String SQL_BED_MEASUREMENT =
+        "SELECT st.km       as km," +
+        "       st.datum    as datum," +
+        "       sp.tiefevon as depth1," +
+        "       sp.tiefebis as depth2," +
+        "       sa.d10      as d10," +
+        "       sa.d16      as d16," +
+        "       sa.d20      as d20," +
+        "       sa.d25      as d25," +
+        "       sa.d30      as d30," +
+        "       sa.d40      as d40," +
+        "       sa.d50      as d50," +
+        "       sa.d60      as d60," +
+        "       sa.d70      as d70," +
+        "       sa.d75      as d75," +
+        "       sa.d80      as d80," +
+        "       sa.d84      as d84," +
+        "       sa.d90      as d90," +
+        "       sa.dmin     as dmin," +
+        "       sa.dmax     as dmax " +
+        "FROM sohltest st " +
+        "    JOIN station sn ON sn.stationid = st.stationid " +
+        "    JOIN gewaesser gw ON gw.gewaesserid = sn.gewaesserid " +
+        "    JOIN sohlprobe sp ON sp.sohltestid = st.sohltestid " +
+        "    JOIN siebanalyse sa ON sa.sohlprobeid = sp.sohlprobeid " +
+        "WHERE gw.name = :name AND " +
+        "      st.km IS NOT NULL AND " +
+        "      sp.tiefevon IS NOT NULL AND " +
+        "      sp.tiefebis IS NOT NULL AND " + // TODO: Test if char diameter ist null.
+        "      st.km BETWEEN :from - 0.001 AND :to + 0.001 AND " +
+        "      st.datum BETWEEN :start AND :end";
+
+    private static final String SQL_BEDLOAD_MEASUREMENT =
+        "SELECT m.km    as km," +
+        "       m.datum as datum," +
+        "       m.d10   as d10," +
+        "       m.d16   as d16," +
+        "       m.d20   as d20," +
+        "       m.d25   as d25," +
+        "       m.d30   as d30," +
+        "       m.d40   as d40," +
+        "       m.d50   as d50," +
+        "       m.d60   as d60," +
+        "       m.d70   as d70," +
+        "       m.d75   as d75," +
+        "       m.d80   as d80," +
+        "       m.d84   as d84," +
+        "       m.d90   as d90," +
+        "       m.dmin  as dmin," +
+        "       m.dmax  as dmax " +
+        "FROM messung m" +
+        "    JOIN station sn ON sn.stationid = m.stationid" +
+        "    JOIN gewaesser gw ON gw.gewaesserid = sn.gewaesserid " +
+        "WHERE gw.name = :name AND " +
+        "      m.km IS NOT NULL AND " +
+        "      m.d10 IS NOT NULL AND" + //TODO: Add all other char. diameter.
+        "      m.km BETWEEN :from - 0.001 AND :to + 0.001 AND" +
+        "      m.datum BETWEEN :start AND :end";
+
+    public static final class QualityMeasurementResultTransformer
+    extends BasicTransformerAdapter {
+
+        public static QualityMeasurementResultTransformer INSTANCE = new QualityMeasurementResultTransformer();
+
+        public QualityMeasurementResultTransformer() {
+        }
+
+        @Override
+        public Object transformTuple(Object[] tuple, String[] aliases) {
+            Map<String, Double> map = new HashMap<String, Double>();
+            double km = 0;
+            Date d = null;
+            double depth1 = Double.NaN;
+            double depth2 = Double.NaN;
+            for (int i = 0; i < tuple.length; ++i) {
+                if (tuple[i] != null) {
+                    if (aliases[i].equals("km")) {
+                        km = ((Number) tuple[i]).doubleValue();
+                    }
+                    else if (aliases[i].equals("datum")) {
+                        d = (Date) tuple[i];
+                    }
+                    else if (aliases[i].equals("depth1")) {
+                        depth1 = ((Number) tuple[i]).doubleValue();
+                    }
+                    else if (aliases[i].equals("depth2")) {
+                        depth2 = ((Number) tuple[i]).doubleValue();
+                    }
+                    else {
+                        map.put(aliases[i], ((Double) tuple[i])/1000);
+                    }
+                }
+            }
+            return new QualityMeasurement(km, d, depth1, depth2, map);
+        }
+    } // class BasicTransformerAdapter
+
+    private QualityMeasurementFactory() {
+    }
+
+    protected static QualityMeasurements load(
+        Session session,
+        String river,
+        double from,
+        double to,
+        Date start,
+        Date end,
+        String statement
+    ) {
+        SQLQuery query = session.createSQLQuery(statement)
+            .addScalar("km", StandardBasicTypes.DOUBLE)
+            .addScalar("datum", StandardBasicTypes.DATE)
+            .addScalar("d10", StandardBasicTypes.DOUBLE)
+            .addScalar("d16", StandardBasicTypes.DOUBLE)
+            .addScalar("d20", StandardBasicTypes.DOUBLE)
+            .addScalar("d25", StandardBasicTypes.DOUBLE)
+            .addScalar("d30", StandardBasicTypes.DOUBLE)
+            .addScalar("d40", StandardBasicTypes.DOUBLE)
+            .addScalar("d50", StandardBasicTypes.DOUBLE)
+            .addScalar("d60", StandardBasicTypes.DOUBLE)
+            .addScalar("d70", StandardBasicTypes.DOUBLE)
+            .addScalar("d75", StandardBasicTypes.DOUBLE)
+            .addScalar("d80", StandardBasicTypes.DOUBLE)
+            .addScalar("d84", StandardBasicTypes.DOUBLE)
+            .addScalar("d90", StandardBasicTypes.DOUBLE)
+            .addScalar("dmin", StandardBasicTypes.DOUBLE)
+            .addScalar("dmax", StandardBasicTypes.DOUBLE);
+
+        if (statement.equals(SQL_BED_MEASUREMENT)) {
+            query.addScalar("depth1", StandardBasicTypes.DOUBLE);
+            query.addScalar("depth2", StandardBasicTypes.DOUBLE);
+        }
+
+        query.setString("name", river);
+        query.setDouble("from", from);
+        query.setDouble("to", to);
+        query.setDate("start", start);
+        query.setDate("end", end);
+
+        query.setResultTransformer(
+            QualityMeasurementResultTransformer.INSTANCE);
+
+        return new QualityMeasurements(query.list());
+    }
+
+    public static QualityMeasurements getBedMeasurements(
+        String river,
+        double from,
+        double to,
+        Date start,
+        Date end) {
+        Session session = SedDBSessionHolder.HOLDER.get();
+        try {
+            return load(session, river, from, to, start, end,
+            SQL_BED_MEASUREMENT);
+        }
+        finally {
+            //session.close();
+        }
+    }
+
+    public static QualityMeasurements getBedloadMeasurements(
+        String river,
+        double from,
+        double to,
+        Date start,
+        Date end
+    ) {
+        Session session = SedDBSessionHolder.HOLDER.get();
+        try {
+            return load(
+                session,
+                river,
+                from,
+                to,
+                start,
+                end,
+                SQL_BEDLOAD_MEASUREMENT);
+        }
+        finally {
+            //session.close();
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurements.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,50 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class QualityMeasurements {
+    private static Logger logger = Logger.getLogger(QualityMeasurements.class);
+    private List<QualityMeasurement> measurements;
+
+    public QualityMeasurements() {
+    }
+
+    public QualityMeasurements(List<QualityMeasurement> list) {
+        measurements = list;
+    }
+
+    public List<QualityMeasurement> getMeasurements() {
+        return measurements;
+    }
+
+    public List<QualityMeasurement> getMeasurements(double km) {
+        List<QualityMeasurement> res = new LinkedList<QualityMeasurement>();
+        for (QualityMeasurement qm: measurements) {
+            if (qm.getKm() == km) {
+                res.add(qm);
+            }
+        }
+        return res;
+    }
+
+    public List<Double> getKms() {
+        List<Double> result = new LinkedList<Double>();
+        for (QualityMeasurement qm : measurements) {
+            if (result.indexOf(qm.getKm()) < 0) {
+                result.add(qm.getKm());
+            }
+        }
+        return result;
+    }
+
+    public void setMeasurements(List<QualityMeasurement> list) {
+        this.measurements = list;
+    }
+
+    public void addMeasurement(QualityMeasurement qm) {
+        this.measurements.add(qm);
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Fitting.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,7 +3,6 @@
 import de.intevation.flys.artifacts.math.fitting.Function;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.commons.math.MathException;
@@ -15,27 +14,36 @@
 import org.apache.log4j.Logger;
 
 public class Fitting
+implements   Outlier.Callback
 {
     private static Logger log = Logger.getLogger(Fitting.class);
 
+    public interface Callback {
+
+        void afterIteration(
+            double [] parameters,
+            SQ []     measurements,
+            SQ []     outliers,
+            double    standardDeviation,
+            double    chiSqr);
+    } // interfacte
+
     protected Function function;
 
-    protected double [] parameters;
+    protected double [] coeffs;
+
+    protected de.intevation.flys.artifacts.math.Function instance;
 
     protected double stdDevFactor;
-
-    protected double standardDeviation;
-
     protected double chiSqr;
 
-    protected SQ [] remaining;
-
-    protected List<SQ []> outliers;
+    protected Callback callback;
 
     public Fitting() {
     }
 
     public Fitting(Function function, double stdDevFactor) {
+        this();
         this.function     = function;
         this.stdDevFactor = stdDevFactor;
     }
@@ -48,14 +56,6 @@
         this.function = function;
     }
 
-    public double [] getParameters() {
-        return parameters;
-    }
-
-    public void setParameters(double [] parameters) {
-        this.parameters = parameters;
-    }
-
     public double getStdDevFactor() {
         return stdDevFactor;
     }
@@ -64,45 +64,51 @@
         this.stdDevFactor = stdDevFactor;
     }
 
-    public double getStandardDeviation() {
-        return standardDeviation;
-    }
+    @Override
+    public void initialize(List<SQ> sqs) throws MathException {
 
-    public void setStandardDeviation(double standardDeviation) {
-        this.standardDeviation = standardDeviation;
-    }
+        LevenbergMarquardtOptimizer lmo =
+            new LevenbergMarquardtOptimizer();
 
-    public double getChiSqr() {
-        return chiSqr;
-    }
+        CurveFitter cf = new CurveFitter(lmo);
+        for (SQ sq: sqs) {
+            cf.addObservedPoint(sq.getQ(), sq.getS());
+        }
 
-    public void setChiSqr(double chiSqr) {
-        this.chiSqr = chiSqr;
+        coeffs = cf.fit(
+            function, function.getInitialGuess());
+
+        instance = function.instantiate(coeffs);
+
+        chiSqr = lmo.getChiSquare();
     }
 
-    public SQ [] getRemaining() {
-        return remaining;
-    }
-
-    public void setRemaining(SQ [] remaining) {
-        this.remaining = remaining;
+    @Override
+    public double eval(SQ sq) {
+        double s = instance.value(sq.q);
+        return sq.s - s;
     }
 
-    public List<SQ []> getOutliers() {
-        return outliers;
-    }
-
-    public void setOutliers(List<SQ []> outliers) {
-        this.outliers = outliers;
-    }
-
-    public void reset() {
-        outliers          = null;
-        remaining         = null;
-        parameters        = null;
-        standardDeviation = 0d;
-        standardDeviation = 0d;
-        chiSqr            = 0d;
+    @Override
+    public void iterationFinished(
+        double   standardDeviation,
+        SQ       outlier,
+        List<SQ> remainings
+    ) {
+        if (log.isDebugEnabled()) {
+            log.debug("iterationFinished ----");
+            log.debug(" num remainings: " + remainings.size());
+            log.debug(" has outlier: " + outlier != null);
+            log.debug(" standardDeviation: " + standardDeviation);
+            log.debug(" Chi^2: " + chiSqr);
+            log.debug("---- iterationFinished");
+        }
+        callback.afterIteration(
+            coeffs,
+            remainings.toArray(new SQ[remainings.size()]),
+            outlier != null ? new SQ [] { outlier} : new SQ [] {},
+            standardDeviation,
+            chiSqr);
     }
 
     protected static final List<SQ> onlyValid(List<SQ> sqs) {
@@ -118,7 +124,7 @@
         return good;
     }
 
-    public boolean fit(List<SQ> sqs) {
+    public boolean fit(List<SQ> sqs, Callback callback) {
 
         sqs = onlyValid(sqs);
 
@@ -127,94 +133,10 @@
             return false;
         }
 
-        final LevenbergMarquardtOptimizer lmo =
-            new LevenbergMarquardtOptimizer();
-
-        CurveFitter cf = new CurveFitter(lmo);
-
-        for (SQ sq: sqs) {
-            cf.addObservedPoint(sq.getQ(), sq.getS());
-        }
-
-        try {
-            parameters = cf.fit(function, function.getInitialGuess());
-        }
-        catch (MathException me) {
-            log.warn(me);
-            return false;
-        }
-
-        chiSqr = lmo.getChiSquare();
-
-        final de.intevation.flys.artifacts.math.Function [] instance = {
-            function.instantiate(parameters)
-        };
+        this.callback = callback;
 
         try {
-            remaining = Outlier.detectOutliers(
-                new Outlier.Callback() {
-
-                    List<List<SQ>> outliers =
-                        new ArrayList<List<SQ>>();
-
-                    int currentIteration;
-
-                    @Override
-                    public double eval(SQ sq) {
-                        double s = instance[0].value(sq.q);
-                        return s - sq.s;
-                    }
-
-                    @Override
-                    public void iteration(int i) {
-                        currentIteration = i;
-                    }
-
-                    @Override
-                    public void outlier(SQ sq) {
-                        if (currentIteration > outliers.size()) {
-                            outliers.add(new ArrayList<SQ>(2));
-                        }
-                        outliers.get(currentIteration-1).add(sq);
-                    }
-
-                    @Override
-                    public void standardDeviation(double stdDev) {
-                        setStandardDeviation(stdDev);
-                    }
-
-                    @Override
-                    public void reinitialize(Iterator<SQ> good)
-                    throws MathException
-                    {
-                        CurveFitter cf = new CurveFitter(lmo);
-                        while (good.hasNext()) {
-                            SQ sq = good.next();
-                            cf.addObservedPoint(sq.getQ(), sq.getS());
-                        }
-
-                        parameters = cf.fit(
-                            function, function.getInitialGuess());
-
-                        instance[0] = function.instantiate(parameters);
-
-                        chiSqr = lmo.getChiSquare();
-                    }
-
-                    @Override
-                    public void finished() {
-                        List<SQ []> result =
-                            new ArrayList<SQ []>(outliers.size());
-
-                        for (List<SQ> ols: outliers) {
-                            result.add(ols.toArray(new SQ[ols.size()]));
-                        }
-
-                        setOutliers(result);
-                    }
-                },
-                sqs,
-                stdDevFactor);
+            Outlier.detectOutliers(this, sqs, stdDevFactor);
         }
         catch (MathException me) {
             log.warn(me);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Measurement.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Measurement.java	Fri Sep 28 12:15:40 2012 +0200
@@ -6,6 +6,9 @@
 {
     protected Map<String, Object> data;
 
+    protected Measurement prev;
+    protected Measurement next;
+
     public Measurement() {
     }
 
@@ -27,44 +30,99 @@
     }
 
     public double Q() {
-        return get("Q");
+        return get("Q_BPEGEL");
     }
 
-    public double S_BL_S() {
-        // TODO: Implement me!
-        return Double.NaN;
+    public double TOTAL_BL() {
+        return get("TGESCHIEBE");
     }
 
-    public double S_BL_FG() {
+    public double BL_G() {
         // TODO: Implement me!
         return Double.NaN;
     }
 
-    public double S_BL_CG() {
-        // TODO: Implement me!
-        return Double.NaN;
-    }
-
-    public double S_BL() {
+    public double BL_C() {
         // TODO: Implement me!
         return Double.NaN;
     }
 
-	public double SIEB(int i) {
-		return get(String.format("SIEB%02d", i));
-	}
+    public double BL_S() {
+        // TODO: Implement me!
+        return Double.NaN;
+    }
 
-	public double RSIEB(int i) {
-		return get(String.format("RSIEB%02d", i));
-	}
+    public double S_BL_S() {
+        return TOTAL_BL() * BL_S();
+    }
 
-	public double REST() {
-		return get("REST");
-	}
+    public double S_BL_FG() {
+        return TOTAL_BL() * BL_G();
+    }
+
+    public double S_BL_CG() {
+        return TOTAL_BL() * BL_C();
+    }
+
+    public double S_BL_1() {
+        return S_BL_S() + S_BL_FG() + S_BL_CG();
+    }
+
+    public double S_BL_2() {
+        return S_SS() + S_BL_S() + S_BL_FG() + S_BL_CG();
+    }
+
+    public double SIEB(int i) {
+        return get(String.format("SIEB%02d", i));
+    }
+
+    public double RSIEB(int i) {
+        return get(String.format("RSIEB%02d", i));
+    }
+
+    public double REST() {
+        return get("REST");
+    }
 
     @Override
     public String toString() {
         return "Measurement: " + data;
     }
+
+    /**
+     * Gets the prev for this instance.
+     *
+     * @return The prev.
+     */
+    public Measurement getPrev() {
+        return this.prev;
+    }
+
+    /**
+     * Sets the prev for this instance.
+     *
+     * @param prev The prev.
+     */
+    public void setPrev(Measurement prev) {
+        this.prev = prev;
+    }
+
+    /**
+     * Gets the next for this instance.
+     *
+     * @return The next.
+     */
+    public Measurement getNext() {
+        return this.next;
+    }
+
+    /**
+     * Sets the next for this instance.
+     *
+     * @param next The next.
+     */
+    public void setNext(Measurement next) {
+        this.next = next;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/MeasurementFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,5 +1,7 @@
 package de.intevation.flys.artifacts.model.sq;
 
+import java.util.List;
+
 import de.intevation.flys.artifacts.model.DateRange;
 
 import de.intevation.flys.backend.SedDBSessionHolder;
@@ -21,62 +23,52 @@
     private static final Logger log =
         Logger.getLogger(MeasurementFactory.class);
 
-    public static final String [] GSIEBSATZ = {
-        "SIEB01", "SIEB02", "SIEB03", "SIEB04",
-        "SIEB05", "SIEB06", "SIEB07", "SIEB08",
-        "SIEB09", "SIEB10", "SIEB11", "SIEB13",
-        "SIEB13", "SIEB14", "SIEB15", "SIEB16",
-        "SIEB17", "SIEB18", "SIEB19", "SIEB20",
-        "SIEB21"
-    };
-
-    public static final String [] SSIEBUNG = {
-        "RSIEB01", "RSIEB02", "RSIEB03", "RSIEB04",
-        "RSIEB05", "RSIEB06", "RSIEB07", "RSIEB08",
-        "RSIEB09", "RSIEB10", "RSIEB11", "RSIEB13",
-        "RSIEB13", "RSIEB14", "RSIEB15", "RSIEB16",
-        "RSIEB17", "RSIEB18", "RSIEB19", "RSIEB20",
-        "RSIEB21", "REST"
-    };
-
     public static final String SQL_MEASSURE =
-        ("SELECT " +
-            "m.TSAND   AS TSAND,"   +
-            "m.TSCHWEB AS TSCHWEB," +
-            "m.CSCHWEB AS CSCHWEB," +
-            "m.Q       AS Q," +
-            "%GSIEBSATZ%," +
-            "%SSIEBUNG% " +
-        "FROM messung m " +
-            "JOIN station   s ON m.stationid   = s.stationid " +
-            "JOIN gewaesser g ON s.gewaesserid = g.gewaesserid " +
-            "LEFT JOIN GSIEBSATZ gs ON m.gsiebsatzid = gs.gsiebsatzid " +
-            "LEFT JOIN SSIEBUNG  ss ON gs.gsiebsatzid = ss.gsiebsatzid " +
+        "SELECT m.datum        AS DATUM," +
+               "g.UFERABST     AS UFERABST," +
+               "g.UFERABLINKS  AS UFERABLINKS," +
+               "m.TSCHWEB      AS TSCHWEB," +
+               "m.TSAND        AS TSAND," +
+               "gp.MESSDAUER   AS MESSDAUER," +
+               "gp.MENGE       AS MENGE," +
+               "gp.GTRIEB      AS GTRIEB," +
+               "gp.LFDNR       AS LFDNR," +
+               "m.TGESCHIEBE   AS TGESCHIEBE," +
+               "gs.RSIEB01     AS RSIEB01," +
+               "gs.RSIEB02     AS RSIEB02," +
+               "gs.RSIEB03     AS RSIEB03," +
+               "gs.RSIEB04     AS RSIEB04," +
+               "gs.RSIEB05     AS RSIEB05," +
+               "gs.RSIEB06     AS RSIEB06," +
+               "gs.RSIEB07     AS RSIEB07," +
+               "gs.RSIEB08     AS RSIEB08," +
+               "gs.RSIEB09     AS RSIEB09," +
+               "gs.RSIEB10     AS RSIEB10," +
+               "gs.RSIEB11     AS RSIEB11," +
+               "gs.RSIEB12     AS RSIEB12," +
+               "gs.RSIEB13     AS RSIEB13," +
+               "gs.RSIEB14     AS RSIEB14," +
+               "gs.RSIEB15     AS RSIEB15," +
+               "gs.RSIEB16     AS RSIEB16," +
+               "gs.RSIEB17     AS RSIEB17," +
+               "gs.RSIEB18     AS RSIEB18," +
+               "gs.RSIEB19     AS RSIEB19," +
+               "gs.RSIEB20     AS RSIEB20," +
+               "gs.RSIEB21     AS RSIEB21," +
+               "gs.REST        AS REST," +
+               "g.GLOTRECHTEID AS GLOTRECHTEID " +
+        "FROM MESSUNG m " +
+            "JOIN STATION    s ON m.STATIONID    = s.STATIONID " +
+            "JOIN glotrechte g ON m.MESSUNGID    = g.MESSUNGID " +
+            "JOIN gprobe    gp ON g.GLOTRECHTEID = gp.GLOTRECHTEID " +
+            "JOIN GSIEBUNG  gs ON g.GLOTRECHTEID = gs.GLOTRECHTEID " +
         "WHERE " +
-            "g.name = :river_name AND " +
-            "s.km BETWEEN :location - 0.001 AND :location + 0.001 AND " +
-            "m.datum BETWEEN :from AND :to AND " +
-            "m.Q IS NOT NULL")
-        .replace("%GSIEBSATZ%", projection("gs", GSIEBSATZ))
-        .replace("%SSIEBUNG%",  projection("ss", SSIEBUNG));
-
-    private static final String projection(
-        String    prefix,
-        String [] columnNames
-    ) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < columnNames.length; ++i) {
-            if (i > 0) {
-                sb.append(',');
-            }
-            sb.append(prefix)
-              .append('.')
-              .append(columnNames[i])
-              .append(" AS ")
-              .append(columnNames[i]);
-        }
-        return sb.toString();
-    }
+            "g.NAME = :river_name " +
+            "AND m.Q_BPEGEL IS NOT NULL " +
+            "AND s.KM BETWEEN :location - 0.001 AND :location + 0.001 " +
+            "AND m.DATUM BETWEEN :from AND :to " +
+            "AND m.TGESCHIEBE IS NOT NULL " +
+        "ORDER BY m.DATUM";
 
     public static final class MeasurementResultTransformer
     extends                   BasicTransformerAdapter
@@ -115,18 +107,40 @@
         }
 
         SQLQuery query = session.createSQLQuery(SQL_MEASSURE)
-            .addScalar("TSAND",   StandardBasicTypes.DOUBLE)
-            .addScalar("TSCHWEB", StandardBasicTypes.DOUBLE)
-            .addScalar("CSCHWEB", StandardBasicTypes.DOUBLE)
-            .addScalar("Q",       StandardBasicTypes.DOUBLE);
-
-        for (String siebsatz: GSIEBSATZ) {
-            query.addScalar(siebsatz, StandardBasicTypes.DOUBLE);
-        }
-
-        for (String siebung: SSIEBUNG) {
-            query.addScalar(siebung, StandardBasicTypes.DOUBLE);
-        }
+            .addScalar("Q_BPEGEL",     StandardBasicTypes.DOUBLE)
+            .addScalar("DATUM",        StandardBasicTypes.DATE)
+            .addScalar("UFERABST",     StandardBasicTypes.DOUBLE)
+            .addScalar("UFERABLINKS",  StandardBasicTypes.DOUBLE)
+            .addScalar("TSCHWEB",      StandardBasicTypes.DOUBLE)
+            .addScalar("TSAND",        StandardBasicTypes.DOUBLE)
+            .addScalar("MESSDAUER",    StandardBasicTypes.DOUBLE)
+            .addScalar("MENGE",        StandardBasicTypes.DOUBLE)
+            .addScalar("GTRIEB",       StandardBasicTypes.DOUBLE)
+            .addScalar("LFDNR",        StandardBasicTypes.DOUBLE)
+            .addScalar("TGESCHIEBE",   StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB01",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB02",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB03",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB04",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB05",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB06",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB07",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB08",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB09",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB10",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB11",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB12",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB13",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB14",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB15",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB16",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB17",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB18",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB19",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB20",      StandardBasicTypes.DOUBLE)
+            .addScalar("RSIEB21",      StandardBasicTypes.DOUBLE)
+            .addScalar("REST",         StandardBasicTypes.DOUBLE)
+            .addScalar("GLOTRECHTEID", StandardBasicTypes.DOUBLE);
 
         query.setString("river_name", river);
         query.setDouble("location", location);
@@ -135,7 +149,18 @@
 
         query.setResultTransformer(MeasurementResultTransformer.INSTANCE);
 
-        return new Measurements(query.list());
+        @SuppressWarnings("unchecked")
+		List<Measurement> measuments = (List<Measurement>)query.list();
+
+        for (int i = 0, N = measuments.size(); i < N; ++i) {
+            Measurement m = measuments.get(i);
+            Measurement p = i >   0 ? measuments.get(i-1) : null;
+            Measurement n = i < N-1 ? measuments.get(i+1) : null;
+            m.setPrev(p);
+            m.setNext(n);
+        }
+
+        return new Measurements(measuments);
     }
 
     public static Measurements getMeasurements(
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Measurements.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Measurements.java	Fri Sep 28 12:15:40 2012 +0200
@@ -51,7 +51,7 @@
     public static final SExtractor S_BL_EXTRACTOR = new SExtractor() {
         @Override
         public double getS(Measurement measument) {
-            return measument.S_BL();
+            return measument.BL_S();
         }
     };
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,123 +1,84 @@
 package de.intevation.flys.artifacts.model.sq;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.commons.math.MathException;
 
 import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
 
+import org.apache.log4j.Logger;
+
 public class Outlier
 {
-    public static final int MAX_ITERATIONS = 1000;
+    private static Logger log = Logger.getLogger(Outlier.class);
 
     public interface Callback {
 
+        void initialize(List<SQ> sqs) throws MathException;
+
         double eval(SQ sq);
 
-        void iteration(int i);
-
-        void outlier(SQ sq);
-
-        void standardDeviation(double stdDev);
-
-        void reinitialize(Iterator<SQ> good) throws MathException;
-
-        void finished();
+        void iterationFinished(
+            double   stdDev,
+            SQ       outlier,
+            List<SQ> remaining);
 
     } // interface Callback
 
-    private static final class EvalSQ {
-        protected SQ     sq;
-        protected double value;
-
-        public EvalSQ(SQ sq) {
-            this.sq = sq;
-        }
-    } // class EvalSQ
-
-    public static SQ [] detectOutliers(
+    public static void detectOutliers(
         Callback callback,
         List<SQ> sqs,
         double   stdDevFactor
     )
     throws MathException
     {
-        List<EvalSQ> data = new ArrayList<EvalSQ>(sqs.size());
+        boolean debug = log.isDebugEnabled();
 
-        for (SQ sq: sqs) {
-            data.add(new EvalSQ(sq));
+        if (debug) {
+            log.debug("stdDevFactor: " + stdDevFactor);
         }
 
-        List<EvalSQ> good = new ArrayList<EvalSQ>(sqs.size());
+        List<SQ> data = new ArrayList<SQ>(sqs);
 
-        for (int i = 1; i <= MAX_ITERATIONS && data.size() > 2; ++i) {
+        while (data.size() > 2) {
+
+            callback.initialize(data);
 
             StandardDeviation stdDev = new StandardDeviation();
 
-            for (EvalSQ esq: data) {
-                stdDev.increment(esq.value = callback.eval(esq.sq));
+            double maxValue = -Double.MAX_VALUE;
+            int    maxIndex = -1;
+
+            for (int i = data.size()-1; i >= 0; --i) {
+                double value = Math.abs(callback.eval(data.get(i)));
+                stdDev.increment(value);
+                if (value > maxValue) {
+                    maxValue = value;
+                    maxIndex = i;
+                }
             }
 
             double sd = stdDev.getResult();
 
-            callback.standardDeviation(sd);
-
             double accepted = stdDevFactor * sd;
 
-            callback.iteration(i);
-
-            for (EvalSQ esq: data) {
-                if (Math.abs(esq.value) > accepted) {
-                    callback.outlier(esq.sq);
-                }
-                else {
-                    good.add(esq);
-                }
-            }
-
-            if (good.size() == data.size()) {
-                break;
+            if (debug) {
+                log.debug("std dev: " + stdDev);
+                log.debug("accepted: " + accepted);
+                log.debug("max value: " + maxValue);
             }
 
-            callback.reinitialize(asSQIterator(good));
-
-            List<EvalSQ> tmp = good;
-            good = data;
-            data = tmp;
-            good.clear();
-        }
-
-        callback.finished();
-
-        SQ [] result = new SQ[good.size()];
-
-        for (int i = 0; i < result.length; ++i) {
-            result[i] = good.get(i).sq;
-        }
+            SQ outlier = maxValue > accepted
+                ? data.remove(maxIndex)
+                : null;
 
-        return result;
-    }
+            callback.iterationFinished(sd, outlier, data);
 
-    protected static Iterator<SQ> asSQIterator(List<EvalSQ> esqs) {
-        final Iterator<EvalSQ> parent = esqs.iterator();
-        return new Iterator<SQ>() {
-            @Override
-            public boolean hasNext() {
-                return parent.hasNext();
+            if (outlier == null) {
+                break;
             }
-
-            @Override
-            public SQ next() {
-                return parent.next().sq;
-            }
-
-            @Override
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
+        }
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQCurveFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQCurveFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -53,41 +53,42 @@
     public Object getData(Artifact artifact, CallContext context) {
         log.debug("SQCurveFacet.getData");
 
-        if (artifact instanceof FLYSArtifact) {
-            FLYSArtifact flys = (FLYSArtifact) artifact;
-
-            CalculationResult res = (CalculationResult) flys.compute(
-                context, ComputeType.ADVANCE, false);
-
-            SQResult[]       results = (SQResult[]) res.getData();
-            SQFractionResult result  = results[index].getFraction(fractionIdx);
-
-            Function func = FunctionFactory.getInstance().getFunction(FUNCTION);
-            String[] paramNames = func.getParameterNames();
-
-            Parameters params = result.getParameters();
-
-            if (params == null) {
-                log.debug("no parameters found");
-                return null;
-            }
-
-            double[]   coeffs = params.get(0, paramNames);
-
-            if (log.isDebugEnabled()) {
-                for (int i = 0, N = paramNames.length; i < N; i++) {
-                    log.debug("retrieved parameter " + paramNames[i] +
-                              " = " + coeffs[i]);
-                }
-            }
-
-            de.intevation.flys.artifacts.math.Function mf =
-                func.instantiate(coeffs);
-
-            return new SQFunction(mf, result.getMinQ(), result.getMaxQ());
+        if (!(artifact instanceof FLYSArtifact)) {
+            return null;
         }
 
-        return null;
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(
+            context, ComputeType.ADVANCE, false);
+
+        SQResult[]       results = (SQResult[]) res.getData();
+        SQFractionResult result  = results[index].getFraction(fractionIdx);
+
+        Parameters params = result.getParameters();
+
+        if (params == null) {
+            log.debug("no parameters found");
+            return null;
+        }
+
+        Function func = FunctionFactory.getInstance().getFunction(FUNCTION);
+        String[] paramNames = func.getParameterNames();
+
+        double [] coeffs = params.get(0, paramNames);
+
+        if (log.isDebugEnabled()) {
+            for (int i = 0, N = paramNames.length; i < N; i++) {
+                log.debug("retrieved parameter " + paramNames[i] +
+                          " = " + coeffs[i]);
+            }
+        }
+
+        de.intevation.flys.artifacts.math.Function mf =
+            func.instantiate(coeffs);
+
+        double [] extent = result.getQExtent();
+        return new SQFunction(mf, extent[0], extent[1]);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQFractionResult.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQFractionResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -6,103 +6,161 @@
 
 import java.util.List;
 
-public class SQFractionResult implements Serializable {
+public class SQFractionResult
+implements   Serializable
+{
+    public static class Iteration
+    implements          Serializable
+    {
+        protected Parameters parameters;
+        protected SQ []      measurements;
+        protected SQ []      outliers;
 
-    protected Parameters parameters;
-    protected SQ[]       measurements;
-    protected List<SQ[]> outliers;
+        public Iteration() {
+        }
+
+        public Iteration(
+            Parameters parameters,
+            SQ []      measurements,
+            SQ []      outliers
+        ) {
+            this.parameters   = parameters;
+            this.measurements = measurements;
+            this.outliers     = outliers;
+        }
+
+        public Parameters getParameters() {
+            return parameters;
+        }
+
+        public void setParameters(Parameters parameters) {
+            this.parameters = parameters;
+        }
+
+        public SQ [] getMeasurements() {
+            return measurements;
+        }
+
+        public void setMeasurements(SQ [] measurements) {
+            this.measurements = measurements;
+        }
+
+        public SQ [] getOutliers() {
+            return outliers;
+        }
+
+        public void setOutliers(SQ [] outliers) {
+            this.outliers = outliers;
+        }
+
+        public boolean isValid() {
+            return parameters   != null
+                && measurements != null
+                && outliers     != null;
+        }
+
+        public int numOutliers() {
+            return outliers != null
+                ? outliers.length
+                : 0;
+        }
+
+        public int numMeasurements() {
+            return measurements != null
+                ? measurements.length
+                : 0;
+        }
+    } // class Iteration
+
+    protected SQ []           measurements;
+    protected List<Iteration> iterations;
 
     public SQFractionResult() {
     }
 
     public SQFractionResult(
-        Parameters parameters,
-        SQ[]       measurements,
-        List<SQ[]> outliers
+        SQ []           measurements,
+        List<Iteration> iterations
     ) {
-        this.parameters   = parameters;
         this.measurements = measurements;
-        this.outliers     = outliers;
+        this.iterations   = iterations;
     }
 
-    public boolean isValid() {
-        return parameters   != null
-            && measurements != null
-            && outliers     != null;
-    }
-
-    public Parameters getParameters() {
-        return parameters;
-    }
-
-    public void setParameters(Parameters parameters) {
-        this.parameters = parameters;
-    }
-
-
-    public SQ[] getMeasurements() {
+    public SQ [] getMeasurements() {
         return measurements;
     }
 
-    public void setMeasurements(SQ[] measurements) {
+    public void setMeasurements(SQ [] measurements) {
         this.measurements = measurements;
     }
 
-
-    public List<SQ[]> getOutliers() {
-        return outliers;
-    }
-
-    public void setOutliers(List<SQ[]> outliers) {
-        this.outliers = outliers;
-    }
-
-
-    public int getOutliersCount() {
-        return outliers == null ? 0 : outliers.size();
+    public List<Iteration> getIterations() {
+        return iterations;
     }
 
-
-    public SQ[] getOutliers(int idx) {
-        if (outliers != null && idx >= 0 && idx < outliers.size()) {
-            return outliers.get(idx);
-        }
-
-        return null;
+    public void setIterations(List<Iteration> iterations) {
+        this.iterations = iterations;
     }
 
-    public void addOutliers(SQ[] outliers) {
-        this.outliers.add(outliers);
+    public double [] getQExtent() {
+        return getQExtent(new double[2]);
     }
 
-
-    public double getMinQ() {
-        double min = Double.MAX_VALUE;
+    public double [] getQExtent(double extent[]) {
+        extent[0] =  Double.MAX_VALUE;
+        extent[1] = -Double.MIN_VALUE;
 
         for (SQ sq: measurements) {
             double q = sq.getQ();
-
-            if (q < min) {
-                min = q;
-            }
+            if (q < extent[0]) extent[0] = q;
+            if (q > extent[1]) extent[1] = q;
         }
 
-        return min;
+        return extent;
     }
 
-
-    public double getMaxQ() {
-        double max = -Double.MAX_VALUE;
+    public int numIterations() {
+        return iterations != null ? iterations.size() : 0;
+    }
 
-        for (SQ sq: measurements) {
-            double q = sq.getQ();
+    public Parameters getParameters() {
+        return iterations != null && !iterations.isEmpty()
+            ? iterations.get(iterations.size()-1).getParameters()
+            : null;
+    }
 
-            if (q > max) {
-                max = q;
+    public SQ [] getOutliers(int index) {
+        return index >= 0 && index < iterations.size()
+            ? iterations.get(index).getOutliers()
+            : null;
+    }
+
+    public Parameters getParameters(int index) {
+        return index >= 0 && index < iterations.size()
+            ? iterations.get(index).getParameters()
+            : null;
+    }
+
+    public SQ [] getMeasurements(int index) {
+        return index >= 0 && index < iterations.size()
+            ? iterations.get(index).getMeasurements()
+            : null;
+    }
+
+    public int totalNumOutliers() {
+        int sum = 0;
+        if (iterations != null) {
+            for (Iteration iteration: iterations) {
+                sum += iteration.numOutliers();
             }
         }
+        return sum;
+    }
 
-        return max;
+    public int numMeasurements() {
+        return measurements != null
+            ? measurements.length
+            : 0;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQMeasurementFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQMeasurementFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -46,19 +46,19 @@
     public Object getData(Artifact artifact, CallContext context) {
         log.debug("SQMeasurementFacet.getData");
 
-        if (artifact instanceof FLYSArtifact) {
-            FLYSArtifact flys = (FLYSArtifact) artifact;
-
-            CalculationResult res = (CalculationResult) flys.compute(
-                context, ComputeType.ADVANCE, false);
-
-            SQResult[]       result  = (SQResult[]) res.getData();
-            SQFractionResult fResult = result[index].getFraction(fractionIdx);
-
-            return fResult.getMeasurements();
+        if (!(artifact instanceof FLYSArtifact)) {
+            return null;
         }
 
-        return null;
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(
+            context, ComputeType.ADVANCE, false);
+
+        SQResult[]       result  = (SQResult[]) res.getData();
+        SQFractionResult fResult = result[index].getFraction(fractionIdx);
+
+        return fResult.getMeasurements();
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierCurveFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,102 @@
+package de.intevation.flys.artifacts.model.sq;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.math.fitting.Function;
+import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.Parameters;
+
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+import org.apache.log4j.Logger;
+
+public class SQOutlierCurveFacet
+extends      DataFacet
+implements   FacetTypes
+{
+    private static final Logger log =
+        Logger.getLogger(SQOutlierCurveFacet.class);
+
+    public static final String FUNCTION = "sq-pow";
+
+    public static final int BITMASK_ITERATION = (1 << 16) - 1;
+
+    private int fractionIdx;
+
+    public SQOutlierCurveFacet() {
+    }
+
+    public SQOutlierCurveFacet(
+        int    idx,
+        int    fractionIdx,
+        String name,
+        String description,
+        String hash,
+        String stateId
+    ) {
+        super(idx, name, description, ComputeType.ADVANCE, hash, stateId);
+        this.fractionIdx = fractionIdx;
+    }
+
+
+    @Override
+    public Object getData(Artifact artifact, CallContext context) {
+        log.debug("SQOutlierCurveFacet.getData");
+
+        if (!(artifact instanceof FLYSArtifact)) {
+            return null;
+        }
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(
+            context, ComputeType.ADVANCE, false);
+
+        int idx  = this.index >> 16;
+        int iter = this.index & BITMASK_ITERATION;
+
+        SQResult[]       results = (SQResult[]) res.getData();
+        SQFractionResult result  = results[idx].getFraction(fractionIdx);
+
+        Parameters params = result.getParameters(iter);
+
+        if (params == null) {
+            return null;
+        }
+
+        Function func = FunctionFactory.getInstance().getFunction(FUNCTION);
+        String [] paramNames = func.getParameterNames();
+
+        double [] coeffs = params.get(0, paramNames);
+
+        if (log.isDebugEnabled()) {
+            for (int i = 0; i < paramNames.length; i++) {
+                log.debug("retrieved parameter " + paramNames[i] +
+                          " = " + coeffs[i]);
+            }
+        }
+
+        de.intevation.flys.artifacts.math.Function mf =
+            func.instantiate(coeffs);
+
+        double [] extent = result.getQExtent();
+        return new SQFunction(mf, extent[0], extent[1]);
+    }
+
+    @Override
+    public Facet deepCopy() {
+        SQOutlierCurveFacet copy = new SQOutlierCurveFacet();
+        copy.set(this);
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierFacet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,17 +1,17 @@
 package de.intevation.flys.artifacts.model.sq;
 
-import org.apache.log4j.Logger;
-
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
+
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
 
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
 
+import org.apache.log4j.Logger;
 
 /**
  * Facet to show the curve in a sq relation.
@@ -24,14 +24,11 @@
 
     public static final int BITMASK_ITERATION = (1 << 16) - 1;
 
-
     private int fractionIdx;
 
-
     public SQOutlierFacet() {
     }
 
-
     public SQOutlierFacet(
         int    idx,
         int    fractionIdx,
@@ -49,39 +46,43 @@
     public Object getData(Artifact artifact, CallContext context) {
         log.debug("SQOutlierFacet.getData");
 
-        if (artifact instanceof FLYSArtifact) {
-            FLYSArtifact flys = (FLYSArtifact) artifact;
-
-            CalculationResult res = (CalculationResult) flys.compute(
-                context, ComputeType.ADVANCE, false);
-
-            int idx  = this.index >> 16;
-            int iter = this.index & BITMASK_ITERATION;
-
-            if (log.isDebugEnabled()) {
-                log.debug("Fetch data for index : " + this.index);
-                log.debug("  > index:       " + idx);
-                log.debug("  > fraction:    " + fractionIdx);
-                log.debug("  > iteration:   " + iter);
-            }
-
-            SQResult[]       result  = (SQResult[]) res.getData();
-            SQFractionResult fResult = result[idx].getFraction(fractionIdx);
-
-            if (fResult == null) {
-                log.warn("No SQFractionResult at " + idx + "|" + fractionIdx);
-            }
-            else if (log.isDebugEnabled()) {
-                SQ[] outliers = fResult.getOutliers(iter);
-                int  num      = outliers != null ? outliers.length : 0;
-
-                log.debug("Found " + num + " outliers for iteration " + iter);
-            }
-
-            return fResult.getOutliers(iter);
+        if (!(artifact instanceof FLYSArtifact)) {
+            return null;
         }
 
-        return null;
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(
+            context, ComputeType.ADVANCE, false);
+
+        int idx  = this.index >> 16;
+        int iter = this.index & BITMASK_ITERATION;
+
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug("Fetch data for index : " + this.index);
+            log.debug("  > index:       " + idx);
+            log.debug("  > fraction:    " + fractionIdx);
+            log.debug("  > iteration:   " + iter);
+        }
+
+        SQResult[]       result  = (SQResult[]) res.getData();
+        SQFractionResult fResult = result[idx].getFraction(fractionIdx);
+
+        if (fResult == null) {
+            log.warn("No SQFractionResult at " + idx + "|" + fractionIdx);
+            return null;
+        }
+
+        SQ [] outliers = fResult.getOutliers(iter);
+
+        if (debug) {
+            int num = outliers != null ? outliers.length : 0;
+            log.debug("Found " + num + " outliers for iteration " + iter);
+        }
+
+        return outliers;
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQOutlierMeasurementFacet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,73 @@
+package de.intevation.flys.artifacts.model.sq;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+import org.apache.log4j.Logger;
+
+public class SQOutlierMeasurementFacet
+extends      DataFacet
+implements   FacetTypes
+{
+    private static final Logger log =
+        Logger.getLogger(SQOutlierMeasurementFacet.class);
+
+    private int fractionIdx;
+
+    public static final int BITMASK_ITERATION = (1 << 16) - 1;
+
+    public SQOutlierMeasurementFacet() {
+    }
+
+    public SQOutlierMeasurementFacet(
+        int    idx,
+        int    fractionIdx,
+        String name,
+        String description,
+        String hash,
+        String stateId
+    ) {
+        super(idx, name, description, ComputeType.ADVANCE, hash, stateId);
+        this.fractionIdx = fractionIdx;
+    }
+
+    @Override
+    public Object getData(Artifact artifact, CallContext context) {
+        log.debug("SQOutlierMeasurementFacet.getData");
+
+        if (!(artifact instanceof FLYSArtifact)) {
+            return null;
+        }
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(
+            context, ComputeType.ADVANCE, false);
+
+        int idx  = this.index >> 16;
+        int iter = this.index & BITMASK_ITERATION;
+
+        SQResult[]       result  = (SQResult[]) res.getData();
+        SQFractionResult fResult = result[idx].getFraction(fractionIdx);
+
+        return fResult.getMeasurements(iter);
+    }
+
+    @Override
+    public Facet deepCopy() {
+        SQOutlierMeasurementFacet copy = new SQOutlierMeasurementFacet();
+        copy.set(this);
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -24,20 +24,22 @@
 
     public static final String SQ_FUNCTION_NAME = "sq-pow";
 
-    protected String       river;
-    protected double       location;
-    protected DateRange [] periods;
-    protected double       outliers;
+    protected String    river;
+    protected double    location;
+    protected DateRange period;
+    protected double    outliers;
 
     public SQRelationCalculation() {
     }
 
     public SQRelationCalculation(SQRelationAccess access) {
 
-        String       river    = access.getRiver();
-        Double       location = access.getLocation();
-        DateRange [] periods  = access.getPeriods();
-        Double       outliers = access.getOutliers();
+        String    river    = access.getRiver();
+        Double    location = access.getLocation();
+        DateRange period   = access.getPeriod();
+        Double    outliers = access.getOutliers();
+
+        //river = "Rhein";
 
         if (river == null) {
             // TODO: i18n
@@ -49,7 +51,7 @@
             addProblem("sq.missing.location");
         }
 
-        if (periods == null || periods.length == 0) {
+        if (period == null) {
             // TODO: i18n
             addProblem("sq.missing.periods");
         }
@@ -62,7 +64,7 @@
         if (!hasProblems()) {
             this.river    = river;
             this.location = location;
-            this.periods  = periods;
+            this.period   = period;
             this.outliers = outliers;
         }
     }
@@ -98,67 +100,90 @@
             addProblem("sq.missing.sq.function");
         }
 
-
         String [] parameterNames = function.getParameterNames();
 
-        List<SQResult> results = new ArrayList<SQResult>(periods.length);
-
-        Fitting fitting = new Fitting(function, outliers);
+        Measurements measurements =
+            MeasurementFactory.getMeasurements(river, location, period);
 
-        for (DateRange period: periods) {
-            Measurements measurements =
-                MeasurementFactory.getMeasurements(river, location, period);
+        SQFractionResult [] fractionResults =
+            new SQFractionResult[SQResult.NUMBER_FRACTIONS];
 
-            if (debug) {
-                log.debug(measurements.toString());
+        for (int i = 0; i < fractionResults.length; ++i) {
+            List<SQ> sqs = measurements.getSQs(i);
+
+            SQFractionResult fractionResult;
+
+            List<SQFractionResult.Iteration> iterations =
+                doFitting(function, sqs);
+
+            if (iterations == null) {
+                // TODO: i18n
+                addProblem("sq.fitting.failed." + i);
+                fractionResult = new SQFractionResult();
+            }
+            else {
+                fractionResult = new SQFractionResult(
+                    sqs.toArray(new SQ[sqs.size()]),
+                    iterations);
             }
 
-            SQFractionResult [] fractionResults =
-                new SQFractionResult[SQResult.NUMBER_FRACTIONS];
-
-            for (int i = 0; i < fractionResults.length; ++i) {
-                List<SQ> sqs = measurements.getSQs(i);
-
-                SQFractionResult fractionResult;
-
-                if (!fitting.fit(sqs)) {
-                    // TODO: i18n
-                    addProblem("sq.fitting.failed." + i);
-                    fractionResult = new SQFractionResult();
-                }
-                else {
-                    Parameters parameters = createParameters(parameterNames);
-                    int row = parameters.newRow();
-                    double [] coeffs = fitting.getParameters();
-                    for (int j = 0; j < parameterNames.length; ++j) {
-                        parameters.set(row, parameterNames[j], coeffs[j]);
-                    }
-                    parameters.set(row, "chi_sqr", fitting.getChiSqr());
-                    parameters.set(row, "std_dev", fitting.getStandardDeviation());
-
-                    fractionResult = new SQFractionResult(
-                        parameters,
-                        fitting.getRemaining(),
-                        fitting.getOutliers());
-                }
-                fitting.reset();
-                fractionResults[i] = fractionResult;
-            }
-            results.add(new SQResult(fractionResults));
+            fractionResults[i] = fractionResult;
         }
 
         return new CalculationResult(
-            results.toArray(new SQResult[results.size()]), 
+            new SQResult[] { new SQResult(location, fractionResults) },
             this);
     }
 
-    public static final Parameters createParameters(String [] names) {
+    protected List<SQFractionResult.Iteration> doFitting(
+        final Function function,
+        List<SQ> sqs
+    ) {
+        final List<SQFractionResult.Iteration> iterations =
+            new ArrayList<SQFractionResult.Iteration>();
 
+        boolean success = new Fitting(function, outliers).fit(
+            sqs,
+            new Fitting.Callback() {
+                @Override
+                public void afterIteration(
+                    double [] coeffs,
+                    SQ []     measurements,
+                    SQ []     outliers,
+                    double    standardDeviation,
+                    double    chiSqr
+                ) {
+                    Parameters parameters = createParameters(
+                        function.getParameterNames(),
+                        coeffs,
+                        standardDeviation,
+                        chiSqr);
+                    iterations.add(new SQFractionResult.Iteration(
+                        parameters,
+                        measurements,
+                        outliers));
+                }
+            });
+
+        return success ? iterations : null;
+    }
+
+    public static final Parameters createParameters(
+        String [] names,
+        double [] values,
+        double    standardDeviation,
+        double    chiSqr
+    ) {
         String [] columns = new String[names.length + 2];
         columns[0] = "chi_sqr";
         columns[1] = "std_dev";
         System.arraycopy(names, 0, columns, 2, names.length);
-        return new Parameters(columns);
+        Parameters parameters = new Parameters(columns);
+        int row = parameters.newRow();
+        parameters.set(row, names, values);
+        parameters.set(row, "chi_sqr", chiSqr);
+        parameters.set(row, "std_dev", standardDeviation);
+        return parameters;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQResult.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQResult.java	Fri Sep 28 12:15:40 2012 +0200
@@ -15,13 +15,15 @@
     public static final int FRACTION_E = 4;
     public static final int FRACTION_F = 5;
 
+    protected double km;
     protected SQFractionResult[] fractions;
 
     public SQResult() {
-        this(new SQFractionResult[NUMBER_FRACTIONS]);
+        this(0d, new SQFractionResult[NUMBER_FRACTIONS]);
     }
 
-    public SQResult(SQFractionResult [] fractions) {
+    public SQResult(double km, SQFractionResult [] fractions) {
+        this.km        = km;
         this.fractions = fractions;
     }
 
@@ -36,5 +38,23 @@
             this.fractions[idx] = fraction;
         }
     }
+
+    public static final String [] FRACTION_NAMES = {
+        "A", "B", "C", "D", "E", "F"
+    };
+
+    public String getFractionName(int idx) {
+        return idx >= 0 && idx < FRACTION_NAMES.length
+            ? FRACTION_NAMES[idx]
+            : "";
+    }
+
+    public double getKm() {
+        return km;
+    }
+
+    public void setKm(double km) {
+        this.km = km;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/resources/Resources.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/resources/Resources.java	Fri Sep 28 12:15:40 2012 +0200
@@ -85,7 +85,6 @@
      * @return the translated message.
      */
     public static String getMsg(CallMeta meta, String key, String def) {
-
         ensureInstance();
 
         Locale[] locales = INSTANCE.getLocales();
@@ -95,10 +94,10 @@
     }
 
     public static String getMsg(
-        CallMeta meta,
-        String   key,
-        Object[] args
-    ) {
+            CallMeta meta,
+            String   key,
+            Object[] args
+            ) {
         return getMsg(meta, key, key, args);
     }
 
@@ -114,10 +113,10 @@
      * @return a translated string.
      */
     public static String getMsg(
-        CallMeta meta,
-        String   key,
-        String   def,
-        Object[] args)
+            CallMeta meta,
+            String   key,
+            String   def,
+            Object[] args)
     {
         String template = getMsg(meta, key, (String)null);
 
@@ -125,22 +124,33 @@
             return def;
         }
 
-        return MessageFormat.format(template, args);
+        return format(meta, template, args);
     }
 
     public static String format(
-        CallMeta   meta,
-        String     key,
-        String     def,
-        Object ... args
-    ) {
+            CallMeta   meta,
+            String     key,
+            String     def,
+            Object ... args
+            ) {
         String template = getMsg(meta, key, (String)null);
 
         if (template == null) {
-            return template = def;
+            template = def;
         }
 
-        return MessageFormat.format(template, args);
+        return format(meta, template, args);
+    }
+
+    /**
+     * Formats the given template using the arguments with respect of the
+     * appropriate locale given by the CallMeta instance.
+     */
+    public static String format(CallMeta meta, String templ, Object ... args) {
+        Locale locale = getLocale(meta);
+        MessageFormat mf = new MessageFormat(templ, locale);
+
+        return mf.format(args, new StringBuffer(), null).toString();
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/BedKMChartService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,305 @@
+package de.intevation.flys.artifacts.services;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.DateAxis;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifactdatabase.DefaultService;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.GlobalContext;
+import de.intevation.artifacts.Service;
+import de.intevation.flys.artifacts.model.minfo.BedOverview;
+import de.intevation.flys.artifacts.model.minfo.BedOverviewFactory;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.backend.SedDBSessionHolder;
+import de.intevation.flys.utils.KMIndex;
+
+public class BedKMChartService extends DefaultService {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -4946194087923870485L;
+
+    private static final Logger log =
+        Logger.getLogger(BedKMChartService.class);
+
+    public static final int DEFAULT_WIDTH  = 240;
+    public static final int DEFAULT_HEIGHT = 180;
+
+    public static final String I18N_CHART_LABEL =
+        "bed.km.chart.label";
+
+    public static final String DEFAULT_CHART_LABEL =
+        "Measuring Points";
+
+    public static final String I18N_CHART_TITLE =
+        "bed.km.chart.title";
+
+    public static final String DEFAULT_CHART_TITLE =
+        "Measuring points";
+
+    public static final String I18N_KM_AXIS =
+        "bed.km.chart.km.axis";
+
+    public static final String DEFAULT_KM_AXIS =
+        "km";
+
+    public static final String I18N_DATE_AXIS =
+        "bed.km.chart.date.axis";
+
+    public static final String DEFAULT_DATE_AXIS =
+        "Date";
+
+    public static final String DEFAULT_FORMAT = "png";
+
+    // TODO: Load fancy image from resources.
+    public static final byte [] EMPTY = {
+        (byte)0x89, (byte)0x50, (byte)0x4e, (byte)0x47,
+        (byte)0x0d, (byte)0x0a, (byte)0x1a, (byte)0x0a,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0d,
+        (byte)0x49, (byte)0x48, (byte)0x44, (byte)0x52,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+        (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x3a, (byte)0x7e, (byte)0x9b,
+        (byte)0x55, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x01, (byte)0x73, (byte)0x52, (byte)0x47,
+        (byte)0x42, (byte)0x00, (byte)0xae, (byte)0xce,
+        (byte)0x1c, (byte)0xe9, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x09, (byte)0x70, (byte)0x48,
+        (byte)0x59, (byte)0x73, (byte)0x00, (byte)0x00,
+        (byte)0x0b, (byte)0x13, (byte)0x00, (byte)0x00,
+        (byte)0x0b, (byte)0x13, (byte)0x01, (byte)0x00,
+        (byte)0x9a, (byte)0x9c, (byte)0x18, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x07, (byte)0x74,
+        (byte)0x49, (byte)0x4d, (byte)0x45, (byte)0x07,
+        (byte)0xdc, (byte)0x04, (byte)0x04, (byte)0x10,
+        (byte)0x30, (byte)0x15, (byte)0x7d, (byte)0x77,
+        (byte)0x36, (byte)0x0b, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x08, (byte)0x74, (byte)0x45,
+        (byte)0x58, (byte)0x74, (byte)0x43, (byte)0x6f,
+        (byte)0x6d, (byte)0x6d, (byte)0x65, (byte)0x6e,
+        (byte)0x74, (byte)0x00, (byte)0xf6, (byte)0xcc,
+        (byte)0x96, (byte)0xbf, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x0a, (byte)0x49, (byte)0x44,
+        (byte)0x41, (byte)0x54, (byte)0x08, (byte)0xd7,
+        (byte)0x63, (byte)0xf8, (byte)0x0f, (byte)0x00,
+        (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x00,
+        (byte)0x1b, (byte)0xb6, (byte)0xee, (byte)0x56,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x49, (byte)0x45, (byte)0x4e, (byte)0x44,
+        (byte)0xae, (byte)0x42, (byte)0x60, (byte)0x82
+    };
+
+    private static final Output empty() {
+        return new Output(EMPTY, "image/png");
+    }
+
+    @Override
+    public Service.Output process(
+        Document      data,
+        GlobalContext globalContext,
+        CallMeta      callMeta
+    ) {
+        log.debug("SQKMChartService.process");
+
+        SedDBSessionHolder.acquire();
+        try {
+            return doProcess(data, globalContext, callMeta);
+        }
+        finally {
+            SedDBSessionHolder.HOLDER.get().close();
+            SedDBSessionHolder.release();
+        }
+    }
+
+    protected Service.Output doProcess(
+        Document      input,
+        GlobalContext globalContext,
+        CallMeta      callMeta
+    ) {
+        String    river  = getRiverName(input);
+        Dimension extent = getExtent(input);
+        String    format = getFormat(input);
+
+        if (river == null) {
+            log.warn("River invalid.");
+            return empty();
+        }
+
+        BedOverview overview = BedOverviewFactory.getOverview(river);
+
+        if (overview == null) {
+            log.warn("No overview found for river '" + river + "'");
+            return empty();
+        }
+
+        KMIndex<List<Date>> entries = overview.filter(BedOverview.ACCEPT);
+
+        JFreeChart chart = createChart(entries, river, callMeta);
+
+        return encode(chart, extent, format);
+    }
+
+    protected static Output encode(
+        JFreeChart chart,
+        Dimension  extent,
+        String     format
+    ) {
+        BufferedImage image = chart.createBufferedImage(
+            extent.width, extent.height,
+            Transparency.BITMASK,
+            null);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        try {
+            ImageIO.write(image, format, out);
+        }
+        catch (IOException ioe) {
+            log.warn("writing image failed", ioe);
+            return empty();
+        }
+
+        return new Output(out.toByteArray(), "image/" + format);
+    }
+
+    protected static JFreeChart createChart(
+        KMIndex<List<Date>> entries,
+        String      river,
+        CallMeta    callMeta
+    ) {
+
+        XYSeriesCollection dataset = new XYSeriesCollection();
+        String key = Resources.format(
+            callMeta, I18N_CHART_LABEL, DEFAULT_CHART_LABEL, river);
+
+        XYSeries series = new XYSeries(key);
+        for (KMIndex.Entry<List<Date>> e: entries) {
+            double km = e.getKm();
+            List<Date> ds = e.getValue();
+            for (Date d: ds) {
+                series.add(km, d.getTime());
+            }
+        }
+
+        dataset.addSeries(series);
+        String title = Resources.format(
+            callMeta, I18N_CHART_TITLE, DEFAULT_CHART_TITLE, river);
+
+        String kmAxis = Resources.getMsg(
+            callMeta, I18N_KM_AXIS, DEFAULT_KM_AXIS);
+
+        String dateAxis = Resources.getMsg(
+            callMeta, I18N_DATE_AXIS, DEFAULT_DATE_AXIS);
+
+        JFreeChart chart = ChartFactory.createXYLineChart(
+            title,
+            kmAxis,
+            dateAxis,
+            null,
+            PlotOrientation.VERTICAL,
+            true,
+            true,
+            false);
+
+        XYPlot plot = (XYPlot)chart.getPlot();
+
+        DateAxis dA = new DateAxis();
+        plot.setRangeAxis(dA);
+        plot.setDataset(0, dataset);
+
+        chart.setBackgroundPaint(Color.white);
+        plot.setBackgroundPaint(Color.white);
+        plot.setDomainGridlinePaint(Color.gray);
+        plot.setRangeGridlinePaint(Color.gray);
+        plot.setDomainGridlinesVisible(true);
+        plot.setRangeGridlinesVisible(true);
+        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
+
+        renderer.setSeriesPaint(0, Color.gray);
+        renderer.setSeriesLinesVisible(0, false);
+        renderer.setSeriesShapesVisible(0, true);
+        renderer.setDrawOutlines(true);
+        return chart;
+    }
+
+
+    protected static String getRiverName(Document input) {
+        NodeList rivers = input.getElementsByTagName("river");
+
+        if (rivers.getLength() == 0) {
+            return null;
+        }
+
+        String river = ((Element)rivers.item(0)).getAttribute("name");
+
+        return river.length() > 0 ? river : null;
+    }
+
+    protected static Dimension getExtent(Document input) {
+
+        int width  = DEFAULT_WIDTH;
+        int height = DEFAULT_HEIGHT;
+
+        NodeList extents = input.getElementsByTagName("extent");
+
+        if (extents.getLength() > 0) {
+            Element element = (Element)extents.item(0);
+            String w = element.getAttribute("width");
+            String h = element.getAttribute("height");
+
+            try {
+                width = Math.max(1, Integer.parseInt(w));
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("width '" + w + "' is not a valid.");
+            }
+
+            try {
+                height = Math.max(1, Integer.parseInt(h));
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("height '" + h + "' is not a valid");
+            }
+        }
+
+        return new Dimension(width, height);
+    }
+
+    protected static String getFormat(Document input) {
+        String format = DEFAULT_FORMAT;
+
+        NodeList formats = input.getElementsByTagName("format");
+
+        if (formats.getLength() > 0) {
+            String type = ((Element)formats.item(0)).getAttribute("type");
+            if (type.length() > 0) {
+                format = type;
+            }
+        }
+
+        return format;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/BedloadKMChartService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,305 @@
+package de.intevation.flys.artifacts.services;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.DateAxis;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifactdatabase.DefaultService;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.GlobalContext;
+import de.intevation.artifacts.Service;
+import de.intevation.flys.artifacts.model.minfo.BedloadOverview;
+import de.intevation.flys.artifacts.model.minfo.BedloadOverviewFactory;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.backend.SedDBSessionHolder;
+import de.intevation.flys.utils.KMIndex;
+
+public class BedloadKMChartService extends DefaultService {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4156704841305086495L;
+
+    private static final Logger log =
+        Logger.getLogger(BedloadKMChartService.class);
+
+    public static final int DEFAULT_WIDTH  = 240;
+    public static final int DEFAULT_HEIGHT = 180;
+
+    public static final String I18N_CHART_LABEL =
+        "bedload.km.chart.label";
+
+    public static final String DEFAULT_CHART_LABEL =
+        "Measuring Points";
+
+    public static final String I18N_CHART_TITLE =
+        "bedload.km.chart.title";
+
+    public static final String DEFAULT_CHART_TITLE =
+        "Measuring points";
+
+    public static final String I18N_KM_AXIS =
+        "bedload.km.chart.km.axis";
+
+    public static final String DEFAULT_KM_AXIS =
+        "km";
+
+    public static final String I18N_DATE_AXIS =
+        "bedload.km.chart.date.axis";
+
+    public static final String DEFAULT_DATE_AXIS =
+        "Date";
+
+    public static final String DEFAULT_FORMAT = "png";
+
+    // TODO: Load fancy image from resources.
+    public static final byte [] EMPTY = {
+        (byte)0x89, (byte)0x50, (byte)0x4e, (byte)0x47,
+        (byte)0x0d, (byte)0x0a, (byte)0x1a, (byte)0x0a,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0d,
+        (byte)0x49, (byte)0x48, (byte)0x44, (byte)0x52,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
+        (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x3a, (byte)0x7e, (byte)0x9b,
+        (byte)0x55, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x01, (byte)0x73, (byte)0x52, (byte)0x47,
+        (byte)0x42, (byte)0x00, (byte)0xae, (byte)0xce,
+        (byte)0x1c, (byte)0xe9, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x09, (byte)0x70, (byte)0x48,
+        (byte)0x59, (byte)0x73, (byte)0x00, (byte)0x00,
+        (byte)0x0b, (byte)0x13, (byte)0x00, (byte)0x00,
+        (byte)0x0b, (byte)0x13, (byte)0x01, (byte)0x00,
+        (byte)0x9a, (byte)0x9c, (byte)0x18, (byte)0x00,
+        (byte)0x00, (byte)0x00, (byte)0x07, (byte)0x74,
+        (byte)0x49, (byte)0x4d, (byte)0x45, (byte)0x07,
+        (byte)0xdc, (byte)0x04, (byte)0x04, (byte)0x10,
+        (byte)0x30, (byte)0x15, (byte)0x7d, (byte)0x77,
+        (byte)0x36, (byte)0x0b, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x08, (byte)0x74, (byte)0x45,
+        (byte)0x58, (byte)0x74, (byte)0x43, (byte)0x6f,
+        (byte)0x6d, (byte)0x6d, (byte)0x65, (byte)0x6e,
+        (byte)0x74, (byte)0x00, (byte)0xf6, (byte)0xcc,
+        (byte)0x96, (byte)0xbf, (byte)0x00, (byte)0x00,
+        (byte)0x00, (byte)0x0a, (byte)0x49, (byte)0x44,
+        (byte)0x41, (byte)0x54, (byte)0x08, (byte)0xd7,
+        (byte)0x63, (byte)0xf8, (byte)0x0f, (byte)0x00,
+        (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x00,
+        (byte)0x1b, (byte)0xb6, (byte)0xee, (byte)0x56,
+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        (byte)0x49, (byte)0x45, (byte)0x4e, (byte)0x44,
+        (byte)0xae, (byte)0x42, (byte)0x60, (byte)0x82
+    };
+
+    private static final Output empty() {
+        return new Output(EMPTY, "image/png");
+    }
+
+    @Override
+    public Service.Output process(
+        Document      data,
+        GlobalContext globalContext,
+        CallMeta      callMeta
+    ) {
+        log.debug("SQKMChartService.process");
+
+        SedDBSessionHolder.acquire();
+        try {
+            return doProcess(data, globalContext, callMeta);
+        }
+        finally {
+            SedDBSessionHolder.HOLDER.get().close();
+            SedDBSessionHolder.release();
+        }
+    }
+
+    protected Service.Output doProcess(
+        Document      input,
+        GlobalContext globalContext,
+        CallMeta      callMeta
+    ) {
+        String    river  = getRiverName(input);
+        Dimension extent = getExtent(input);
+        String    format = getFormat(input);
+
+        if (river == null) {
+            log.warn("River invalid.");
+            return empty();
+        }
+
+        BedloadOverview overview = BedloadOverviewFactory.getOverview(river);
+
+        if (overview == null) {
+            log.warn("No overview found for river '" + river + "'");
+            return empty();
+        }
+
+        KMIndex<List<Date>> entries = overview.filter(BedloadOverview.ACCEPT);
+
+        JFreeChart chart = createChart(entries, river, callMeta);
+
+        return encode(chart, extent, format);
+    }
+
+    protected static Output encode(
+        JFreeChart chart,
+        Dimension  extent,
+        String     format
+    ) {
+        BufferedImage image = chart.createBufferedImage(
+            extent.width, extent.height,
+            Transparency.BITMASK,
+            null);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        try {
+            ImageIO.write(image, format, out);
+        }
+        catch (IOException ioe) {
+            log.warn("writing image failed", ioe);
+            return empty();
+        }
+
+        return new Output(out.toByteArray(), "image/" + format);
+    }
+
+    protected static JFreeChart createChart(
+        KMIndex<List<Date>> entries,
+        String      river,
+        CallMeta    callMeta
+    ) {
+
+        XYSeriesCollection dataset = new XYSeriesCollection();
+        String key = Resources.format(
+            callMeta, I18N_CHART_LABEL, DEFAULT_CHART_LABEL, river);
+
+        XYSeries series = new XYSeries(key);
+        for (KMIndex.Entry<List<Date>> e: entries) {
+            double km = e.getKm();
+            List<Date> ds = e.getValue();
+            for (Date d: ds) {
+                series.add(km, d.getTime());
+            }
+        }
+
+        dataset.addSeries(series);
+        String title = Resources.format(
+            callMeta, I18N_CHART_TITLE, DEFAULT_CHART_TITLE, river);
+
+        String kmAxis = Resources.getMsg(
+            callMeta, I18N_KM_AXIS, DEFAULT_KM_AXIS);
+
+        String dateAxis = Resources.getMsg(
+            callMeta, I18N_DATE_AXIS, DEFAULT_DATE_AXIS);
+
+        JFreeChart chart = ChartFactory.createXYLineChart(
+            title,
+            kmAxis,
+            dateAxis,
+            null,
+            PlotOrientation.VERTICAL,
+            true,
+            true,
+            false);
+
+        XYPlot plot = (XYPlot)chart.getPlot();
+
+        DateAxis dA = new DateAxis();
+        plot.setRangeAxis(dA);
+        plot.setDataset(0, dataset);
+
+        chart.setBackgroundPaint(Color.white);
+        plot.setBackgroundPaint(Color.white);
+        plot.setDomainGridlinePaint(Color.gray);
+        plot.setRangeGridlinePaint(Color.gray);
+        plot.setDomainGridlinesVisible(true);
+        plot.setRangeGridlinesVisible(true);
+        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
+
+        renderer.setSeriesPaint(0, Color.gray);
+        renderer.setSeriesLinesVisible(0, false);
+        renderer.setSeriesShapesVisible(0, true);
+        renderer.setDrawOutlines(true);
+        return chart;
+    }
+
+
+    protected static String getRiverName(Document input) {
+        NodeList rivers = input.getElementsByTagName("river");
+
+        if (rivers.getLength() == 0) {
+            return null;
+        }
+
+        String river = ((Element)rivers.item(0)).getAttribute("name");
+
+        return river.length() > 0 ? river : null;
+    }
+
+    protected static Dimension getExtent(Document input) {
+
+        int width  = DEFAULT_WIDTH;
+        int height = DEFAULT_HEIGHT;
+
+        NodeList extents = input.getElementsByTagName("extent");
+
+        if (extents.getLength() > 0) {
+            Element element = (Element)extents.item(0);
+            String w = element.getAttribute("width");
+            String h = element.getAttribute("height");
+
+            try {
+                width = Math.max(1, Integer.parseInt(w));
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("width '" + w + "' is not a valid.");
+            }
+
+            try {
+                height = Math.max(1, Integer.parseInt(h));
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("height '" + h + "' is not a valid");
+            }
+        }
+
+        return new Dimension(width, height);
+    }
+
+    protected static String getFormat(Document input) {
+        String format = DEFAULT_FORMAT;
+
+        NodeList formats = input.getElementsByTagName("format");
+
+        if (formats.getLength() > 0) {
+            String type = ((Element)formats.item(0)).getAttribute("type");
+            if (type.length() > 0) {
+                format = type;
+            }
+        }
+
+        return format;
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/FixingsKMChartService.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/FixingsKMChartService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -18,7 +18,7 @@
 import de.intevation.flys.artifacts.model.GaugeFinderFactory;
 import de.intevation.flys.artifacts.model.GaugeRange;
 
-import de.intevation.flys.artifacts.model.fixings.QW;
+import de.intevation.flys.artifacts.model.fixings.QWI;
 
 import de.intevation.flys.artifacts.resources.Resources;
 
@@ -68,6 +68,8 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
+
+/** Serve chart of Fixings at certain km. */
 public class FixingsKMChartService
 extends      DefaultService
 {
@@ -274,11 +276,11 @@
             boolean interpolated = !col.getB().getW(km, w);
             double q = col.getB().getQ(km);
             if (!Double.isNaN(w[0]) && !Double.isNaN(q)) {
-                QW qw = new QW(
+                QWI qw = new QWI(
                     q, w[0],
                     col.getA().getDescription(),
                     col.getA().getStartTime(),
-                    interpolated);
+                    interpolated, 0);
                 dataset.add(qw);
             }
         }
@@ -352,6 +354,7 @@
         return chart;
     }
 
+    /** Add domain markers to plot that indicate Q-sectors. */
     protected static void applyQSectorMarkers(
         XYPlot   plot,
         String   river,
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/GaugeInfoService.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/GaugeInfoService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -32,7 +32,7 @@
     }
 
 
-    protected class ReferenceNumberFilter implements Filter {
+    private static final class ReferenceNumberFilter implements Filter {
         private long refNr;
 
         public ReferenceNumberFilter(long refNr) {
@@ -41,14 +41,11 @@
 
         @Override
         public boolean apply(Gauge  gauge) {
-            logger.debug("Test gauge '" + gauge.getName() + "'");
+            if (logger.isDebugEnabled()) {
+                logger.debug("Test gauge '" + gauge.getName() + "'");
+            }
 
-            if (gauge != null && gauge.getOfficialNumber() == refNr) {
-                return true;
-            }
-            else {
-                return false;
-            }
+            return gauge != null && gauge.getOfficialNumber() == refNr;
         }
     } // end of ReferenceNumberFilter class
 
@@ -75,8 +72,9 @@
     ) {
         logger.debug("GaugeInfoService.process");
 
-        // XXX REMOVE THIS
-        logger.debug(XMLUtils.toString(data));
+        if (logger.isDebugEnabled()) {
+            logger.debug(XMLUtils.toString(data));
+        }
 
         River river = getRiverFromRequest(data);
 
@@ -88,6 +86,7 @@
             for (Filter f: filters) {
                 if (f.apply(g)) {
                     filtered.add(g);
+                    break;
                 }
             }
         }
@@ -118,7 +117,8 @@
 
         if (refNr != null && refNr.length() > 0) {
             try {
-                filters.add(new ReferenceNumberFilter(Long.valueOf(refNr)));
+                filters.add(
+                    new ReferenceNumberFilter(Long.parseLong(refNr)));
             }
             catch (NumberFormatException nfe) {
                 logger.warn(nfe, nfe);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/GaugeOverviewInfoService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,160 @@
+package de.intevation.flys.artifacts.services;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.GlobalContext;
+import de.intevation.artifacts.common.ArtifactNamespaceContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.flys.artifacts.model.RiverFactory;
+import de.intevation.flys.model.Gauge;
+import de.intevation.flys.model.MinMaxWQ;
+import de.intevation.flys.model.Range;
+import de.intevation.flys.model.River;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeOverviewInfoService extends FLYSService {
+
+    private static final Logger logger = Logger.getLogger(
+            GaugeOverviewInfoService.class);
+
+    public static final String RIVER_XPATH = "/art:river/text()";
+
+    @Override
+    public Document doProcess(
+        Document      data,
+        GlobalContext globalContext,
+        CallMeta      callMeta
+    ) {
+        logger.debug("GaugeOverviewInfoService.process");
+
+        String riverstr = XMLUtils.xpathString(
+            data, RIVER_XPATH, ArtifactNamespaceContext.INSTANCE);
+
+        River river = RiverFactory.getRiver(riverstr);
+
+        Document result = XMLUtils.newDocument();
+
+        if (river == null) {
+            logger.warn("No river with name " + riverstr + " found.");
+            return result;
+        }
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            result,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element go = ec.create("gauge-info");
+
+        double[] minmax  = river.determineMinMaxDistance();
+        double[] minmaxq = river.determineMinMaxQ();
+
+        Element r = ec.create("river");
+        ec.addAttr(r, "name", river.getName(), true);
+        ec.addAttr(r, "start", Double.toString(minmax[0]), true);
+        ec.addAttr(r, "end", Double.toString(minmax[1]), true);
+        ec.addAttr(r, "wstunit", river.getWstUnit().getName(), true);
+        ec.addAttr(r, "kmup", Boolean.toString(river.getKmUp()), true);
+        ec.addAttr(r, "minq", Double.toString(minmaxq[0]), true);
+        ec.addAttr(r, "maxq", Double.toString(minmaxq[1]), true);
+        ec.addAttr(r, "official", Long.toString(river.getOfficialNumber()),
+                    true);
+
+        Element egs = ec.create("gauges");
+
+        List<Gauge> gauges = river.getGauges();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Loaded gauges: " + gauges);
+        }
+
+        for (Gauge gauge: river.getGauges()) {
+            Element eg = ec.create("gauge");
+
+            String name = gauge.getName();
+            if (name != null) {
+                ec.addAttr(eg, "name", gauge.getName(), true);
+            }
+
+            String aeo = getGaugeValue(gauge.getAeo());
+            if (aeo != null) {
+                ec.addAttr(eg, "aeo", aeo, true);
+            }
+
+            String datum = getGaugeValue(gauge.getDatum());
+            if (datum != null) {
+                ec.addAttr(eg, "datum", datum, true);
+            }
+
+            Range range = gauge.getRange();
+            if (range != null) {
+                BigDecimal a = range.getA();
+                if (a != null) {
+                    double min = a.doubleValue();
+                    ec.addAttr(eg, "start", Double.toString(min), true);
+                }
+
+                BigDecimal b = range.getB();
+                if (b != null) {
+                    double max = range.getB().doubleValue();
+                    ec.addAttr(eg, "end", Double.toString(max), true);
+                }
+            }
+            MinMaxWQ minmaxwq = gauge.fetchMaxMinWQ();
+            String minw = getGaugeValue(minmaxwq.getMinW());
+            String maxw = getGaugeValue(minmaxwq.getMaxW());
+            String minq = getGaugeValue(minmaxwq.getMinQ());
+            String maxq = getGaugeValue(minmaxwq.getMaxQ());
+
+            if (minw != null) {
+                ec.addAttr(eg, "minw", minw, true);
+            }
+            if (maxw != null) {
+                ec.addAttr(eg, "maxw", maxw, true);
+            }
+            if (minq != null) {
+                ec.addAttr(eg, "minq", minq, true);
+            }
+            if (maxq != null) {
+                ec.addAttr(eg, "maxq", maxq, true);
+            }
+
+            String station = getGaugeValue(gauge.getStation());
+            if (station != null) {
+                ec.addAttr(eg, "station", station, true);
+            }
+
+            Long official = gauge.getOfficialNumber();
+            if (official != null) {
+                ec.addAttr(eg, "official", official.toString(), true);
+            }
+
+            egs.appendChild(eg);
+        }
+
+        go.appendChild(r);
+        go.appendChild(egs);
+        result.appendChild(go);
+
+        return result;
+    }
+
+    /**
+     * Returns a Double from a BigDecimal value or null if value is null
+     */
+    private static String getGaugeValue(BigDecimal value) {
+        return value != null
+            ? Double.toString(value.doubleValue())
+            : "";
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -21,7 +21,6 @@
 import de.intevation.flys.model.Range;
 import de.intevation.flys.model.River;
 
-import de.intevation.flys.artifacts.model.MainValuesFactory;
 import de.intevation.flys.artifacts.model.RiverFactory;
 
 
@@ -52,6 +51,11 @@
     public MainValuesService() {
     }
 
+    private static final Document error(String msg) {
+        logger.debug(msg);
+        return XMLUtils.newDocument();
+    }
+
 
     @Override
     public Document doProcess(
@@ -61,23 +65,21 @@
     ) {
         logger.debug("MainValuesService.process");
 
-        try {
-            River river     = getRequestedRiver(data);
-            double[] minmax = getRequestedStartEnd(data, river);
-            Gauge gauge     = river.determineGauge(minmax[0], minmax[1]);
-
-            logger.debug("Found gauge: " + gauge.getName());
+        River river = getRequestedRiver(data);
+        if (river == null) {
+            return error("no river found.");
+        }
 
-            List<MainValue> mainValues = getMainValues(river, gauge);
+        double[] minmax = getRequestedStartEnd(data, river);
+        Gauge gauge = river.determineGauge(minmax[0], minmax[1]);
 
-            return buildDocument(river, gauge, mainValues, context);
+        if (gauge == null) {
+            return error("no gauge found.");
         }
-        catch (NullPointerException npe) {
-            logger.error("Could not process the request.");
-            logger.error(npe, npe);
 
-            return XMLUtils.newDocument();
-        }
+        List<MainValue> mainValues = getMainValues(river, gauge);
+
+        return buildDocument(river, gauge, mainValues, context);
     }
 
 
@@ -98,17 +100,9 @@
         String riverStr = XMLUtils.xpathString(
             data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE);
 
-        if (riverStr == null || riverStr.trim().length() == 0) {
-            throw new NullPointerException("No river found in the request.");
-        }
-
-        River river = RiverFactory.getRiver(riverStr);
-
-        if (river == null) {
-            throw new NullPointerException("No such river found: " + riverStr);
-        }
-
-        return river;
+         return riverStr != null && (riverStr = riverStr.trim()).length() > 0
+            ? RiverFactory.getRiver(riverStr)
+            : null;
     }
 
 
@@ -132,18 +126,23 @@
         String endStr = XMLUtils.xpathString(
             data, XPATH_END, ArtifactNamespaceContext.INSTANCE);
 
+        if (startStr == null || endStr == null) {
+            return river.determineMinMaxDistance();
+        }
+
         try {
             double start = Double.parseDouble(startStr);
             double end   = Double.parseDouble(endStr);
 
-            logger.debug("Found start: " + start);
-            logger.debug("Found end: " + end);
+            if (logger.isDebugEnabled()) {
+                logger.debug("Found start: " + start);
+                logger.debug("Found end: " + end);
+            }
 
             return new double[] { start, end };
         }
         catch (NumberFormatException nfe) {
             logger.warn(nfe, nfe);
-
             return river.determineMinMaxDistance();
         }
     }
@@ -159,23 +158,20 @@
      * @return a document that includes the main values of the specified river
      * at the specified gauge.
      */
-    protected List<MainValue> getMainValues(River river, Gauge gauge)
-    throws    NullPointerException
-    {
+    protected List<MainValue> getMainValues(River river, Gauge gauge) {
+
         if (logger.isDebugEnabled()) {
             logger.debug("MainValuesService.buildMainValues");
             logger.debug("River: " + river.getName());
             logger.debug("Gauge: " + gauge.getName());
         }
 
-        List<MainValue> mainValues = MainValuesFactory.getMainValues(gauge);
+        List<MainValue> mainValues = gauge.getMainValues();
 
-        if (mainValues == null || mainValues.isEmpty()) {
-            throw new NullPointerException("No main values found.");
+        if (logger.isDebugEnabled()) {
+            logger.debug(mainValues.size() + " main values found.");
         }
 
-        logger.debug(mainValues.size() + " main values found.");
-
         return mainValues;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/ModuleService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,62 @@
+package de.intevation.flys.artifacts.services;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.GlobalContext;
+import de.intevation.artifacts.ArtifactNamespaceContext;
+import de.intevation.flys.artifacts.model.Module;
+import de.intevation.flys.artifacts.context.FLYSContext;
+import de.intevation.flys.artifacts.resources.Resources;
+
+public class ModuleService extends FLYSService {
+
+    private static final String MODULE = "module";
+
+    private static Logger logger = Logger.getLogger(ModuleService.class);
+
+    protected Document doProcess(
+        Document      data,
+        GlobalContext globalContext,
+        CallMeta      callMeta
+    ) {
+        logger.debug("ModuleService.process");
+
+        Document result = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            result,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element em = ec.create("modules");
+        List<Module> modules = (List<Module>)globalContext.get(FLYSContext.MODULES);
+
+        for (Module module : modules) {
+            Element m = ec.create("module");
+            ec.addAttr(m, "name", module.getName(), true);
+            String localname = Resources.getMsg(callMeta,
+                    MODULE + "." + module.getName(), module.getName());
+            ec.addAttr(m, "localname", localname, true);
+
+            if (module.isSelected()) {
+                ec.addAttr(m, "selected", "true", true);
+            }
+
+            em.appendChild(m);
+        }
+
+        result.appendChild(em);
+
+        return result;
+    }
+}
+
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/QWSeriesCollection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/QWSeriesCollection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,6 +1,6 @@
 package de.intevation.flys.artifacts.services;
 
-import de.intevation.flys.artifacts.model.fixings.QW;
+import de.intevation.flys.artifacts.model.fixings.QWI;
 
 import de.intevation.flys.java2d.ShapeUtils;
 
@@ -38,7 +38,7 @@
 implements   XYItemLabelGenerator
 {
     public interface LabelGenerator {
-        String createLabel(QW qw);
+        String createLabel(QWI qw);
     } // interface LabelGenerator
 
     public static class DateFormatLabelGenerator
@@ -59,7 +59,7 @@
         }
 
         @Override
-        public String createLabel(QW qw) {
+        public String createLabel(QWI qw) {
             Date date = qw.getDate();
             return date != null ? format.format(date) : "";
         }
@@ -71,7 +71,7 @@
     protected Date minDate;
     protected Date maxDate;
 
-    protected List<List<QW>> labels;
+    protected List<List<QWI>> labels;
 
     protected Rectangle2D area;
 
@@ -81,7 +81,7 @@
         new HashMap<ShapeRenderer.Entry, Integer>();
 
     public QWSeriesCollection() {
-        labels = new ArrayList<List<QW>>();
+        labels = new ArrayList<List<QWI>>();
         labelGenerator = SIMPLE_GENERATOR;
     }
 
@@ -90,7 +90,7 @@
         this.labelGenerator = labelGenerator;
     }
 
-    protected static ShapeRenderer.Entry classify(QW qw) {
+    protected static ShapeRenderer.Entry classify(QWI qw) {
         boolean interpolated = qw.getInterpolated();
 
         Shape shape = interpolated
@@ -98,14 +98,12 @@
             : ShapeUtils.MEASURED_SHAPE;
 
         boolean filled = !interpolated;
-        Color color = interpolated
-            ? Color.green
-            : Color.blue;
+        Color color = Color.blue;
 
         return new ShapeRenderer.Entry(shape, color, filled);
     }
 
-    public void add(QW qw) {
+    public void add(QWI qw) {
 
         ShapeRenderer.Entry key = classify(qw);
 
@@ -118,7 +116,7 @@
             knownShapes.put(key, seriesNo);
             series = new XYSeries(seriesNo, false);
             addSeries(series);
-            labels.add(new ArrayList<QW>());
+            labels.add(new ArrayList<QWI>());
         }
         else {
             series = getSeries(seriesNo);
@@ -132,7 +130,7 @@
         extendArea(qw);
     }
 
-    protected void extendDateRange(QW qw) {
+    protected void extendDateRange(QWI qw) {
         Date date = qw.getDate();
         if (date != null) {
             if (minDate == null) {
@@ -149,7 +147,7 @@
         }
     }
 
-    protected void extendArea(QW qw) {
+    protected void extendArea(QWI qw) {
         if (area == null) {
             area = new Rectangle2D.Double(
                 qw.getQ(), qw.getW(), 0d, 0d);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DefaultState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DefaultState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,6 @@
 package de.intevation.flys.artifacts.states;
 
 import java.text.NumberFormat;
-import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.List;
@@ -87,11 +86,9 @@
             return ui;
         }
 
-        Iterator<String> iter = theData.keySet().iterator();
-        FLYSArtifact     flys = (FLYSArtifact) artifact;
+        FLYSArtifact flys = (FLYSArtifact)artifact;
 
-        while (iter.hasNext()) {
-            String name = iter.next();
+        for (String name: theData.keySet()) {
             appendStaticData(flys, context, creator, ui, name);
         }
 
@@ -115,9 +112,11 @@
 
         String type = data.getType();
 
-        logger.debug(
-            "Append element " + type + "'" +
-            name + "' (" + value + ")");
+        if (logger.isDebugEnabled()) {
+            logger.debug(
+                "Append element " + type + "'" +
+                name + "' (" + value + ")");
+        }
 
         Element e = createStaticData(flys, cr, context, name, value, type);
 
@@ -183,7 +182,7 @@
         try {
             // XXX A better way to format the output would be to use the
             // 'type' value of the data objects.
-            double doubleVal = Double.valueOf(value);
+            double doubleVal = Double.parseDouble(value);
             Locale         l = Resources.getLocale(meta);
             NumberFormat  nf = NumberFormat.getInstance(l);
 
@@ -195,6 +194,35 @@
     }
 
 
+    /**
+     * This method returns the default value and description for <i>data</i>.
+     * Note, that this method returns the defaults only if <i>USE_DEFAULTS</i>
+     * is set; otherwise, null is returned.
+     * @param context The CallContext used for i18n.
+     * @param data The data objects that the defaults are for.
+     * @return a String[] with [default value, default label].
+     */
+    protected String[] getDefaultsFor(CallContext context, StateData data) {
+        if (USE_DEFAULTS) {
+            String defValue = (String) data.getValue();
+            String defDesc  = null;
+
+            if (defValue != null && defValue.length() > 0) {
+                defDesc = Resources.getMsg(
+                    context.getMeta(),
+                    defValue,
+                    defValue);
+            }
+
+            if (defValue != null && defDesc != null) {
+                return new String[] { defValue, defDesc };
+            }
+        }
+
+        return null;
+    }
+
+
     public Element describe(
         Artifact    artifact,
         Document    document,
@@ -230,32 +258,21 @@
             return ui;
         }
 
-        Iterator<String> iter = theData.keySet().iterator();
-        FLYSArtifact     flys = (FLYSArtifact) artifact;
+        FLYSArtifact flys = (FLYSArtifact)artifact;
 
-        while (iter.hasNext()) {
-            String    name = iter.next();
+        for (String name: theData.keySet()) {
             StateData data = getData(flys, name);
 
-            data = data != null ? data : getData(name);
+            if (data == null) {
+                data = getData(name);
+            }
 
             Element select = createData(creator, artifact, data, context);
 
-            if (USE_DEFAULTS) {
-                String defValue = (String) data.getValue();
-                String defDesc  = null;
-
-                if (defValue != null && defValue.length() > 0) {
-                    defDesc = Resources.getMsg(
-                        context.getMeta(),
-                        defValue,
-                        defValue);
-                }
-
-                if (defValue != null && defDesc != null) {
-                    creator.addAttr(select, "defaultValue", defValue, true);
-                    creator.addAttr(select, "defaultLabel", defDesc, true);
-                }
+            String[] defaults = getDefaultsFor(context, data);
+            if (defaults != null && defaults.length > 1) {
+                creator.addAttr(select, "defaultValue", defaults[0], true);
+                creator.addAttr(select, "defaultLabel", defaults[1], true);
             }
 
             appendItems(artifact, creator, name, context, select);
@@ -389,7 +406,9 @@
         String       name,
         String       val
     ) {
-        logger.debug("Transform data ('" + name + "','" + val + "')");
+        if (logger.isDebugEnabled()) {
+            logger.debug("Transform data ('" + name + "','" + val + "')");
+        }
 
         stateData.setValue(val);
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DischargeState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DischargeState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -18,13 +18,14 @@
 
 public class DischargeState extends MultiIntArrayState {
 
-    public static final String MAIN_CHANNEL  = "main.channel";
-    public static final String TOTAL_CHANNEL = "total.channel";
+    public static final String MAIN_CHANNEL  = "main_channel";
+    public static final String TOTAL_CHANNEL = "total_channel";
 
 
     private static final Logger logger = Logger.getLogger(DischargeState.class);
 
 
+    /** Let client display a matrix. */
     @Override
     public String getUIProvider() {
         return "parameter-matrix";
@@ -99,7 +100,7 @@
         String lo = zone.getLowerDischarge();
         String hi = zone.getUpperDischarge();
 
-        return hi != null && lo.equals(hi)
+        return hi != null && !lo.equals(hi)
             ? lo + " - " + hi
             : lo;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/EnterMultipleLocationsState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/EnterMultipleLocationsState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,16 +1,25 @@
 package de.intevation.flys.artifacts.states;
 
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+
+import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 import de.intevation.artifacts.common.utils.StringUtils;
+import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
+import de.intevation.flys.artifacts.WINFOArtifact;
 
 
 /**
  * Get me doubles (km).
  */
 public class EnterMultipleLocationsState extends EnterLocationState {
+    /** The logger for this class. */
+    private static Logger logger = Logger.getLogger(EnterMultipleLocationsState.class);
 
     @Override
     protected String getUIProvider() {
+        logger.debug("multi location panel");
         return "multi_location_panel";
     }
 
@@ -31,5 +40,34 @@
 
         return StringUtils.join(" ", vals);
     }
+
+    /**
+     * This method creates a list of items. These items represent the amount of
+     * input data that is possible for this state.
+     *
+     * @param cr The ElementCreator.
+     * @param name The name of the amount of data.
+     *
+     * @return a list of items.
+     */
+    @Override
+    protected Element[] createItems(
+        ElementCreator cr,
+        Artifact    artifact,
+        String      name,
+        CallContext context
+    ) {
+        if (name.equals("reference_endpoint")) {
+            Element[] elements = new Element[1];
+            WINFOArtifact winfo = (WINFOArtifact) artifact;
+            Double km = winfo.getReferenceStartKm();
+            elements[0] = createItem(
+                cr,
+                new String[] {"start_km", km.toString()});
+            return elements;
+        }
+        return null;
+    }
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -122,7 +122,7 @@
     ) {
         FLYSArtifact flys  = (FLYSArtifact) owner;
         List<Facet> facets = flys.getFacets();
-        if (facets == null || facets.size() == 0) {
+        if (facets == null || facets.isEmpty()) {
             logger.warn("No facets for '" + OUTPUT_NAME + "' given!");
             return;
         }
@@ -411,7 +411,7 @@
             "barriers", srs, Geometry.class);
 
         List<SimpleFeature> features = GeometryUtils.parseGeoJSON(geoJSON, ft);
-        if (features == null || features.size() == 0) {
+        if (features == null || features.isEmpty()) {
             logger.debug("No barrier features extracted.");
             return;
         }
@@ -604,7 +604,7 @@
         String srs     = "EPSG:" + srid;
 
         List<RiverAxis> axes = RiverAxis.getRiverAxis(river);
-        if (axes == null || axes.size() == 0) {
+        if (axes == null || axes.isEmpty()) {
             logger.warn("Could not find river axis for: '" + river + "'");
             return;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/GaugeTimerangeState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/GaugeTimerangeState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,15 +4,13 @@
 import java.util.List;
 
 import org.apache.log4j.Logger;
-
+import org.hibernate.SQLQuery;
 import org.hibernate.Session;
-import org.hibernate.SQLQuery;
 import org.hibernate.type.StandardBasicTypes;
 
-import de.intevation.flys.model.Gauge;
+import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.backend.SessionHolder;
-
-import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.model.Gauge;
 import de.intevation.flys.utils.FLYSUtils;
 
 
@@ -22,7 +20,7 @@
 public class GaugeTimerangeState extends IntRangeState {
 
     private static final Logger logger =
-        Logger.getLogger(GaugeTimerangeState.class);
+            Logger.getLogger(GaugeTimerangeState.class);
 
 
     protected int[] getLowerUpper(FLYSArtifact flys) {
@@ -36,17 +34,17 @@
         Session session = SessionHolder.HOLDER.get();
 
         SQLQuery query = session.createSQLQuery(
-            "SELECT min(start_time) as min, max(stop_time) as max " +
-            "FROM time_intervals WHERE id in " +
-            "(SELECT time_interval_id FROM discharge_tables " +
-            "WHERE gauge_id =:gid)");
+                "SELECT min(start_time) as min, max(stop_time) as max " +
+                        "FROM time_intervals WHERE id in " +
+                        "(SELECT time_interval_id FROM discharge_tables " +
+                "WHERE gauge_id =:gid)");
 
         query.addScalar("min", StandardBasicTypes.CALENDAR);
         query.addScalar("max", StandardBasicTypes.CALENDAR);
 
         query.setInteger("gid", gauge.getId());
 
-        List results = query.list();
+        List<?> results = query.list();
 
         if (results != null) {
             Object[] res = (Object[]) results.get(0);
@@ -54,7 +52,9 @@
             Calendar lo = (Calendar) res[0];
             Calendar up = (Calendar) res[1];
 
-            return new int[] { lo.get(Calendar.YEAR), up.get(Calendar.YEAR) };
+            if (lo != null && up != null) {
+                return new int[] { lo.get(Calendar.YEAR), up.get(Calendar.YEAR) };
+            }
         }
 
         logger.warn("Could not determine time range for gauge: " + gauge);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/LocationDistanceSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/LocationDistanceSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,7 @@
 
 import de.intevation.artifactdatabase.data.StateData;
 
+import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.WINFOArtifact;
 
 
@@ -48,18 +49,22 @@
     {
         logger.debug("LocationDistanceSelect.validate");
 
-        WINFOArtifact flys = (WINFOArtifact) artifact;
-
-        if (flys.isRange()) {
-            return super.validate(flys);
+        FLYSArtifact flys = (FLYSArtifact)artifact;
+        StateData mode = getData(flys, MODE);
+        String mValue = mode != null ? (String)mode.getValue() : null;
+        if (mValue != null) {
+            if (mValue.equals("distance")) {
+                return super.validate(flys);
+            }
+            else {
+                return validateLocations(flys);
+            }
         }
-        else {
-            return validateLocations(flys);
-        }
+        return false;
     }
 
 
-    protected boolean validateLocations(WINFOArtifact flys)
+    protected boolean validateLocations(FLYSArtifact flys)
     throws    IllegalArgumentException
     {
         StateData dValues = getData(flys, LOCATIONS);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/ManualPointsSingleState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/ManualPointsSingleState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,22 +3,17 @@
 import java.util.List;
 
 import org.apache.log4j.Logger;
-
 import org.json.JSONArray;
 import org.json.JSONException;
 
-import de.intevation.artifacts.CallMeta;
+import de.intevation.artifactdatabase.state.Facet;
 import de.intevation.artifacts.CallContext;
-
-import de.intevation.artifactdatabase.state.Facet;
-
+import de.intevation.artifacts.CallMeta;
 import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.ManualPointsArtifact;
-
 import de.intevation.flys.artifacts.model.CrossSectionWaterLineFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.ManualPointsFacet;
-
 import de.intevation.flys.artifacts.resources.Resources;
 
 /**
@@ -69,27 +64,27 @@
             // Handle points.
             String pointData = points.getDataAsString(ct + "." + MANUALPOINTS +
                 DOT_DATA);
-            if (pointData != null && !pointData.equals("")
+            if (pointData != null && pointData.length() != 0
                 && !pointData.equals("[]")) {
                 String fName = ct + "." + MANUALPOINTS;
                 ManualPointsFacet facet = new ManualPointsFacet(
                     0,
                     fName,
                     Resources.getMsg(meta, "manualpoints", "Manual Points"));
-
                 facets.add(facet);
+                logger.debug("compute(): ManualPointsFacet for " + ct + " created");
             }
             else {
-                //logger.debug("No points for " + ct);
+                logger.debug("compute(): No points for " + ct);
             }
 
             // Handle lines.
             String linesData = points.getDataAsString(ct + "." + MANUALPOINTS +
                 DOT_LINES);
-            if (linesData != null && !linesData.equals("")
+            if (linesData != null && linesData.length() != 0
                 && !linesData.equals("[]")) {
                 try {
-                    JSONArray lines = new JSONArray((String) linesData);
+                    JSONArray lines = new JSONArray(linesData);
                     for (int i = 0, P = lines.length(); i < P; i++) {
                         JSONArray array = lines.getJSONArray(i);
                         double y    = array.getDouble(0);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/MultiStringArrayState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/MultiStringArrayState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -35,7 +35,7 @@
         try {
             creator.addAttr(select, "type", "options", true);
 
-            for (KVP kvp: getOptions(artifact, name)) {
+            for (KVP kvp: getOptions(artifact, name, context)) {
                 Element item = creator.create("item");
                 creator.addAttr(item, "label", kvp.getValue().toString(), true);
                 creator.addAttr(item, "value", kvp.getKey().toString(), true);
@@ -80,7 +80,8 @@
 
     protected abstract KVP<String, String>[] getOptions(
         Artifact artifact,
-        String   parameterName
+        String   parameterName,
+        CallContext context
     )
     throws IllegalArgumentException;
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/OutliersInput.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/OutliersInput.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,6 +2,9 @@
 
 import org.apache.log4j.Logger;
 
+import de.intevation.artifactdatabase.data.StateData;
+import de.intevation.artifacts.CallContext;
+
 /**
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
@@ -10,6 +13,8 @@
     /** The logger used in this class. */
     private static Logger logger = Logger.getLogger(OutliersInput.class);
 
+    public static final String PARAMETER_NAME = "outliers";
+
 
     /**
      * The default constructor that initializes an empty State object.
@@ -22,5 +27,15 @@
         return "outliers_input";
     }
 
+
+    @Override
+    protected String[] getDefaultsFor(CallContext context, StateData data) {
+        if (data != null && data.getName().equals(PARAMETER_NAME)) {
+            return new String[] {"3", "3"};
+        }
+
+        return null;
+    }
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/PeriodSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.artifacts.states;
+
+public class PeriodSelect extends DefaultState {
+
+    public static final String UI_PROVIDER = "period_select";
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public PeriodSelect() {
+    }
+
+    @Override
+    protected String getUIProvider() {
+        return UI_PROVIDER;
+    }
+
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/QSectorSingleState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,91 @@
+package de.intevation.flys.artifacts.states;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.QSectorArtifact;
+
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.QSectorFacet;
+
+import de.intevation.flys.artifacts.resources.Resources;
+
+/**
+ * The only state for an QSectorArtifact.
+ */
+public class QSectorSingleState
+extends      DefaultState
+implements   FacetTypes
+{
+    /** Developer-centric description of facet. */
+    public static final String I18N_DESCRIPTION
+        = "facet.qsector";
+
+    /** The logger that is used in this state. */
+    private static final Logger logger =
+        Logger.getLogger(QSectorSingleState.class);
+
+
+    /**
+     * Add QSectorFacets to list of Facets.
+     *
+     * @param artifact Ignored.
+     * @param hash Ignored.
+     * @param meta CallMeta to be used for internationalization.
+     * @param facets List to add QSectorFacet to.
+     *
+     * @return null.
+     */
+    public Object compute(
+        FLYSArtifact artifact,
+        String       hash,
+        CallMeta     meta,
+        List<Facet>  facets
+    ) {
+        logger.debug("QSectorSingleState.compute()");
+        QSectorArtifact points = (QSectorArtifact) artifact;
+
+        QSectorFacet qfacet = new QSectorFacet(
+            0,
+            QSECTOR,
+            Resources.getMsg(meta, "qsectors", "Q Sectors"));
+
+        facets.add(qfacet);
+
+        return null;
+    }
+
+
+    /** Call compute. */
+    @Override
+    public Object computeInit(
+        FLYSArtifact artifact,
+        String       hash,
+        Object       context,
+        CallMeta     meta,
+        List<Facet>  facets
+     ) {
+        return compute(artifact, hash, meta, facets);
+    }
+
+
+    /** Call compute. */
+    @Override
+    public Object computeFeed(
+        FLYSArtifact artifact,
+        String hash,
+        CallContext context,
+        List<Facet> facets,
+        Object old
+    ) {
+        return compute(artifact, hash, context.getMeta(), facets);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/RiverSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -30,7 +30,6 @@
     /** The logger used in this class. */
     private static Logger logger = Logger.getLogger(RiverSelect.class);
 
-
     /** Error message that is thrown if no river was found based on a given
      * name.*/
     public static final String ERROR_NO_SUCH_RIVER =
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/SQRelation.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/SQRelation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,10 +1,14 @@
 package de.intevation.flys.artifacts.states;
 
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 
+import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 import de.intevation.artifacts.CallMeta;
 
+import de.intevation.artifacts.common.utils.StringUtils;
+
 import de.intevation.flys.artifacts.FLYSArtifact;
 
 import de.intevation.flys.artifacts.access.SQRelationAccess;
@@ -16,10 +20,12 @@
 import de.intevation.flys.artifacts.model.sq.SQCurveFacet;
 import de.intevation.flys.artifacts.model.sq.SQFractionResult;
 import de.intevation.flys.artifacts.model.sq.SQMeasurementFacet;
+import de.intevation.flys.artifacts.model.sq.SQOutlierCurveFacet;
 import de.intevation.flys.artifacts.model.sq.SQOutlierFacet;
+import de.intevation.flys.artifacts.model.sq.SQOutlierMeasurementFacet;
+import de.intevation.flys.artifacts.model.sq.SQOverviewFacet;
 import de.intevation.flys.artifacts.model.sq.SQRelationCalculation;
 import de.intevation.flys.artifacts.model.sq.SQResult;
-import de.intevation.flys.artifacts.model.sq.SQOverviewFacet;
 
 import de.intevation.flys.artifacts.resources.Resources;
 
@@ -44,6 +50,75 @@
     public static final String I18N_FACET_OUTLIERS =
         "facet.sq_relation.outliers";
 
+    public static final String I18N_FACET_OUTLIER_CURVE =
+        "facet.sq_relation.outlier.curve";
+
+    public static final String I18N_FACET_OUTLIER_MEASUREMENT =
+        "facet.sq_relation.outlier.measurement";
+
+    public static final int CURVE_INDEX               = 0;
+    public static final int MEASURREMENT_INDEX        = 1;
+    public static final int OUTLIER_INDEX             = 2;
+    public static final int OUTLIER_CURVE_INDEX       = 3;
+    public static final int OUTLIER_MEASUREMENT_INDEX = 4;
+
+    public static final String [][] FACET_NAMES = {
+        { SQ_A_CURVE, SQ_B_CURVE, SQ_C_CURVE,
+          SQ_D_CURVE, SQ_E_CURVE, SQ_F_CURVE
+        },
+        { SQ_A_MEASUREMENT, SQ_B_MEASUREMENT, SQ_C_MEASUREMENT,
+          SQ_D_MEASUREMENT, SQ_E_MEASUREMENT, SQ_F_MEASUREMENT
+        },
+        { SQ_A_OUTLIER, SQ_B_OUTLIER, SQ_C_OUTLIER,
+          SQ_D_OUTLIER, SQ_E_OUTLIER, SQ_F_OUTLIER
+        },
+        { SQ_A_OUTLIER_CURVE, SQ_B_OUTLIER_CURVE, SQ_C_OUTLIER_CURVE,
+          SQ_D_OUTLIER_CURVE, SQ_E_OUTLIER_CURVE, SQ_F_OUTLIER_CURVE
+        },
+        { SQ_A_OUTLIER_MEASUREMENT, SQ_B_OUTLIER_MEASUREMENT,
+          SQ_C_OUTLIER_MEASUREMENT, SQ_D_OUTLIER_MEASUREMENT,
+          SQ_E_OUTLIER_MEASUREMENT, SQ_F_OUTLIER_MEASUREMENT
+        }
+    };
+
+
+    static {
+        // Active/deactivate facets.
+        FacetActivity.Registry.getInstance().register(
+            "minfo",
+            new FacetActivity() {
+                @Override
+                public Boolean isInitialActive(
+                    Artifact artifact,
+                    Facet    facet,
+                    String   output
+                ) {
+                    String name = facet.getName();
+
+                    if (StringUtils.contains(
+                        name, FACET_NAMES[CURVE_INDEX])
+                    ||  StringUtils.contains(
+                        name, FACET_NAMES[OUTLIER_INDEX])
+                    ||  StringUtils.contains(
+                        name, FACET_NAMES[MEASURREMENT_INDEX])
+                    ) {
+                        // TODO: Only the last should be active.
+                        return Boolean.TRUE;
+                    }
+
+                    if (StringUtils.contains(
+                        name, FACET_NAMES[OUTLIER_CURVE_INDEX])
+                     || StringUtils.contains(
+                        name, FACET_NAMES[OUTLIER_MEASUREMENT_INDEX])
+                    ) {
+                        return Boolean.FALSE;
+                    }
+
+                    return null;
+                }
+            });
+    }
+
 
     public SQRelation() {
     }
@@ -94,25 +169,27 @@
         SQResult[]  sqr,
         String      hash
     ) {
+        boolean debug = log.isDebugEnabled();
+
         CallMeta meta    = context.getMeta();
         String   stateId = getID();
         for (int i = 0; i < 6; i++) {
             container.add(new SQOverviewFacet(
-                    i,
-                    i,
-                    "sq_chart_overview",
-                    Resources.getMsg(
-                        context.getMeta(),
-                        I18N_FACET_CURVE,
-                        I18N_FACET_CURVE
-                    ),
-                    hash,
-                    getID()
-                ));
+                i,
+                i,
+                "sq_chart_overview",
+                Resources.getMsg(
+                    meta,
+                    I18N_FACET_CURVE,
+                    I18N_FACET_CURVE
+                ),
+                hash,
+                getID()
+            ));
         }
         for (int res = 0, n = sqr.length; res < n; res++) {
 
-            for (int i = 0; i < 6; i++) {
+            for (int i = 0; i < SQResult.NUMBER_FRACTIONS; i++) {
                 SQFractionResult result = sqr[res].getFraction(i);
 
                 if (result == null) {
@@ -120,23 +197,10 @@
                     continue;
                 }
 
-                container.add(new SQMeasurementFacet(
-                    res,
-                    i,
-                    getFractionFacetname(1, i),
-                    Resources.getMsg(
-                        meta,
-                        I18N_FACET_MEASUREMENTS,
-                        I18N_FACET_MEASUREMENTS
-                    ),
-                    hash,
-                    stateId
-                ));
-
                 container.add(new SQCurveFacet(
                     res,
                     i,
-                    getFractionFacetname(0, i),
+                    getFractionFacetname(CURVE_INDEX, i),
                     Resources.getMsg(
                         meta,
                         I18N_FACET_CURVE,
@@ -146,12 +210,15 @@
                     stateId
                 ));
 
-                for (int j = 0, C = result.getOutliersCount(); j < C; j++) {
+                for (int j = 0, C = result.numIterations()-1; j < C; j++) {
+
+                    Object [] round = new Object [] { j + 1 };
+
                     int index = res;
                     index     = index << 16;
                     index     = index + j;
 
-                    if (log.isDebugEnabled()) {
+                    if (debug) {
                         log.debug("new outliers facet (index=" +index+ ")");
                         log.debug("   result index = " + res);
                         log.debug("   fraction idx = " + i);
@@ -161,56 +228,68 @@
                     container.add(new SQOutlierFacet(
                         index,
                         i,
-                        getFractionFacetname(2, i),
+                        getFractionFacetname(OUTLIER_INDEX, i),
                         Resources.getMsg(
                             meta,
                             I18N_FACET_OUTLIERS,
                             I18N_FACET_OUTLIERS,
-                            new Object[] { j }
+                            round
                         ),
                         hash,
                         stateId
                     ));
-                }
-            }
-        }
+
+                    container.add(new SQOutlierCurveFacet(
+                        index,
+                        i,
+                        getFractionFacetname(OUTLIER_CURVE_INDEX, i),
+                        Resources.getMsg(
+                            meta,
+                            I18N_FACET_OUTLIER_CURVE,
+                            I18N_FACET_OUTLIER_CURVE,
+                            round
+                        ),
+                        hash,
+                        stateId
+                    ));
+
+                    container.add(new SQOutlierMeasurementFacet(
+                        index,
+                        i,
+                        getFractionFacetname(OUTLIER_MEASUREMENT_INDEX, i),
+                        Resources.getMsg(
+                            meta,
+                            I18N_FACET_OUTLIER_MEASUREMENT,
+                            I18N_FACET_OUTLIER_MEASUREMENT,
+                            round
+                        ),
+                        hash,
+                        stateId
+                    ));
+                } // for all outliers
+
+                container.add(new SQMeasurementFacet(
+                    res,
+                    i,
+                    getFractionFacetname(MEASURREMENT_INDEX, i),
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_MEASUREMENTS,
+                        I18N_FACET_MEASUREMENTS
+                    ),
+                    hash,
+                    stateId
+                ));
+            } // for all fractions
+        } // for all results
     }
 
-
-    protected String getFractionFacetname(int type, int fractionIdx) {
-        log.debug("getFractionFacetname(): " + type + " | " + fractionIdx);
-
-        switch (type) {
-            case 0:
-                switch (fractionIdx) {
-                    case 0: return SQ_A_CURVE;
-                    case 1: return SQ_B_CURVE;
-                    case 2: return SQ_C_CURVE;
-                    case 3: return SQ_D_CURVE;
-                    case 4: return SQ_E_CURVE;
-                    case 5: return SQ_F_CURVE;
-                }
-            case 1:
-                switch (fractionIdx) {
-                    case 0: return SQ_A_MEASUREMENT;
-                    case 1: return SQ_B_MEASUREMENT;
-                    case 2: return SQ_C_MEASUREMENT;
-                    case 3: return SQ_D_MEASUREMENT;
-                    case 4: return SQ_E_MEASUREMENT;
-                    case 5: return SQ_F_MEASUREMENT;
-                }
-            case 2:
-                switch (fractionIdx) {
-                    case 0: return SQ_A_OUTLIER;
-                    case 1: return SQ_B_OUTLIER;
-                    case 2: return SQ_C_OUTLIER;
-                    case 3: return SQ_D_OUTLIER;
-                    case 4: return SQ_E_OUTLIER;
-                    case 5: return SQ_F_OUTLIER;
-                }
+    protected static String getFractionFacetname(int type, int idx) {
+        if (log.isDebugEnabled()) {
+            log.debug("getFractionFacetname(): " + type + " | " + idx);
         }
-
-        return null;
+        type %= FACET_NAMES.length;
+        return FACET_NAMES[type][idx % FACET_NAMES[type].length];
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -20,13 +20,13 @@
 
 public class SoundingsSelect extends MultiStringArrayState {
 
-    public static final String SOUNDINGS  = "soundings";
+    public static final String SOUNDINGS = "soundings";
 
     public static final String PREFIX_SINGLE = "single-";
 
-    public static final String PREFIX_EPOCH  = "epoch-";
+    public static final String PREFIX_EPOCH = "epoch-";
 
-
+    /** Private logger. */
     private static final Logger logger = Logger.getLogger(SoundingsSelect.class);
 
 
@@ -39,7 +39,8 @@
     @Override
     protected KVP<String, String>[] getOptions(
         Artifact artifact,
-        String   parameterName
+        String   parameterName,
+        CallContext context
     )
     throws IllegalArgumentException
     {
@@ -62,7 +63,7 @@
         appendSingles(river, kmLo, kmHi, kvp);
         appendEpochs(river, kmLo, kmHi, kvp);
 
-        return (KVP<String,String>[]) kvp.toArray(new KVP[kvp.size()]);
+        return kvp.toArray(new KVP[kvp.size()]);
     }
 
 
@@ -76,7 +77,11 @@
             BedHeightSingle.getBedHeightSingles(river, kmLo, kmHi);
 
         if (singles != null) {
-            for (int i = 0, S = singles.size(); i < S; i++) {
+            int size = singles.size();
+
+            logger.debug("Found " + size + " singles.");
+
+            for (int i = 0; i < size; i++) {
                 BedHeightSingle s = singles.get(i);
 
                 String id    = PREFIX_SINGLE + s.getId();
@@ -98,7 +103,11 @@
             BedHeightEpoch.getBedHeightEpochs(river, kmLo, kmHi);
 
         if (epochs != null) {
-            for (int i = 0, E = epochs.size(); i < E; i++) {
+            int size = epochs.size();
+
+            logger.debug("Found " + size + " epochs.");
+
+            for (int i = 0; i < size; i++) {
                 BedHeightEpoch e = epochs.get(i);
 
                 String id    = PREFIX_EPOCH + e.getId();
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/StateFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/StateFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -103,12 +103,12 @@
             String desc = (String) XMLUtils.xpath(
                 data, XPATH_DATA_DESCRIPTION, XPathConstants.STRING);
 
-            if (name == null || name.equals("")) {
+            if (name == null || name.length() == 0) {
                 logger.warn("No name for data item at pos " + i + " found.");
                 continue;
             }
 
-            if (type == null || type.equals("")) {
+            if (type == null || type.length() == 0) {
                 logger.warn("No type for data item at pos " + i + " found.");
                 logger.warn("Default type 'string' used.");
                 type = "string";
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/StaticState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/StaticState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,7 @@
 
 import de.intevation.artifactdatabase.state.Facet;
 import de.intevation.artifactdatabase.state.DefaultOutput;
+import de.intevation.artifactdatabase.state.Output;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
@@ -107,5 +108,9 @@
     ) {
         return staticCompute(facets, artifact);
     }
+
+    public void addOutput(Output out) {
+        super.addOutput(out);
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java	Fri Sep 28 12:15:40 2012 +0200
@@ -22,7 +22,7 @@
 import de.intevation.flys.model.River;
 import de.intevation.flys.model.Wst;
 
-import de.intevation.flys.artifacts.WINFOArtifact;
+import de.intevation.flys.artifacts.FLYSArtifact;
 
 import de.intevation.flys.artifacts.model.RangeWithValues;
 import de.intevation.flys.artifacts.model.WstFactory;
@@ -30,6 +30,7 @@
 
 
 /**
+ * State to input W/Q data.
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class WQAdapted extends DefaultState {
@@ -37,7 +38,6 @@
     /** The logger used in this state.*/
     private static Logger logger = Logger.getLogger(WQAdapted.class);
 
-
     public static final String FIELD_WQ_MODE = "wq_isq";
 
     public static final String FIELD_WQ_VALUES = "wq_values";
@@ -57,9 +57,11 @@
     public static final GaugeOrder GAUGE_UP   = new GaugeOrder(true);
     public static final GaugeOrder GAUGE_DOWN = new GaugeOrder(false);
 
+    /** Trivial, empty constructor. */
     public WQAdapted() {
     }
 
+
     /**
      * This method creates one element for each gauge of the selected river that
      * is intersected by the given kilometer range. Each element is a tuple of
@@ -97,6 +99,7 @@
     }
 
 
+    /** Creates "Q" and "W" items. */
     protected Element[] createModeItems(
         XMLUtils.ElementCreator cr,
         Artifact    artifact,
@@ -120,12 +123,12 @@
     {
         logger.debug("WQAdapted.createValueItems");
 
-        WINFOArtifact flysArtifact = (WINFOArtifact) artifact;
+        FLYSArtifact flysArtifact = (FLYSArtifact) artifact;
 
         double[]    dist   = FLYSUtils.getKmRange(flysArtifact);
         River       river  = FLYSUtils.getRiver(flysArtifact);
         Wst         wst    = WstFactory.getWst(river);
-        List<Gauge> gauges = flysArtifact.getGauges();
+        List<Gauge> gauges = FLYSUtils.getGauges(flysArtifact);
 
         int num = gauges != null ? gauges.size() : 0;
 
@@ -134,13 +137,11 @@
             return null;
         }
 
-        Element[] elements = new Element[num];
+        List<Element> elements = new ArrayList<Element>();
 
         double rangeFrom = dist[0];
         double rangeTo   = dist[1];
 
-        int idx = 0;
-
         if (rangeFrom < rangeTo) {
             Collections.sort(gauges, GAUGE_UP);
             for (Gauge gauge: gauges) {
@@ -148,14 +149,19 @@
                 double lower = range.getA().doubleValue();
                 double upper = range.getB().doubleValue();
 
+                // If gauge out of range, skip it.
+                if (upper <= rangeFrom || lower >= rangeTo) {
+                    continue;
+                }
+
                 double from = lower < rangeFrom ? rangeFrom : lower;
                 double to   = upper > rangeTo   ? rangeTo   : upper;
 
                 double[] mmQ = determineMinMaxQ(gauge, wst);
                 double[] mmW = gauge.determineMinMaxW();
 
-                elements[idx++] = createItem(
-                    cr, new String[] { from + ";" + to, ""}, mmQ, mmW);
+                elements.add(createItem(
+                    cr, new String[] { from + ";" + to, ""}, mmQ, mmW));
             }
         }
         else {
@@ -170,15 +176,18 @@
                 double from = lower < rangeFrom ? rangeFrom : lower;
                 double to   = upper > rangeTo   ? rangeTo   : upper;
 
+                // TODO probably need to continue out if oof range (see above).
+
                 double[] mmQ = determineMinMaxQ(gauge, wst);
                 double[] mmW = gauge.determineMinMaxW();
 
-                elements[idx++] = createItem(
-                    cr, new String[] { to + ";" + from, ""}, mmQ, mmW);
+                elements.add(createItem(
+                    cr, new String[] { to + ";" + from, ""}, mmQ, mmW));
             }
         }
 
-        return elements;
+        Element[] els = new Element[elements.size()];
+        return elements.toArray(els);
     }
 
 
@@ -278,7 +287,7 @@
     {
         logger.debug("WQAdapted.validate");
 
-        WINFOArtifact flys = (WINFOArtifact) artifact;
+        FLYSArtifact flys = (FLYSArtifact) artifact;
         StateData    data = getData(flys, FIELD_WQ_MODE);
 
         String mode = data != null ? (String) data.getValue() : null;
@@ -302,7 +311,7 @@
     throws IllegalArgumentException
     {
         logger.debug("WQAdapted.validateW");
-        WINFOArtifact flys = (WINFOArtifact) artifact;
+        FLYSArtifact flys = (FLYSArtifact) artifact;
 
         RangeWithValues[] rwvs = extractInput(getData(flys, "wq_values"));
 
@@ -310,7 +319,7 @@
             throw new IllegalArgumentException("error_missing_wq_data");
         }
 
-        List<Gauge>     gauges = ((WINFOArtifact) artifact).getGauges();
+        List<Gauge> gauges = FLYSUtils.getGauges((FLYSArtifact) artifact);
 
         for (Gauge gauge: gauges) {
             Range range  = gauge.getRange();
@@ -318,7 +327,7 @@
             double upper = range.getB().doubleValue();
 
             for (RangeWithValues rwv: rwvs) {
-                if (lower <= rwv.getLower() && upper >= rwv.getUpper()) {
+                if (lower <= rwv.getStart() && upper >= rwv.getEnd()) {
                     compareWsWithGauge(gauge, rwv.getValues());
                 }
             }
@@ -332,7 +341,7 @@
     throws IllegalArgumentException
     {
         logger.debug("WQAdapted.validateQ");
-        WINFOArtifact flys = (WINFOArtifact) artifact;
+        FLYSArtifact flys = (FLYSArtifact) artifact;
 
         RangeWithValues[] rwvs = extractInput(getData(flys, "wq_values"));
 
@@ -340,7 +349,7 @@
             throw new IllegalArgumentException("error_missing_wq_data");
         }
 
-        List<Gauge> gauges = flys.getGauges();
+        List<Gauge> gauges = FLYSUtils.getGauges(flys);
         River        river = FLYSUtils.getRiver(flys);
         Wst            wst = WstFactory.getWst(river);
 
@@ -350,7 +359,7 @@
             double upper = range.getB().doubleValue();
 
             for (RangeWithValues rwv: rwvs) {
-                if (lower <= rwv.getLower() && upper >= rwv.getUpper()) {
+                if (lower <= rwv.getStart() && upper >= rwv.getEnd()) {
                     compareQsWithGauge(wst, gauge, rwv.getValues());
                 }
             }
@@ -453,7 +462,7 @@
             rwv.add(new RangeWithValues(lower, upper, res));
         }
 
-        return (RangeWithValues[]) rwv.toArray(new RangeWithValues[rwv.size()]);
+        return rwv.toArray(new RangeWithValues[rwv.size()]);
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,13 +1,14 @@
 package de.intevation.flys.artifacts.states;
 
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
 import de.intevation.artifactdatabase.state.Facet;
-
 import de.intevation.artifacts.CallContext;
-
 import de.intevation.flys.artifacts.ChartArtifact;
 import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.WINFOArtifact;
-
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.CrossSectionWaterLineFacet;
 import de.intevation.flys.artifacts.model.DataFacet;
@@ -16,13 +17,8 @@
 import de.intevation.flys.artifacts.model.ReportFacet;
 import de.intevation.flys.artifacts.model.WQKms;
 import de.intevation.flys.artifacts.model.WaterlevelFacet;
-
 import de.intevation.flys.utils.FLYSUtils;
 
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
 public class WaterlevelState
 extends      DefaultState
 implements   FacetTypes
@@ -127,7 +123,6 @@
         Object       old
     ) {
         if (artifact instanceof ChartArtifact) {
-            ChartArtifact chart = (ChartArtifact)artifact;
             facets.add(new EmptyFacet());
             return null;
         }
@@ -147,7 +142,6 @@
         Object       old
     ) {
         if (artifact instanceof ChartArtifact) {
-            ChartArtifact chart = (ChartArtifact)artifact;
             facets.add(new EmptyFacet());
             return null;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/extreme/ExtremeCompute.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,65 @@
+package de.intevation.flys.artifacts.states.extreme;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.access.ExtremeAccess;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.ReportFacet;
+
+import de.intevation.flys.artifacts.model.extreme.ExtremeCalculation;
+
+import de.intevation.flys.artifacts.states.DefaultState;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class ExtremeCompute
+extends      DefaultState
+{
+    private static Logger log = Logger.getLogger(ExtremeCompute.class);
+
+    public ExtremeCompute() {
+    }
+
+    @Override
+    public Object computeAdvance(
+        FLYSArtifact artifact,
+        String       hash,
+        CallContext  context,
+        List<Facet>  facets,
+        Object       old
+    ) {
+        log.debug("ExtremeCompute.computeAdvance");
+
+        CalculationResult res;
+
+        ExtremeAccess access = new ExtremeAccess(artifact);
+
+        if (old instanceof CalculationResult) {
+            res = (CalculationResult)old;
+        }
+        else {
+            ExtremeCalculation calc = new ExtremeCalculation(access);
+            res = calc.calculate();
+        }
+
+        if (facets == null) {
+            return res;
+        }
+
+        if (res.getReport().hasProblems()) {
+            facets.add(new ReportFacet());
+        }
+
+        // TODO: Add more facets.
+
+        return res;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FixAnalysisCompute.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,319 @@
+package de.intevation.flys.artifacts.states.fixation;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.DateRange;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.ReportFacet;
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisCalculation;
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisEventsFacet;
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisPeriodsFacet;
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisResult;
+import de.intevation.flys.artifacts.model.fixings.FixAvSectorFacet;
+import de.intevation.flys.artifacts.model.fixings.FixDerivateFacet;
+import de.intevation.flys.artifacts.model.fixings.FixDeviationFacet;
+import de.intevation.flys.artifacts.model.fixings.FixLongitudinalAnalysisFacet;
+import de.intevation.flys.artifacts.model.fixings.FixLongitudinalAvSectorFacet;
+import de.intevation.flys.artifacts.model.fixings.FixLongitudinalDeviationFacet;
+import de.intevation.flys.artifacts.model.fixings.FixLongitudinalReferenceFacet;
+import de.intevation.flys.artifacts.model.fixings.FixOutlierFacet;
+import de.intevation.flys.artifacts.model.fixings.FixReferenceEventsFacet;
+import de.intevation.flys.artifacts.model.fixings.FixWQCurveFacet;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.artifacts.states.DefaultState;
+import de.intevation.flys.utils.IdGenerator;
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class FixAnalysisCompute
+extends      DefaultState
+implements   FacetTypes
+{
+    /** The log used in this class. */
+    private static Logger log = Logger.getLogger(FixAnalysisCompute.class);
+
+    private static final String I18N_REFERENCEPERIOD_SHORT = "fix.reference.period.event.short";
+
+    private static final String I18N_ANALYSISPERIODS = "fix.analysis.periods";
+
+    private static final String I18N_DERIVATIVE = "fix.derivative";
+
+    private static final String I18N_OUTLIER = "fix.outlier";
+
+    private static final String I18N_ANALYSIS = "fix.analysis.short";
+
+    private static final String I18N_DEVIATION = "fix.deviation";
+
+    private static final String I18N_REFERENCEDEVIATION = "fix.reference.deviation";
+
+    private static final String I18N_REFERENCEPERIOD = "state.fix.analysis.referenceperiod";
+
+    public static final String [] SECTOR_LABELS = {
+        "[0 - (MNQ+MQ)/2)",
+        "[(MNQ+MQ)/2 - (MQ+MHQ)/2)",
+        "[(MQ+MHQ)/2 - HQ5)",
+        "[HQ5 - \u221e)"
+    };
+
+    static {
+        // Active/deactivate facets.
+        FacetActivity.Registry.getInstance().register(
+            "fixanalysis",
+            new FacetActivity() {
+                @Override
+                public Boolean isInitialActive(
+                    Artifact artifact,
+                    Facet    facet,
+                    String   output
+                ) {
+                    if (output.contains(FacetTypes.ChartType.FLSC.toString())) { // Longitudinal section chart
+                        String name = facet.getName();
+
+                        if (name.contains(FacetTypes.FIX_ANALYSIS_EVENTS_DWT)
+                         || name.contains(FacetTypes.FIX_ANALYSIS_EVENTS_LS)
+                         || name.contains(FacetTypes.FIX_ANALYSIS_EVENTS_WQ)
+                         || name.contains(FacetTypes.FIX_REFERENCE_EVENTS_DWT)
+                         || name.contains(FacetTypes.FIX_REFERENCE_EVENTS_LS)
+                         || name.contains(FacetTypes.FIX_REFERENCE_EVENTS_WQ)
+                        ) {
+                            return Boolean.FALSE;
+                        }
+                    }
+
+                    return Boolean.TRUE;
+                }
+            });
+    }
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public FixAnalysisCompute() {
+    }
+
+    @Override
+    public Object computeAdvance(
+        FLYSArtifact artifact,
+        String       hash,
+        CallContext  context,
+        List<Facet>  facets,
+        Object       old
+    ) {
+        log.debug("FixAnalysisCompute.computeAdvance");
+
+        CalculationResult res;
+
+        FixAnalysisAccess access =
+            new FixAnalysisAccess(artifact);
+
+        if (old instanceof CalculationResult) {
+            res = (CalculationResult)old;
+        }
+        else {
+            FixAnalysisCalculation calc = new FixAnalysisCalculation(access);
+            res = calc.calculate();
+        }
+
+        if (facets == null) {
+            return res;
+        }
+
+        if (res.getReport().hasProblems()) {
+            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, id));
+        }
+
+        FixAnalysisResult fr = (FixAnalysisResult)res.getData();
+        if (fr == null) {
+            return res;
+        }
+
+        facets.add(
+            new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
+        facets.add(
+            new DataFacet(
+                FIX_PARAMETERS, "parameters", ComputeType.ADVANCE, hash, id));
+        facets.add(
+            new DataFacet(AT, "AT data", ComputeType.ADVANCE, hash, id));
+
+        int maxId = -100;
+
+        int sectorMask = fr.getUsedSectorsInAnalysisPeriods();
+
+        int qsS = access.getQSectorStart();
+        int qsE = access.getQSectorEnd();
+
+        // TODO: i18n
+        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
+
+        DateRange [] periods = access.getAnalysisPeriods();
+
+        for (int i = 0; i < periods.length; i++) {
+            DateRange period = periods[i];
+            String startDate = df.format(period.getFrom());
+            String endDate = df.format(period.getTo());
+
+            for (int j = qsS; j <= qsE; j++) {
+
+                // Only emit facets for sectors that really have data.
+                if ((sectorMask & (1 << j)) == 0) {
+                    continue;
+                }
+
+                String sector = SECTOR_LABELS[j];
+                String description = sector + ": " +
+                                     startDate + " - " +
+                                     endDate;
+
+                int sectorNdx = j - qsS;
+                int facetNdx = i << 2;
+                facetNdx = facetNdx | j;
+
+                if (facetNdx > maxId) {
+                    maxId = facetNdx;
+                }
+
+                facets.add(
+                    new FixAvSectorFacet(
+                        facetNdx,
+                        FIX_SECTOR_AVERAGE_DWT + "_" + sectorNdx,
+                        description));
+                facets.add(
+                    new FixLongitudinalAvSectorFacet(
+                        facetNdx,
+                        FIX_SECTOR_AVERAGE_LS + "_" + sectorNdx,
+                        description));
+                // TODO: i18n
+                String dev = "Abweichung: " + description;
+                facets.add(
+                    new FixLongitudinalAvSectorFacet(
+                        facetNdx,
+                        FIX_SECTOR_AVERAGE_LS_DEVIATION + "_" + sectorNdx,
+                        dev));
+                facets.add(
+                    new FixAvSectorFacet(
+                        facetNdx,
+                        FIX_SECTOR_AVERAGE_WQ + "_" + sectorNdx,
+                        description));
+
+            }
+
+            String eventDesc =
+                Resources.getMsg(context.getMeta(),
+                                 I18N_ANALYSIS,
+                                 I18N_ANALYSIS);
+
+            int k = 0;
+            for (Date d: fr.getAnalysisEventsDates(i)) {
+                int anaNdx = i << 8;
+                anaNdx = anaNdx | k;
+                facets.add(new FixAnalysisEventsFacet(anaNdx,
+                    FIX_ANALYSIS_EVENTS_DWT,
+                    eventDesc + (i+1) + " - " + df.format(d)));
+                facets.add(new FixLongitudinalAnalysisFacet(anaNdx,
+                    FIX_ANALYSIS_EVENTS_LS,
+                    eventDesc + (i+1) + " - " + df.format(d)));
+                facets.add(new FixAnalysisEventsFacet(anaNdx,
+                    FIX_ANALYSIS_EVENTS_WQ,
+                    eventDesc + (i+1) +" - " + df.format(d)));
+                k++;
+            }
+        }
+
+        IdGenerator idg = new IdGenerator(maxId + 1);
+
+        String i18n_ref = Resources.getMsg(context.getMeta(),
+                I18N_REFERENCEPERIOD_SHORT,
+                I18N_REFERENCEPERIOD_SHORT);
+        String i18n_dev = Resources.getMsg(context.getMeta(),
+                I18N_REFERENCEDEVIATION,
+                I18N_REFERENCEDEVIATION);
+
+        int i = 0;
+        for (Date d: fr.getReferenceEventsDates()) {
+            int refNdx = idg.next() << 8;
+            refNdx |=  i;
+            facets.add(new FixReferenceEventsFacet(refNdx,
+                FIX_REFERENCE_EVENTS_DWT,
+                i18n_ref + " - " + df.format(d)));
+            refNdx = idg.next() << 8;
+            refNdx = refNdx | i;
+            facets.add(new FixLongitudinalReferenceFacet(refNdx,
+                FIX_REFERENCE_EVENTS_LS,
+                i18n_ref + " - " + df.format(d)));
+            refNdx = idg.next() << 8;
+            refNdx |= i;
+            facets.add(new FixReferenceEventsFacet(refNdx,
+                FIX_REFERENCE_EVENTS_WQ,
+                i18n_ref + " - " + df.format(d)));
+            i++;
+        }
+
+
+        facets.add(new FixLongitudinalDeviationFacet(idg.next(),
+            FIX_DEVIATION_LS,
+            i18n_dev));
+
+        String i18n_ana = Resources.getMsg(context.getMeta(),
+                I18N_ANALYSISPERIODS,
+                I18N_ANALYSISPERIODS);
+        facets.add(new FixAnalysisPeriodsFacet(idg.next(),
+            FIX_ANALYSIS_PERIODS_DWT,
+            i18n_ana));
+        facets.add(new FixAnalysisPeriodsFacet(idg.next(),
+            FIX_ANALYSIS_PERIODS_LS,
+            i18n_ana));
+        facets.add(new FixAnalysisPeriodsFacet(idg.next(),
+            FIX_ANALYSIS_PERIODS_WQ,
+            i18n_ana));
+
+        String i18n_refp = Resources.getMsg(context.getMeta(),
+                I18N_REFERENCEPERIOD,
+                I18N_REFERENCEPERIOD);
+        facets.add(new DataFacet(idg.next(),
+            FIX_REFERENCE_PERIOD_DWT,
+            i18n_refp,
+            ComputeType.ADVANCE, null, null));
+
+        facets.add(new FixWQCurveFacet(idg.next(), "W/Q"));
+
+        Boolean preprocessing = access.getPreprocessing();
+
+        if (preprocessing != null && preprocessing) {
+            facets.add(new FixOutlierFacet(
+                idg.next(),
+                FIX_OUTLIER,
+                Resources.getMsg(
+                    context.getMeta(), I18N_OUTLIER, I18N_OUTLIER)));
+        }
+
+        facets.add(new FixDerivateFacet(
+            idg.next(),
+            FIX_DERIVATE_CURVE,
+            Resources.getMsg(
+                context.getMeta(),
+                I18N_DERIVATIVE,
+                I18N_DERIVATIVE)));
+
+        facets.add(new FixDeviationFacet(
+            idg.next(),
+            FIX_DEVIATION_DWT,
+            Resources.getMsg(context.getMeta(),
+                I18N_DEVIATION,
+                I18N_DEVIATION)));
+        return res;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FixRealizingCompute.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,147 @@
+package de.intevation.flys.artifacts.states.fixation;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.FixRealizingAccess;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.ReportFacet;
+import de.intevation.flys.artifacts.model.WQCKms;
+import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.artifacts.model.fixings.FixOutlierFacet;
+import de.intevation.flys.artifacts.model.fixings.FixRealizingCalculation;
+import de.intevation.flys.artifacts.model.fixings.FixRealizingResult;
+import de.intevation.flys.artifacts.model.fixings.FixReferenceEventsFacet;
+import de.intevation.flys.artifacts.model.fixings.FixWQCurveFacet;
+import de.intevation.flys.artifacts.model.fixings.FixWaterlevelFacet;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.artifacts.states.DefaultState;
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class FixRealizingCompute extends DefaultState implements FacetTypes {
+
+    /** The logger used in this class. */
+    private static Logger logger = Logger.getLogger(FixRealizingCompute.class);
+
+
+    public static final String I18N_WQ_CURVE = "fix.vollmer.wq.curve";
+
+    public static final String I18N_WQ_OUTLIER = "fix.vollmer.wq.outliers";
+
+    public static final String I18N_WQ_EVENTS = "fix.vollmer.wq.events";
+
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public FixRealizingCompute() {
+    }
+
+    @Override
+    public Object computeAdvance(
+        FLYSArtifact artifact,
+        String       hash,
+        CallContext  context,
+        List<Facet>  facets,
+        Object       old
+    ) {
+        logger.debug("FixRealizingCompute.computeAdvance");
+
+        CalculationResult res;
+
+        FixRealizingAccess access =
+            new FixRealizingAccess(artifact);
+
+        if (old instanceof CalculationResult) {
+            res = (CalculationResult)old;
+        }
+        else {
+            FixRealizingCalculation calc = new FixRealizingCalculation(access);
+            res = calc.calculate();
+        }
+
+        if (facets == null) {
+            return res;
+        }
+
+        if (res.getReport().hasProblems()) {
+            facets.add(new ReportFacet());
+        }
+
+        String   id   = getID();
+        CallMeta meta = context.getMeta();
+
+        FixRealizingResult fixRes = (FixRealizingResult) res.getData();
+        WQKms [] wqkms = fixRes != null ? fixRes.getWQKms() : new WQKms[0];
+
+        for (int i = 0; i < wqkms.length; i++) {
+            String nameW = null;
+            String nameQ = null;
+
+            if (access.isQ()) {
+                nameQ = wqkms[i].getName();
+                nameW = "W(" + nameQ + ")";
+            }
+            else {
+                nameW = wqkms[i].getName();
+                nameQ = "Q(" + nameW + ")";
+            }
+
+            Facet w = new FixWaterlevelFacet(
+                i, LONGITUDINAL_W, nameW);
+
+            Facet q = new FixWaterlevelFacet(
+                i, LONGITUDINAL_Q, nameQ);
+
+            facets.add(w);
+            facets.add(q);
+
+            if (wqkms[i] instanceof WQCKms) {
+                String nameC = nameW.replace(
+                    "benutzerdefiniert",
+                    "benutzerdefiniert [korrigiert]");
+
+                Facet c = new FixWaterlevelFacet(
+                    i, DISCHARGE_LONGITUDINAL_C, nameC);
+
+                facets.add(c);
+            }
+        }
+
+        if (wqkms.length > 0) {
+            facets.add(
+                new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
+
+            facets.add(
+                new DataFacet(WST, "WST data", ComputeType.ADVANCE, hash, id));
+
+            facets.add(
+                new DataFacet(PDF, "PDF data", ComputeType.ADVANCE, hash, id));
+        }
+
+        facets.add(new FixWQCurveFacet(
+            0, Resources.getMsg(meta, I18N_WQ_CURVE, I18N_WQ_CURVE)));
+
+        facets.add(new FixReferenceEventsFacet(
+            0,
+            FIX_REFERENCE_EVENTS_WQ,
+            Resources.getMsg(meta, I18N_WQ_EVENTS, I18N_WQ_EVENTS)));
+
+        facets.add(new FixOutlierFacet(
+            0,
+            FIX_OUTLIER,
+            Resources.getMsg(meta, I18N_WQ_OUTLIER, I18N_WQ_OUTLIER)));
+
+        return res;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FixationCompute.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-package de.intevation.flys.artifacts.states.fixation;
-
-import de.intevation.artifactdatabase.state.Facet;
-
-import de.intevation.artifacts.CallContext;
-
-import de.intevation.flys.artifacts.FLYSArtifact;
-
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
-
-import de.intevation.flys.artifacts.model.CalculationResult;
-import de.intevation.flys.artifacts.model.DataFacet;
-import de.intevation.flys.artifacts.model.DateRange;
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.ReportFacet;
-
-import de.intevation.flys.artifacts.model.fixings.FixAnalysisEventsFacet;
-import de.intevation.flys.artifacts.model.fixings.FixAnalysisPeriodsFacet;
-import de.intevation.flys.artifacts.model.fixings.FixAvSectorFacet;
-import de.intevation.flys.artifacts.model.fixings.FixCalculation;
-import de.intevation.flys.artifacts.model.fixings.FixDerivateFacet;
-import de.intevation.flys.artifacts.model.fixings.FixDeviationFacet;
-import de.intevation.flys.artifacts.model.fixings.FixLongitudinalAnalysisFacet;
-import de.intevation.flys.artifacts.model.fixings.FixLongitudinalDeviationFacet;
-import de.intevation.flys.artifacts.model.fixings.FixLongitudinalReferenceFacet;
-import de.intevation.flys.artifacts.model.fixings.FixOutlierFacet;
-import de.intevation.flys.artifacts.model.fixings.FixReferenceEventsFacet;
-import de.intevation.flys.artifacts.model.fixings.FixResult;
-import de.intevation.flys.artifacts.model.fixings.FixWQCurveFacet;
-
-import de.intevation.flys.artifacts.resources.Resources;
-
-import de.intevation.flys.artifacts.states.DefaultState;
-
-import de.intevation.flys.utils.IdGenerator;
-
-import java.text.DateFormat;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-/**
- * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
- */
-public class FixationCompute
-extends      DefaultState
-implements   FacetTypes
-{
-    /** The log used in this class. */
-    private static Logger log = Logger.getLogger(FixationCompute.class);
-
-    private static final String I18N_REFERENCEPERIOD = "fix.reference.period.events";
-
-    private static final String I18N_ANALYSISPERIODS = "fix.analysis.periods";
-
-    private static final String I18N_DERIVATIVE = "fix.derivative";
-
-    private static final String I18N_OUTLIER = "fix.outlier";
-
-    private static final String I18N_ANALYSIS = "fix.analysis";
-
-    private static final String I18N_DEVIATION = "fix.deviation";
-
-    private static final String I18N_REFERENCEDEVIATION = "fix.reference.deviation";
-
-    public static final String [] SECTOR_LABELS = {
-        "[0 - (MNQ+MQ)/2)",
-        "[(MNQ+MQ)/2 - (MQ+MHQ)/2)",
-        "[(MQ+MHQ)/2 - HQ5)",
-        "[HQ5 - \u221e)"
-    };
-
-    /**
-     * The default constructor that initializes an empty State object.
-     */
-    public FixationCompute() {
-    }
-
-    @Override
-    public Object computeAdvance(
-        FLYSArtifact artifact,
-        String       hash,
-        CallContext  context,
-        List<Facet>  facets,
-        Object       old
-    ) {
-        log.debug("FixationCompute.computeAdvance");
-
-        CalculationResult res;
-
-        FixationArtifactAccess access =
-            new FixationArtifactAccess(artifact);
-
-        if (old instanceof CalculationResult) {
-            res = (CalculationResult)old;
-        }
-        else {
-            FixCalculation calc = new FixCalculation(access);
-            res = calc.calculate();
-        }
-
-        if (facets == null) {
-            return res;
-        }
-
-        if (res.getReport().hasProblems()) {
-            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, id));
-        }
-
-        FixResult fr = (FixResult)res.getData();
-
-        if (fr == null) {
-            return res;
-        }
-
-        facets.add(
-            new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
-        facets.add(
-            new DataFacet(
-                FIX_PARAMETERS, "parameters", ComputeType.ADVANCE, hash, id));
-
-        int maxId = -100;
-
-        int sectorMask = fr.getUsedSectorsInAnalysisPeriods();
-
-        int qsS = access.getQSectorStart();
-        int qsE = access.getQSectorEnd();
-
-        // TODO: i18n
-        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
-
-        DateRange [] periods = access.getAnalysisPeriods();
-
-        for (int i = 0; i < periods.length; i++) {
-            DateRange period = periods[i];
-            String startDate = df.format(period.getFrom());
-            String endDate = df.format(period.getTo());
-
-            for (int j = qsS; j <= qsE; j++) {
-
-                // Only emit facets for sectors that really have data.
-                if ((sectorMask & (1 << j)) == 0) {
-                    continue;
-                }
-
-                String sector = SECTOR_LABELS[j];
-                String description = sector + ": " +
-                                     startDate + " - " +
-                                     endDate;
-
-                int sectorNdx = j - qsS;
-                int facetNdx = i << 2;
-                facetNdx = facetNdx | j;
-
-                if (facetNdx > maxId) {
-                    maxId = facetNdx;
-                }
-
-                facets.add(
-                    new FixAvSectorFacet(
-                        facetNdx,
-                        FIX_SECTOR_AVERAGE_DWT + "_" + sectorNdx,
-                        description));
-                facets.add(
-                    new FixLongitudinalAnalysisFacet(
-                        facetNdx,
-                        FIX_SECTOR_AVERAGE_LS + "_" + sectorNdx,
-                        description));
-                // TODO: i18n
-                String dev = "Abweichung: " + description;
-                facets.add(
-                    new FixLongitudinalAnalysisFacet(
-                        facetNdx,
-                        FIX_SECTOR_AVERAGE_LS_DEVIATION + "_" + sectorNdx,
-                        dev));
-                facets.add(
-                    new FixAvSectorFacet(
-                        facetNdx,
-                        FIX_SECTOR_AVERAGE_WQ + "_" + sectorNdx,
-                        description));
-
-            }
-
-            String eventDesc =
-                Resources.getMsg(context.getMeta(),
-                                 I18N_ANALYSIS,
-                                 I18N_ANALYSIS) +
-                ": " + startDate + " - " + endDate;
-            facets.add(new FixAnalysisEventsFacet(i,
-                FIX_ANALYSIS_EVENTS_DWT,
-                eventDesc));
-            facets.add(new FixLongitudinalAnalysisFacet(i,
-                FIX_ANALYSIS_EVENTS_LS,
-                eventDesc));
-            facets.add(new FixAnalysisEventsFacet(i,
-                FIX_ANALYSIS_EVENTS_WQ,
-                eventDesc));
-        }
-
-        IdGenerator idg = new IdGenerator(maxId + 1);
-
-        String i18n_ref = Resources.getMsg(context.getMeta(),
-                I18N_REFERENCEPERIOD,
-                I18N_REFERENCEPERIOD);
-        String i18n_dev = Resources.getMsg(context.getMeta(),
-                I18N_REFERENCEDEVIATION,
-                I18N_REFERENCEDEVIATION);
-
-
-        facets.add(new FixReferenceEventsFacet(idg.next(),
-            FIX_REFERENCE_EVENTS_DWT,
-            i18n_ref));
-        facets.add(new FixLongitudinalReferenceFacet(idg.next(),
-            FIX_REFERENCE_EVENTS_LS,
-            i18n_ref));
-        facets.add(new FixReferenceEventsFacet(idg.next(),
-            FIX_REFERENCE_EVENTS_WQ,
-            i18n_ref));
-
-        facets.add(new FixLongitudinalDeviationFacet(idg.next(),
-            FIX_DEVIATION_LS,
-            i18n_dev));
-
-        String i18n_ana = Resources.getMsg(context.getMeta(),
-                I18N_ANALYSISPERIODS,
-                I18N_ANALYSISPERIODS);
-        facets.add(new FixAnalysisPeriodsFacet(idg.next(),
-            FIX_ANALYSIS_PERIODS_DWT,
-            i18n_ana));
-        facets.add(new FixAnalysisPeriodsFacet(idg.next(),
-            FIX_ANALYSIS_PERIODS_LS,
-            i18n_ana));
-        facets.add(new FixAnalysisPeriodsFacet(idg.next(),
-            FIX_ANALYSIS_PERIODS_WQ,
-            i18n_ana));
-
-
-        facets.add(new FixWQCurveFacet(idg.next(), "W/Q"));
-
-        Boolean preprocessing = access.getPreprocessing();
-
-        if (preprocessing != null && preprocessing) {
-            facets.add(new FixOutlierFacet(
-                idg.next(),
-                FIX_OUTLIER,
-                Resources.getMsg(
-                    context.getMeta(), I18N_OUTLIER, I18N_OUTLIER)));
-        }
-
-        facets.add(new FixDerivateFacet(
-            idg.next(),
-            FIX_DERIVATE,
-            Resources.getMsg(
-                context.getMeta(),
-                I18N_DERIVATIVE,
-                I18N_DERIVATIVE)));
-
-        facets.add(new FixDeviationFacet(
-            idg.next(),
-            FIX_DEVIATION_DWT,
-            Resources.getMsg(context.getMeta(),
-                I18N_DEVIATION,
-                I18N_DEVIATION)));
-        return res;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FixationSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FixationSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -26,13 +26,13 @@
     /** Constant value for the default fixation calculation. */
     public static final String CALCULATION_DEFAULT = "calculation.analysis";
 
-    /** Constant value for the volmer fixation analysis. */
-    public static final String CALCULATION_VOLMER = "calculation.volmer";
+    /** Constant value for the vollmer fixation analysis. */
+    public static final String CALCULATION_VOLLMER = "calculation.vollmer";
 
     /** An Array that holds all available calculation modes.*/
     public static final String[] CALCULATIONS = {
         CALCULATION_DEFAULT,
-        CALCULATION_VOLMER
+        CALCULATION_VOLLMER
     };
 
     /** Error message that is thrown if no mode has been chosen. */
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FixationVolmerCompute.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-package de.intevation.flys.artifacts.states.fixation;
-
-import org.apache.log4j.Logger;
-
-import de.intevation.flys.artifacts.states.DefaultState;
-
-
-/**
- * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
- */
-public class FixationVolmerCompute extends DefaultState {
-
-    /** The logger used in this class. */
-    private static Logger logger = Logger.getLogger(FixationVolmerCompute.class);
-
-
-    /**
-     * The default constructor that initializes an empty State object.
-     */
-    public FixationVolmerCompute() {
-    }
-
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FunctionSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/FunctionSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,17 +4,14 @@
 import java.util.Iterator;
 
 import org.apache.log4j.Logger;
-
 import org.w3c.dom.Element;
 
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
-
 import de.intevation.artifacts.common.utils.XMLUtils;
-
-import de.intevation.flys.artifacts.states.DefaultState;
 import de.intevation.flys.artifacts.math.fitting.Function;
 import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
+import de.intevation.flys.artifacts.states.DefaultState;
 
 /**
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
@@ -31,6 +28,10 @@
     public FunctionSelect() {
     }
 
+    @Override
+    public String getUIProvider() {
+        return "fix.functionselect";
+    }
 
     @Override
     protected Element[] createItems(
@@ -40,13 +41,13 @@
         CallContext             context)
     {
         FunctionFactory ff = FunctionFactory.getInstance();
-        Collection fc = ff.getFunctions();
+        Collection<Function> fc = ff.getFunctions();
         Element[] functions = new Element[fc.size()];
-        Iterator i = fc.iterator();
+        Iterator<Function> i = fc.iterator();
 
         int j = 0;
         while(i.hasNext()) {
-            Function f = (Function)i.next();
+            Function f = i.next();
             String n = f.getName();
             String d = f.getDescription();
             functions[j] = createItem(ec, new String[] {d, n});
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/LocationSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/LocationSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -57,5 +57,16 @@
         return STEP;
     }
 
+
+    /** Misuse to set location mode. */
+    @Override
+    public boolean validate(Artifact artifact)
+    throws IllegalArgumentException
+    {
+        ((FLYSArtifact) artifact).addStringData("ld_mode", "distance");
+        return super.validate(artifact);
+    }
+
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/QSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/fixation/QSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -20,6 +20,7 @@
     }
 
 
+    /** Show Q Select Panel in clients. */
     @Override
     protected String getUIProvider() {
         return "fix.qselect_panel";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityPeriodsSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,24 @@
+package de.intevation.flys.artifacts.states.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.artifacts.states.DefaultState;
+
+public class BedQualityPeriodsSelect extends DefaultState {
+
+    /** The logger used in this class. */
+    private static Logger logger = Logger.getLogger(BedQualityPeriodsSelect.class);
+
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public BedQualityPeriodsSelect() {
+    }
+
+    @Override
+    protected String getUIProvider() {
+        return "bedquality_periods_select";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/BedQualityState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,227 @@
+package de.intevation.flys.artifacts.states.minfo;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.BedQualityAccess;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.DateRange;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDensityFacet;
+import de.intevation.flys.artifacts.model.minfo.BedDiameterFacet;
+import de.intevation.flys.artifacts.model.minfo.BedDiameterResult;
+import de.intevation.flys.artifacts.model.minfo.BedParametersResult;
+import de.intevation.flys.artifacts.model.minfo.BedPorosityFacet;
+import de.intevation.flys.artifacts.model.minfo.BedQualityCalculation;
+import de.intevation.flys.artifacts.model.minfo.BedQualityDiameterResult;
+import de.intevation.flys.artifacts.model.minfo.BedQualityResult;
+import de.intevation.flys.artifacts.model.minfo.BedloadDiameterFacet;
+import de.intevation.flys.artifacts.model.minfo.BedloadDiameterResult;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.artifacts.states.DefaultState;
+
+
+public class BedQualityState extends DefaultState implements FacetTypes {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger logger = Logger
+        .getLogger(BedQualityState.class);
+
+    public static final String I18N_TOPLAYER = "bedquality.toplayer";
+    public static final String I18N_SUBLAYER = "bedquality.sublayer";
+
+    public static final String I18N_FACET_BED_POROSITY_TOPLAYER = "facet.bedquality.bed.porosity.toplayer";
+    public static final String I18N_FACET_BED_POROSITY_SUBLAYER = "facet.bedquality.bed.porosity.sublayer";
+    public static final String I18N_FACET_BED_DENSITY_TOPLAYER = "facet.bedquality.bed.density.toplayer";
+    public static final String I18N_FACET_BED_DENSITY_SUBLAYER = "facet.bedquality.bed.density.sublayer";
+    public static final String I18N_FACET_BED_DIAMETER_TOPLAYER = "facet.bedquality.bed.diameter.toplayer";
+    public static final String I18N_FACET_BED_DIAMETER_SUBLAYER = "facet.bedquality.bed.diameter.sublayer";
+    public static final String I18N_FACET_BEDLOAD_DIAMETER = "facet.bedquality.bedload.diameter";
+
+    @Override
+    public Object computeAdvance(FLYSArtifact artifact, String hash,
+        CallContext context, List<Facet> facets, Object old) {
+        logger.debug("BedQualityState.computeAdvance");
+
+        List<Facet> newFacets = new ArrayList<Facet>();
+
+        BedQualityAccess access = new BedQualityAccess(artifact);
+
+        CalculationResult res = old instanceof CalculationResult ? (CalculationResult) old
+            : new BedQualityCalculation().calculate(access);
+
+        if (facets == null || res == null) {
+            return res;
+        }
+
+        BedQualityResult[] results = (BedQualityResult[]) res.getData();
+
+        if (results == null || results.length == 0) {
+            logger.warn("Calculation computed no results!");
+            return res;
+        }
+
+        generateFacets(context, newFacets, results, getID(), hash);
+        logger.debug("Created " + newFacets.size() + " new Facets.");
+
+        facets.addAll(newFacets);
+
+        return res;
+    }
+
+    protected void generateFacets(CallContext context, List<Facet> newFacets,
+        BedQualityResult[] results, String stateId, String hash) {
+        logger.debug("BedQualityState.generateFacets");
+
+        CallMeta meta = context.getMeta();
+
+        newFacets.add(new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
+        for (int idx = 0; idx < results.length; idx++) {
+            BedQualityResult result = results[idx];
+            DateRange range = result.getDateRange();
+            BedDiameterResult[] bedDiameter = result.getBedResults();
+            for (int j = 0; j < bedDiameter.length; j++) {
+                newFacets.add(new BedDiameterFacet((idx << 8) + j,
+                    BED_QUALITY_BED_DIAMETER_TOPLAYER,
+                    createDiameterTopLayerDescription(
+                        meta,
+                        bedDiameter[j],
+                        range),
+                    ComputeType.ADVANCE, stateId, hash));
+
+                newFacets.add(new BedDiameterFacet((idx << 8) +j,
+                    BED_QUALITY_BED_DIAMETER_SUBLAYER,
+                    createDiameterSubLayerDescription(
+                        meta,
+                        bedDiameter[j],
+                        range),
+                    ComputeType.ADVANCE, stateId, hash));
+            }
+            BedloadDiameterResult[] bedloadDiameter = result.getBedloadResults();
+            for (int j = 0;  j < bedloadDiameter.length; j++) {
+                newFacets.add(new BedloadDiameterFacet(
+                    (idx << 8) + j,
+                    BED_QUALITY_BEDLOAD_DIAMETER,
+                    createDiameterDescription(
+                        meta, bedloadDiameter[j]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+
+            }
+            BedParametersResult[] bedParameters = result.getParameters();
+            for (int j = 0; j < bedParameters.length; j++) {
+                newFacets.add(new BedPorosityFacet((idx << 8) + j,
+                    BED_QUALITY_POROSITY_TOPLAYER,
+                    createPorosityTopLayerDescription(
+                        meta,
+                        bedParameters[j],
+                        range),
+                    ComputeType.ADVANCE, stateId, hash));
+
+                newFacets.add(new BedPorosityFacet((idx << 8) + j,
+                    BED_QUALITY_POROSITY_SUBLAYER,
+                    createPorositySubLayerDescription(
+                        meta,
+                        bedParameters[j],
+                        range),
+                    ComputeType.ADVANCE, stateId, hash));
+
+                newFacets.add(new BedDensityFacet((idx << 8) + j,
+                    BED_QUALITY_SEDIMENT_DENSITY_TOPLAYER,
+                    createDensityTopLayerDescription(
+                        meta,
+                        bedParameters[j],
+                        range),
+                    ComputeType.ADVANCE, stateId, hash));
+
+                newFacets.add(new BedDensityFacet((idx << 8) + j,
+                    BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER,
+                    createDensitySubLayerDescription(
+                        meta,
+                        bedParameters[j],
+                        range),
+                    ComputeType.ADVANCE, stateId, hash));
+            }
+        }
+    }
+
+    protected String createPorosityTopLayerDescription(CallMeta meta,
+        BedParametersResult result, DateRange range) {
+        Date from = range != null ? range.getFrom() : new Date();
+        Date to = range != null ? range.getTo() : new Date();
+
+        String toplayer = Resources.getMsg(meta, I18N_TOPLAYER, I18N_TOPLAYER);
+        return Resources.getMsg(meta, I18N_FACET_BED_POROSITY_TOPLAYER,
+            I18N_FACET_BED_POROSITY_TOPLAYER, new Object[] { from, to, toplayer });
+    }
+
+    protected String createPorositySubLayerDescription(CallMeta meta,
+        BedParametersResult result, DateRange range) {
+        Date from = range != null ? range.getFrom() : new Date();
+        Date to = range != null ? range.getTo() : new Date();
+
+        String sublayer = Resources.getMsg(meta, I18N_SUBLAYER, I18N_SUBLAYER);
+        return Resources.getMsg(meta, I18N_FACET_BED_POROSITY_SUBLAYER,
+            I18N_FACET_BED_POROSITY_SUBLAYER, new Object[] { from, to, sublayer });
+    }
+
+    protected String createDensityTopLayerDescription(CallMeta meta,
+        BedParametersResult result, DateRange range) {
+        Date from = range != null ? range.getFrom() : new Date();
+        Date to = range != null ? range.getTo() : new Date();
+
+        String toplayer = Resources.getMsg(meta, I18N_TOPLAYER, I18N_TOPLAYER);
+        return Resources.getMsg(meta, I18N_FACET_BED_DENSITY_TOPLAYER,
+            I18N_FACET_BED_DENSITY_TOPLAYER, new Object[] { from, to, toplayer });
+    }
+
+    protected String createDensitySubLayerDescription(CallMeta meta,
+        BedParametersResult result, DateRange range) {
+        Date from = range != null ? range.getFrom() : new Date();
+        Date to = range != null ? range.getTo() : new Date();
+
+        String sublayer = Resources.getMsg(meta, I18N_SUBLAYER, I18N_SUBLAYER);
+        return Resources.getMsg(meta, I18N_FACET_BED_DENSITY_SUBLAYER,
+            I18N_FACET_BED_DENSITY_SUBLAYER, new Object[] { from, to, sublayer });
+    }
+
+    protected String createDiameterTopLayerDescription(CallMeta meta,
+        BedDiameterResult result, DateRange range) {
+        Date from = range != null ? range.getFrom() : new Date();
+        Date to = range != null ? range.getTo() : new Date();
+
+        String toplayer = Resources.getMsg(meta, I18N_TOPLAYER, I18N_TOPLAYER);
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIAMETER_TOPLAYER,
+            I18N_FACET_BED_DIAMETER_TOPLAYER, new Object[] { result.getType(),
+                from, to, toplayer });
+    }
+
+    protected String createDiameterSubLayerDescription(CallMeta meta,
+        BedDiameterResult result, DateRange range) {
+        Date from = range != null ? range.getFrom() : new Date();
+        Date to = range != null ? range.getTo() : new Date();
+
+        String sublayer = Resources.getMsg(meta, I18N_SUBLAYER, I18N_SUBLAYER);
+        return Resources.getMsg(meta, I18N_FACET_BED_DIAMETER_SUBLAYER,
+            I18N_FACET_BED_DIAMETER_SUBLAYER, new Object[] { result.getType(),
+                from, to, sublayer });
+    }
+
+    protected String createDiameterDescription(CallMeta meta,
+        BedQualityDiameterResult result) {
+        return Resources.getMsg(meta, I18N_FACET_BEDLOAD_DIAMETER,
+            I18N_FACET_BEDLOAD_DIAMETER, new Object[] { result.getType() });
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/CharDiameter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,88 @@
+package de.intevation.flys.artifacts.states.minfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.common.model.KVP;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.artifacts.states.MultiStringArrayState;
+
+public class CharDiameter extends MultiStringArrayState {
+
+    private static final Logger logger = Logger.getLogger(CharDiameter.class);
+
+    public static final String UI_PROVIDER = "parameter-matrix";
+
+    private static final String CHAR_DIAMETER_MIN  = "calc.bed.dmin";
+    private static final String CHAR_DIAMETER_MAX  = "calc.bed.dmax";
+    private static final String CHAR_DIAMETER_90  = "calc.bed.d90";
+    private static final String CHAR_DIAMETER_84  = "calc.bed.d84";
+    private static final String CHAR_DIAMETER_80  = "calc.bed.d80";
+    private static final String CHAR_DIAMETER_75  = "calc.bed.d75";
+    private static final String CHAR_DIAMETER_70  = "calc.bed.d70";
+    private static final String CHAR_DIAMETER_60  = "calc.bed.d60";
+    private static final String CHAR_DIAMETER_50  = "calc.bed.d50";
+    private static final String CHAR_DIAMETER_40  = "calc.bed.d40";
+    private static final String CHAR_DIAMETER_30  = "calc.bed.d30";
+    private static final String CHAR_DIAMETER_25  = "calc.bed.d25";
+    private static final String CHAR_DIAMETER_20  = "calc.bed.d20";
+    private static final String CHAR_DIAMETER_16  = "calc.bed.d16";
+    private static final String CHAR_DIAMETER_10  = "calc.bed.d10";
+
+    public static final String[] CHAR_DIAMETER = {
+        CHAR_DIAMETER_10,
+        CHAR_DIAMETER_16,
+        CHAR_DIAMETER_20,
+        CHAR_DIAMETER_25,
+        CHAR_DIAMETER_30,
+        CHAR_DIAMETER_40,
+        CHAR_DIAMETER_50,
+        CHAR_DIAMETER_60,
+        CHAR_DIAMETER_70,
+        CHAR_DIAMETER_75,
+        CHAR_DIAMETER_80,
+        CHAR_DIAMETER_84,
+        CHAR_DIAMETER_90,
+        CHAR_DIAMETER_MAX,
+        CHAR_DIAMETER_MIN
+    };
+
+    @Override
+    public String getUIProvider() {
+        return UI_PROVIDER;
+    }
+
+    @Override
+    protected KVP<String, String>[] getOptions(
+        Artifact artifact,
+        String parameterName,
+        CallContext context
+    )
+    throws IllegalArgumentException
+    {
+        CallMeta meta   = context.getMeta();
+
+        List<KVP<String, String>> rows = new ArrayList<KVP<String, String>>();
+        String key = parameterName;
+        for (int i = 0; i < CHAR_DIAMETER.length; ++i) {
+            String calc = CHAR_DIAMETER[i];
+            rows.add(new KVP (calc,
+                              Resources.getMsg(meta, calc, calc)));
+        }
+
+        return rows.toArray(new KVP[rows.size()]);
+    }
+
+    @Override
+    protected String getLabelFor(CallContext cc, String parameterName,
+            String value) throws IllegalArgumentException {
+
+        return Resources.getMsg(cc.getMeta(), value, value);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/DifferenceSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,139 @@
+package de.intevation.flys.artifacts.states.minfo;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.BedHeightAccess;
+import de.intevation.flys.artifacts.states.DefaultState;
+import de.intevation.flys.utils.StringUtil;
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class DifferenceSelect extends DefaultState {
+
+    /** The logger used in this class. */
+    private static Logger logger = Logger.getLogger(DifferenceSelect.class);
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public DifferenceSelect() {
+    }
+    /**
+     *  Specify to display nothing (this is kind of a "final" state).
+     */
+    @Override
+    protected String getUIProvider() {
+        return "bedheights_twin_panel";
+    }
+
+    /**
+     * Overridden to do nothing.
+     */
+    @Override
+    public Object computeAdvance(
+        FLYSArtifact artifact,
+        String       hash,
+        CallContext  context,
+        List<Facet>  facets,
+        Object       old
+    ) {
+        //Get data and do stuff, do not calculate
+        return "";
+    }
+
+    @Override
+    protected Element[] createItems(
+        XMLUtils.ElementCreator ec,
+        Artifact                artifact,
+        String                  name,
+        CallContext             context)
+    {
+        Element[] elements = new Element[1];
+        BedHeightAccess bha = new BedHeightAccess((FLYSArtifact)artifact);
+        String time = bha.getYearEpoch();
+        elements[0] = createItem(
+            ec,
+            new String[] {"year-epoch", time});
+
+        return elements;
+    }
+
+    /**
+     * Creates the data element used for the static part of DESCRIBE document.
+     */
+    @Override
+    protected Element createStaticData(
+        FLYSArtifact   flys,
+        ElementCreator creator,
+        CallContext    cc,
+        String         name,
+        String         value,
+        String         type
+    ) {
+        Element dataElement = creator.create("data");
+        creator.addAttr(dataElement, "name", name, true);
+        creator.addAttr(dataElement, "type", type, true);
+
+        Element itemElement = creator.create("item");
+        creator.addAttr(itemElement, "value", value, true);
+
+        String[] labels = getLabels(cc, value);
+
+        creator.addAttr(
+            itemElement,
+            "label",
+            labels[0],
+            true);
+        dataElement.appendChild(itemElement);
+
+        return dataElement;
+    }
+
+
+    /**
+     * Get name to display for selected watelerlevels (for example "Q=123")
+     * from the CalculationResult.
+     */
+    public static String[] getLabels(CallContext cc, String value) {
+        String[] recommendations = value.split("#");
+        String displayString = "";
+
+        // Walk over all selected recommendations and create label
+        for (int i = 0; i < recommendations.length; i+=2) {
+            String[] minuendParts = StringUtil
+                .unbracket(recommendations[i+0])
+                .split(";");
+            if(minuendParts.length >= 4) {
+                displayString += "(" + minuendParts[3];
+            }
+            else {
+                displayString += "([error]";
+            }
+
+            displayString += " - ";
+
+            String[] subtrahendParts = StringUtil
+                .unbracket(recommendations[i+1])
+                .split(";");
+            if(subtrahendParts.length >= 4) {
+                displayString += subtrahendParts[3] + ") ";
+            }
+            else {
+                displayString += "[error])";
+            }
+        }
+
+        return new String[] { displayString };
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,248 @@
+package de.intevation.flys.artifacts.states.minfo;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.BedDifferencesAccess;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffCalculation;
+import de.intevation.flys.artifacts.model.minfo.BedDiffEpochFacet;
+import de.intevation.flys.artifacts.model.minfo.BedDiffEpochResult;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearFacet;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
+import de.intevation.flys.artifacts.model.minfo.BedDifferencesResult;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.artifacts.states.DefaultState;
+import de.intevation.flys.utils.Formatter;
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class DifferencesState
+extends DefaultState
+implements FacetTypes
+{
+    /** The logger used in this class. */
+    private static Logger logger = Logger.getLogger(DifferencesState.class);
+    public static final String I18N_DIFF_YEAR = "beddifference.year";
+    public static final String I18N_DIFF_EPOCH = "beddifference.epoch";
+
+    public static final String I18N_FACET_BED_DIFF_YEAR = "facet.bedheight.diff.year";
+    public static final String I18N_FACET_BED_DIFF_ABSOLUTE = "facet.bedheight.diff.absolute";
+    public static final String I18N_FACET_BED_DIFF_MORPH = "facet.bedheight.diff.morph";
+    public static final String I18N_FACET_BED_DIFF_EPOCH = "facet.bedheight.diff.epoch";
+    public static final String I18N_FACET_BED_DIFF_HEIGHT1 = "facet.bedheight.diff.height1";
+    public static final String I18N_FACET_BED_DIFF_HEIGHT2 = "facet.bedheight.diff.height2";
+
+    public DifferencesState() {
+    }
+
+    @Override
+    public Object computeAdvance(FLYSArtifact artifact, String hash,
+        CallContext context, List<Facet> facets, Object old) {
+        logger.debug("BedQualityState.computeAdvance");
+
+        List<Facet> newFacets = new ArrayList<Facet>();
+
+        BedDifferencesAccess access =
+            new BedDifferencesAccess(artifact, context);
+
+        CalculationResult res = old instanceof CalculationResult ? (CalculationResult) old
+            : new BedDiffCalculation().calculate(access);
+
+        if (facets == null || res == null) {
+            return res;
+        }
+
+        BedDifferencesResult[] results = (BedDifferencesResult[]) res.getData();
+
+        if (results == null || results.length == 0) {
+            logger.warn("Calculation computed no results!");
+            return res;
+        }
+
+        generateFacets(context, newFacets, results, getID(), hash);
+        logger.debug("Created " + newFacets.size() + " new Facets.");
+
+        facets.addAll(newFacets);
+
+        return res;
+    }
+
+    protected void generateFacets(CallContext context, List<Facet> newFacets,
+        BedDifferencesResult[] results, String stateId, String hash) {
+        logger.debug("BedQualityState.generateFacets");
+
+        CallMeta meta = context.getMeta();
+
+        for (int idx = 0; idx < results.length; idx++) {
+            if (results[idx] instanceof BedDiffYearResult) {
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_YEAR,
+                    createBedDiffYearDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_MORPH_WIDTH,
+                    createBedDiffMorphDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_YEAR_HEIGHT1,
+                    createBedDiffHeightDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx],
+                        0),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                 newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_YEAR_HEIGHT2,
+                    createBedDiffHeightDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx],
+                        1),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_HEIGHT_YEAR,
+                    createBedDiffAbsoluteDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (results[idx] instanceof BedDiffEpochResult) {
+                newFacets.add(new BedDiffEpochFacet(
+                    idx,
+                    BED_DIFFERENCE_EPOCH,
+                    createBedDiffEpochDescription(
+                        meta,
+                        (BedDiffEpochResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffEpochFacet(
+                    idx,
+                    BED_DIFFERENCE_EPOCH_HEIGHT1,
+                    createBedDiffHeightEpochDescription(
+                        meta,
+                        (BedDiffEpochResult)results[idx],
+                        0),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffEpochFacet(
+                    idx,
+                    BED_DIFFERENCE_EPOCH_HEIGHT2,
+                    createBedDiffHeightEpochDescription(
+                        meta,
+                        (BedDiffEpochResult)results[idx],
+                        1),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+
+            }
+        }
+    }
+
+    private String createBedDiffHeightDescription(
+        CallMeta meta,
+        BedDiffYearResult result,
+        int ndx
+    ) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        if (ndx == 0) {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT1,
+                I18N_FACET_BED_DIFF_HEIGHT1, new Object[] { range });
+        }
+        else {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT2,
+                I18N_FACET_BED_DIFF_HEIGHT2, new Object[] {range});
+        }
+    }
+
+    private String createBedDiffHeightEpochDescription(
+        CallMeta meta,
+        BedDiffEpochResult result,
+        int ndx
+    ) {
+        DateFormat df = Formatter.getDateFormatter(meta, "yyyy");
+        String range =
+            df.format(result.getStart())
+            + " - " +
+            df.format(result.getEnd());
+
+        if (ndx == 0) {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT1,
+                I18N_FACET_BED_DIFF_HEIGHT1, new Object[] { range });
+        }
+        else {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT2,
+                I18N_FACET_BED_DIFF_HEIGHT2, new Object[] {range});
+        }
+    }
+
+    protected String createBedDiffYearDescription(
+        CallMeta meta,
+        BedDiffYearResult result) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_YEAR,
+            I18N_FACET_BED_DIFF_YEAR, new Object[] { range });
+    }
+
+    protected String createBedDiffMorphDescription(
+        CallMeta meta,
+        BedDiffYearResult result) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_MORPH,
+            I18N_FACET_BED_DIFF_MORPH, new Object[] { range });
+    }
+
+    protected String createBedDiffAbsoluteDescription(
+        CallMeta meta,
+        BedDiffYearResult result) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_ABSOLUTE,
+            I18N_FACET_BED_DIFF_ABSOLUTE, new Object[] { range });
+    }
+
+    protected String createBedDiffEpochDescription(
+        CallMeta meta,
+        BedDiffEpochResult result) {
+        DateFormat df = Formatter.getDateFormatter(meta, "yyyy");
+        String range =
+            df.format(result.getStart())
+            + " - " +
+            df.format(result.getEnd());
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_EPOCH,
+            I18N_FACET_BED_DIFF_EPOCH, new Object[] { range });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/YearEpochSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,59 @@
+package de.intevation.flys.artifacts.states.minfo;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.artifacts.states.DefaultState;
+
+/**
+ * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
+ */
+public class YearEpochSelect extends DefaultState {
+    /** The logger used in this class. */
+    private static Logger logger = Logger.getLogger(YearEpochSelect.class);
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public YearEpochSelect() {
+    }
+
+    @Override
+    protected String getUIProvider() {
+        return "minfo.bed.year_epoch";
+    }
+
+    @Override
+    protected Element[] createItems(
+        XMLUtils.ElementCreator ec,
+        Artifact                artifact,
+        String                  name,
+        CallContext             context)
+    {
+        CallMeta meta = context.getMeta();
+        Element[] elements = new Element[2];
+        elements[0] = createItem(
+                ec,
+                new String[] {
+                    Resources.getMsg(meta,
+                        "state.minfo.year",
+                        "state.minfo.year"),
+                    "year"});
+
+        elements[1] = createItem(
+            ec,
+            new String[] {
+                Resources.getMsg(meta,
+                    "state.minfo.epoch",
+                    "state.minfo.epoch"),
+                "epoch"});
+
+        return elements;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/sq/SQPeriodSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,17 @@
+package de.intevation.flys.artifacts.states.sq;
+
+import de.intevation.flys.artifacts.states.PeriodsSelect;
+
+public class SQPeriodSelect extends PeriodsSelect {
+
+    public static final String UI_PROVIDER = "sq.period.select";
+
+    private static final long serialVersionUID = 1L;
+
+
+    @Override
+    public String getUIProvider() {
+        return UI_PROVIDER;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/collections/AttributeWriter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/AttributeWriter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -11,6 +11,7 @@
 import de.intevation.artifacts.ArtifactDatabaseException;
 
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.FacetActivity;
 import de.intevation.artifactdatabase.state.Output;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
@@ -90,11 +91,13 @@
      * @return document with merged outputs as described.
      */
     protected CollectionAttribute write() {
+
+        boolean debug = logger.isDebugEnabled();
+
         for (Map.Entry<String, Output> entry: newAttr.entrySet()) {
             String outName = entry.getKey();
             Output a       = entry.getValue();
 
-
             Output exists = attribute.getOutput(outName);
             if (exists == null) {
                 attribute.addOutput(outName, a);
@@ -102,7 +105,7 @@
 
             attribute.clearFacets(outName);
 
-            if (logger.isDebugEnabled()) {
+            if (debug) {
                 logger.debug("Merge Output: " + outName);
                 logger.debug("   old Facets: " + oldFacets.size());
                 logger.debug("   new Facets: " + newFacets.size());
@@ -153,10 +156,10 @@
      * @return true if any facets are written to the out.
      */
     protected boolean writeFacets(
-        String         outputName,
-        List<Facet>    newFacets,
-        List<Facet>    oldFacets,
-        List<String>   compatibleFacets)
+        String        outputName,
+        List<Facet>   newFacets,
+        List<Facet>   oldFacets,
+        List<String>  compatibleFacets)
     throws ArtifactDatabaseException
     {
         if (compatibleFacets == null) {
@@ -171,10 +174,14 @@
         List<ManagedFacet> currentFacets      = new ArrayList<ManagedFacet>();
         List<ManagedFacet> genuinelyNewFacets = new ArrayList<ManagedFacet>();
 
+        boolean debug = logger.isDebugEnabled();
+
         for (int i = 0; i < num; i++) {
             ManagedFacet facet = (ManagedFacet) newFacets.get(i);
 
-            logger.debug("Try to add Facet: " + facet.getName());
+            if (debug) {
+                logger.debug("Try to add Facet: " + facet.getName());
+            }
 
             if (!compatibleFacets.contains(facet.getName())) {
                 //logger.debug("Have incompatible facet, skip: " + facet.getName());
@@ -192,14 +199,18 @@
             }
         }
 
-        // With each genuinely new Facet, ask Artifact whether it comes to live
+        FacetActivity.Registry registry = FacetActivity.Registry.getInstance();
+
+        // With each genuinely new Facet, figure out whether it comes to live
         // in/activate.
         for (ManagedFacet newMF: genuinelyNewFacets) {
-            FLYSArtifact flys = (FLYSArtifact) db.getRawArtifact(newMF.getArtifact());
-            newMF.setActive(flys.getInitialFacetActivity(
-                outputName,
-                newMF.getName(),
-                newMF.getIndex()));
+            FLYSArtifact flys =
+                (FLYSArtifact)db.getRawArtifact(newMF.getArtifact());
+
+            boolean isActive = registry.isInitialActive(
+                flys.getName(), flys, newMF, outputName);
+
+            newMF.setActive(isActive ? 1 : 0);
         }
 
         // For each genuinely new Facet check positional conflicts.
@@ -211,8 +222,12 @@
                 for (ManagedFacet oldMF: currentFacets) {
                     if (newMF.getPosition() == oldMF.getPosition()) {
                         conflicts = true;
-                        logger.debug("Positional conflict while merging " +
-                            "facets, pushing newest facet 1 up (" + newMF.getPosition() + ")");
+                        if (debug) {
+                            logger.debug(
+                                "Positional conflict while merging " +
+                                "facets, pushing newest facet 1 up (" +
+                                newMF.getPosition() + ")");
+                        }
                         newMF.setPosition(newMF.getPosition() + 1);
                         break;
                     }
@@ -224,7 +239,8 @@
         // Fill/correct "gaps" (e.g. position 1,2,5 are taken, after gap filling
         // expect positions 1,2,3 [5->3])
         // Preparations to be able to detect gaps.
-        Map<Integer, ManagedFacet> mfmap = new HashMap<Integer, ManagedFacet>();
+        Map<Integer, ManagedFacet> mfmap =
+            new HashMap<Integer, ManagedFacet>();
         int max = 0;
         for (ManagedFacet mf: currentFacets) {
             int pos = mf.getPosition();
@@ -250,7 +266,7 @@
             attribute.addFacet(outputName, oldMF);
         }
 
-        return currentFacets.size() > 0;
+        return !currentFacets.isEmpty();
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionAttribute.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionAttribute.java	Fri Sep 28 12:15:40 2012 +0200
@@ -23,12 +23,12 @@
 import de.intevation.artifactdatabase.state.Settings;
 
 
+/** Create attribute part of collection document. */
 public class CollectionAttribute {
 
     private static final Logger logger =
         Logger.getLogger(CollectionAttribute.class);
 
-
     protected ElementCreator ec;
 
     protected Map<String, Output> outputMap;
@@ -183,7 +183,7 @@
             return null;
         }
 
-        if (outputMap == null || outputMap.size() == 0) {
+        if (outputMap == null || outputMap.isEmpty()) {
             logger.warn("Tried to retrieve Output, but no Outputs existing.");
             return null;
         }
@@ -217,7 +217,7 @@
     public List<Facet> getFacets() {
         List<Facet> allFacets = new ArrayList<Facet>();
 
-        if (outputMap == null || outputMap.size() == 0) {
+        if (outputMap == null || outputMap.isEmpty()) {
             logger.warn("No Outputs existing.");
             return allFacets;
         }
@@ -233,7 +233,7 @@
 
 
     protected void appendOutputs(Element root) {
-        if (outputMap == null || outputMap.size() == 0) {
+        if (outputMap == null || outputMap.isEmpty()) {
             logger.warn("No outputs to append.");
             return;
         }
@@ -281,7 +281,7 @@
 
 
     protected void appendFacets(Element root, List<Facet> facets) {
-        if (facets == null || facets.size() == 0) {
+        if (facets == null || facets.isEmpty()) {
             logger.warn("Tried to append 0 Facets.");
             return;
         }
--- a/flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/CollectionDescriptionHelper.java	Fri Sep 28 12:15:40 2012 +0200
@@ -6,18 +6,16 @@
 
 import javax.xml.xpath.XPathConstants;
 
+import org.apache.log4j.Logger;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-import org.apache.log4j.Logger;
-
 import de.intevation.artifacts.ArtifactDatabase;
 import de.intevation.artifacts.ArtifactDatabaseException;
 import de.intevation.artifacts.ArtifactNamespaceContext;
 import de.intevation.artifacts.CallContext;
-
 import de.intevation.artifacts.common.utils.XMLUtils;
 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
 
@@ -63,20 +61,17 @@
         long        ttl,
         CallContext callContext
     ) {
-        this.name     = name;
-        this.uuid     = uuid;
-        this.creation = creation;
-        this.ttl      = ttl;
-        this.context  = callContext;
-        this.database = callContext.getDatabase();
+        this.name      = name;
+        this.uuid      = uuid;
+        this.creation  = creation;
+        this.ttl       = ttl;
+        this.context   = callContext;
+        this.database  = callContext.getDatabase();
+        this.artifacts = new ArrayList<String>();
     }
 
 
     public void addArtifact(String uuid) {
-        if (artifacts == null) {
-            artifacts = new ArrayList<String>();
-        }
-
         if (uuid != null && uuid.length() > 0) {
             artifacts.add(uuid);
         }
@@ -197,10 +192,12 @@
 
 
     protected void appendAttribute(Element root) {
-        Document owner = root.getOwnerDocument();
-        Document attr  = attribute.toXML();
+        if (attribute != null) {
+            Document owner = root.getOwnerDocument();
+            Document attr  = attribute.toXML();
 
-        root.appendChild(owner.importNode(attr.getFirstChild(), true));
+            root.appendChild(owner.importNode(attr.getFirstChild(), true));
+        }
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -11,33 +11,28 @@
 import javax.xml.xpath.XPathConstants;
 
 import org.apache.log4j.Logger;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-import de.intevation.artifacts.Artifact;
-import de.intevation.artifacts.ArtifactDatabase;
-import de.intevation.artifacts.ArtifactDatabaseException;
-import de.intevation.artifacts.ArtifactNamespaceContext;
-import de.intevation.artifacts.CallContext;
-import de.intevation.artifacts.CallMeta;
-
-import de.intevation.artifacts.common.utils.XMLUtils;
-
 import de.intevation.artifactdatabase.Backend;
 import de.intevation.artifactdatabase.Backend.PersistentArtifact;
 import de.intevation.artifactdatabase.DefaultArtifactCollection;
 import de.intevation.artifactdatabase.state.Output;
 import de.intevation.artifactdatabase.state.Settings;
 import de.intevation.artifactdatabase.state.StateEngine;
-
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.ArtifactDatabase;
+import de.intevation.artifacts.ArtifactDatabaseException;
+import de.intevation.artifacts.ArtifactNamespaceContext;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.context.FLYSContext;
-import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.exports.OutGenerator;
 import de.intevation.flys.exports.OutputHelper;
-
 import de.intevation.flys.utils.FLYSUtils;
 
 /**
@@ -131,6 +126,11 @@
         CollectionAttribute cAttribute =
             buildOutAttributes(db, context, oldParser, uuids);
 
+        if (cAttribute == null) {
+            log.warn("mergeAttributes: cAttribute == null");
+            return null;
+        }
+
         cAttribute.setLoadedRecommendations(
             getLoadedRecommendations(oldParser.getAttributeDocument()));
 
@@ -220,7 +220,7 @@
      * Merge the recommendations which have already been loaded from the old
      * attribute document into the new attribute document. This is necessary,
      * because mergeAttributes() only merges the art:outputs nodes - all
-     * other nodes are skiped.
+     * other nodes are skipped.
      */
     protected Node getLoadedRecommendations(Document oldAttrs) {
         Element loadedRecoms = (Element) XMLUtils.xpath(
@@ -252,7 +252,7 @@
             ? attribute.getOutputs()
             : null;
 
-        if (outputMap == null || outputMap.size() == 0) {
+        if (outputMap == null || outputMap.isEmpty()) {
             log.debug("No Output Settings check necessary.");
             return modified;
         }
@@ -378,6 +378,7 @@
 
         generator.init(format, out, context);
         generator.setSettings(settings);
+        generator.setCollection(this);
         prepareMasterArtifact(generator, context);
 
         try {
@@ -454,18 +455,21 @@
         AttributeParser  aParser,
         String[]         uuids)
     {
-        Document doc = XMLUtils.newDocument();
-
         FLYSContext flysContext = FLYSUtils.getFlysContext(context);
         StateEngine engine = (StateEngine) flysContext.get(
-        FLYSContext.STATE_ENGINE_KEY);
+            FLYSContext.STATE_ENGINE_KEY);
+
+        if (engine == null) {
+            log.error("buildOutAttributes: engine == null");
+            return null;
+        }
 
         FLYSArtifact masterArtifact = getMasterArtifact(context);
 
-        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
-            doc,
-            ArtifactNamespaceContext.NAMESPACE_URI,
-            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+        if (masterArtifact == null) {
+            log.debug("buildOutAttributes: masterArtifact == null");
+            return null;
+        }
 
         OutputParser oParser = new OutputParser(db, context);
 
@@ -482,7 +486,7 @@
 
         aParser.parse();
 
-        return new AttributeWriter(
+        AttributeWriter aWriter = new AttributeWriter(
             db,
             aParser.getCollectionAttribute(),
             aParser.getOuts(),
@@ -490,7 +494,8 @@
             oParser.getOuts(),
             oParser.getFacets(),
             engine.getCompatibleFacets(masterArtifact.getStateHistoryIds())
-            ).write();
+            );
+        return aWriter.write();
     }
 
 
@@ -579,7 +584,7 @@
             }
         }
 
-        return (String[]) uuids.toArray(new String[uuids.size()]);
+        return uuids.toArray(new String[uuids.size()]);
     }
 
 
@@ -603,7 +608,5 @@
     }
 
 
-
-
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ATExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ATExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -17,6 +17,7 @@
 import de.intevation.flys.artifacts.FLYSArtifact;
 
 import de.intevation.flys.artifacts.model.WQ;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 
 import de.intevation.flys.utils.FLYSUtils;
 
@@ -33,6 +34,9 @@
     protected OutputStream out;
     protected FLYSArtifact master;
 
+    protected FLYSArtifactCollection collection;
+
+
     public ATExporter() {
     }
 
@@ -42,12 +46,18 @@
         this.out     = out;
     }
 
+
     @Override
     public void setMasterArtifact(Artifact master) {
         this.master = (FLYSArtifact) master;
     }
 
     @Override
+    public void setCollection(FLYSArtifactCollection collection) {
+        this.collection = collection;
+    }
+
+    @Override
     public void doOut(
         ArtifactAndFacet artifactf,
         Document attr,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/AbstractExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/AbstractExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -22,6 +22,7 @@
 import de.intevation.artifacts.common.utils.XMLUtils;
 
 import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 
 import de.intevation.flys.utils.Formatter;
 
@@ -67,6 +68,9 @@
     /** The selected facet. */
     protected String facet;
 
+    /** The collection.*/
+    protected FLYSArtifactCollection collection;
+
     /** The master artifact. */
     protected Artifact master;
 
@@ -113,6 +117,12 @@
     }
 
 
+    @Override
+    public void setCollection(FLYSArtifactCollection collection) {
+        this.collection = collection;
+    }
+
+
     /**
      * This doOut() just collects the data of multiple artifacts. Therefore, it
      * makes use of the addData() method which enables concrete subclasses to
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -10,6 +10,7 @@
 import de.intevation.artifacts.common.utils.XMLUtils;
 import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 import de.intevation.flys.jfree.Bounds;
 import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
 import de.intevation.flys.jfree.DoubleBounds;
@@ -21,6 +22,8 @@
 import de.intevation.flys.jfree.StyledAreaSeriesCollection;
 import de.intevation.flys.jfree.StyledSeries;
 import de.intevation.flys.model.River;
+import de.intevation.flys.themes.LineStyle;
+import de.intevation.flys.themes.TextStyle;
 import de.intevation.flys.themes.ThemeAccess;
 import de.intevation.flys.utils.FLYSUtils;
 import de.intevation.flys.utils.ThemeUtil;
@@ -53,6 +56,7 @@
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.chart.title.TextTitle;
 import org.jfree.data.Range;
 import org.jfree.data.general.Series;
 import org.jfree.data.xy.XYDataset;
@@ -61,6 +65,7 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import de.intevation.flys.utils.Formatter;
 
 /**
  * The base class for chart creation. It should provide some basic things that
@@ -104,6 +109,8 @@
     /** The CallContext object.*/
     protected CallContext context;
 
+    protected FLYSArtifactCollection collection;
+
     /** The artifact that is used to decorate the chart with meta information.*/
     protected Artifact master;
 
@@ -175,8 +182,8 @@
         StickyAxisAnnotation annotation,
         XYPlot plot,
         ChartArea area,
-        ThemeAccess.LineStyle lineStyle,
-        ThemeAccess.TextStyle textStyle,
+        LineStyle lineStyle,
+        TextStyle textStyle,
         Document theme
     ) {
         // OPTIMIZE pre-calculate area-related values
@@ -297,7 +304,7 @@
      * @param lineStyle the line style to use for the line.
      */
     protected static XYLineAnnotation createGroundStickAnnotation(
-        ChartArea area, float pos, ThemeAccess.LineStyle lineStyle
+        ChartArea area, float pos, LineStyle lineStyle
     ) {
         // Style the line.
         if (lineStyle != null) {
@@ -321,7 +328,7 @@
      * @param lineStyle the line style to use for the line.
      */
     protected static XYLineAnnotation createRightStickAnnotation(
-        ChartArea area, float pos, ThemeAccess.LineStyle lineStyle
+        ChartArea area, float pos, LineStyle lineStyle
     ) {
         // Style the line.
         if (lineStyle != null) {
@@ -345,7 +352,7 @@
      * @param lineStyle the line style to use for the line.
      */
     protected static XYLineAnnotation createLeftStickAnnotation(
-        ChartArea area, float pos, ThemeAccess.LineStyle lineStyle
+        ChartArea area, float pos, LineStyle lineStyle
     ) {
         // Style the line.
         if (lineStyle != null) {
@@ -372,7 +379,7 @@
      */
     protected static XYLineAnnotation createStickyLineAnnotation(
         StickyAxisAnnotation.SimpleAxis axis, float fromD1, float toD2,
-        ChartArea area, ThemeAccess.LineStyle lineStyle
+        ChartArea area, LineStyle lineStyle
     ) {
         double anchorX1 = 0d, anchorX2 = 0d, anchorY1 = 0d, anchorY2 = 0d;
         switch(axis) {
@@ -417,7 +424,7 @@
     protected void addAnnotationsToRenderer(XYPlot plot) {
         logger.debug("addAnnotationsToRenderer");
 
-        if (annotations == null || annotations.size() == 0) {
+        if (annotations == null || annotations.isEmpty()) {
             logger.debug("addAnnotationsToRenderer: no annotations.");
             return;
         }
@@ -432,8 +439,8 @@
 
             // Access text styling, if any.
             Document theme = fa.getTheme();
-            ThemeAccess.TextStyle textStyle = null;
-            ThemeAccess.LineStyle lineStyle = null;
+            TextStyle textStyle = null;
+            LineStyle lineStyle = null;
 
             // Get Themeing information and add legend item.
             if (theme != null) {
@@ -570,13 +577,21 @@
 
 
     /**
-     * This method should be used by concrete subclasses to add subtitle to
-     * <i>chart</i>. <b>The method in this implementation is empty</b>.
+     * This method retrieves the chart subtitle by calling getChartSubtitle()
+     * and adds it as TextTitle to the chart.
+     * The default implementation of getChartSubtitle() returns the same
+     * as getDefaultChartSubtitle() which must be implemented by derived
+     * classes. If you want to add multiple subtitles to the chart override
+     * this method and add your subtitles manually.
      *
      * @param chart The JFreeChart chart object.
      */
     protected void addSubtitles(JFreeChart chart) {
-        // do nothing
+        String subtitle = getChartSubtitle();
+
+        if (subtitle != null && subtitle.length() > 0) {
+            chart.addSubtitle(new TextTitle(subtitle));
+        }
     }
 
 
@@ -686,6 +701,12 @@
 
 
     @Override
+    public void setCollection(FLYSArtifactCollection collection) {
+        this.collection = collection;
+    }
+
+
+    @Override
     public void setSettings(Settings settings) {
         this.settings = settings;
     }
@@ -731,7 +752,10 @@
         ChartSection chartSection = new ChartSection();
         chartSection.setTitle(getChartTitle());
         chartSection.setSubtitle(getChartSubtitle());
-        chartSection.setDisplayGird(isGridVisible());
+        chartSection.setDisplayGrid(isGridVisible());
+        chartSection.setDisplayLogo(showLogo());
+        chartSection.setLogoVPlacement(logoVPlace());
+        chartSection.setLogoHPlacement(logoHPlace());
         return chartSection;
     }
 
@@ -1008,6 +1032,55 @@
     }
 
 
+    /** Where to place the logo. */
+    protected String logoHPlace() {
+        ChartSettings chartSettings = getChartSettings();
+        if (chartSettings != null) {
+            ChartSection cs    = chartSettings.getChartSection();
+            String       place = cs.getLogoHPlacement();
+
+            return place;
+        }
+        return "center";
+    }
+
+
+    /** Where to place the logo. */
+    protected String logoVPlace() {
+        ChartSettings chartSettings = getChartSettings();
+        if (chartSettings != null) {
+            ChartSection cs    = chartSettings.getChartSection();
+            String       place = cs.getLogoVPlacement();
+
+            return place;
+        }
+        return "top";
+    }
+
+
+    /** Return the logo id from settings. */
+    protected String showLogo(ChartSettings chartSettings) {
+        if (chartSettings != null) {
+            ChartSection cs   = chartSettings.getChartSection();
+            String       logo = cs.getDisplayLogo();
+
+            return logo;
+        }
+        return "none";
+    }
+
+
+    /**
+     * This method is used to determine if a logo should be added to the plot.
+     *
+     * @return logo name (null if none).
+     */
+    protected String showLogo() {
+        ChartSettings chartSettings = getChartSettings();
+        return showLogo(chartSettings);
+    }
+
+
     /**
      * This method is used to determine the font size of the chart's legend. If
      * a <i>settings</i> instance is set, this instance determines the font
@@ -1597,6 +1670,12 @@
 
         area.applyTheme(dRenderer);
 
+        // i18n
+        dRenderer.setAreaLabelNumberFormat(Formatter.getFormatter(context.getMeta(), 2, 4));
+
+        dRenderer.setAreaLabelTemplate(Resources.getMsg(
+            context.getMeta(), "area.label.template", "Area=%sm2"));
+
         LegendItem legendItem = dRenderer.getLegendItem(idx, 0);
         if (legendItem != null) {
             legendItem.setLabelFont(legendFont);
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,5 +1,6 @@
 package de.intevation.flys.exports;
 
+import de.intevation.flys.collections.FLYSArtifactCollection;
 import de.intevation.flys.java2d.NOPGraphics2D;
 
 import java.io.IOException;
@@ -86,6 +87,16 @@
 
     /**
      * Dispatches the operation to the instantiated generator.
+     *
+     * @param collection The collection.
+     */
+    public void setCollection(FLYSArtifactCollection collection) {
+        generator.setCollection(collection);
+    }
+
+
+    /**
+     * Dispatches the operation to the instantiated generator.
      */
     public void doOut(
         ArtifactAndFacet artifactFacet,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartSection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartSection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,5 +1,6 @@
 package de.intevation.flys.exports;
 
+import org.apache.log4j.Logger;
 
 
 /**
@@ -7,9 +8,14 @@
  */
 public class ChartSection extends TypeSection {
 
-    public static final String TITLE_ATTR       = "title";
-    public static final String SUBTITLE_ATTR    = "subtitle";
-    public static final String DISPLAYGRID_ATTR = "display-grid";
+    private static Logger logger = Logger.getLogger(ChartSection.class);
+
+    public static final String TITLE_ATTR         = "title";
+    public static final String SUBTITLE_ATTR      = "subtitle";
+    public static final String DISPLAYGRID_ATTR   = "display-grid";
+    public static final String DISPLAYLOGO_ATTR   = "display-logo";
+    public static final String LOGOPLACEMENTH_ATTR = "logo-placeh";
+    public static final String LOGOPLACEMENTV_ATTR = "logo-placev";
 
 
     public ChartSection() {
@@ -37,7 +43,44 @@
     }
 
 
-    public void setDisplayGird(boolean displayGrid) {
+    /** Get Property-value for display-logo property. */
+    public String getDisplayLogo() {
+        return getStringValue(DISPLAYLOGO_ATTR);
+    }
+
+
+    /** Set Property-value for display-logo property. */
+    public void setDisplayLogo(String logo) {
+        logger.debug("Setting Display logo string.");
+        setChoiceStringValue(DISPLAYLOGO_ATTR, logo, "logo");
+    }
+
+
+    /** Get Property-value for horizontal logo-placement property. */
+    public String getLogoHPlacement() {
+        return getStringValue(LOGOPLACEMENTH_ATTR);
+    }
+
+
+    /** Set Property-value for horizontal logo-placement property. */
+    public void setLogoHPlacement(String place) {
+        setChoiceStringValue(LOGOPLACEMENTH_ATTR, place, "placeh");
+    }
+
+
+    /** Get Property-value for vertical logo-placement property. */
+    public String getLogoVPlacement() {
+        return getStringValue(LOGOPLACEMENTV_ATTR);
+    }
+
+
+    /** Set Property-value for vertical logo-placement property. */
+    public void setLogoVPlacement(String place) {
+        setChoiceStringValue(LOGOPLACEMENTV_ATTR, place, "placev");
+    }
+
+
+    public void setDisplayGrid(boolean displayGrid) {
         setBooleanValue(DISPLAYGRID_ATTR, displayGrid);
     }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartSettings.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartSettings.java	Fri Sep 28 12:15:40 2012 +0200
@@ -215,31 +215,44 @@
 
         section.setIdentifier(id);
         section.setLabel(label);
-        section.setFontSize(Integer.valueOf(fSize.length() > 0 ? fSize : "-1"));
+        section.setFontSize(Integer.parseInt(fSize.length() > 0 ? fSize : "-1"));
         section.setFixed(Boolean.valueOf(fixation));
-        section.setLowerRange(Double.valueOf(low.length() > 0 ? low : "0"));
-        section.setUpperRange(Double.valueOf(up.length() > 0 ? up : "0"));
+        section.setLowerRange(Double.parseDouble(low.length() > 0 ? low : "0"));
+        section.setUpperRange(Double.parseDouble(up.length() > 0 ? up : "0"));
 
         target.addAxisSection(section);
     }
 
 
+    /**
+     * From document chart create ChartSection and populate it with attributes.
+     * Give this object to target as chartsection.
+     */
     protected static void parseChart(ChartSettings target, Node chart) {
         ChartSection chartSection = new ChartSection();
 
         String title = XMLUtils.xpathString(chart, "chart/title", null);
         String sub   = XMLUtils.xpathString(chart, "chart/subtitle", null);
         String grid  = XMLUtils.xpathString(chart, "chart/display-grid", null);
+        String logo  = XMLUtils.xpathString(chart, "chart/display-logo", null);
+        String placeh = XMLUtils.xpathString(chart, "chart/logo-placeh", null);
+        String placev = XMLUtils.xpathString(chart, "chart/logo-placev", null);
 
         if (logger.isDebugEnabled()) {
             logger.debug("Found chart title:    '" + title + "'");
             logger.debug("Found chart subtitle: '" + sub + "'");
             logger.debug("Found chart grid:     '" + grid + "'");
+            logger.debug("Found chart logo:     '" + logo + "'");
+            logger.debug("Found chart logo placeh: '" + placeh + "'");
+            logger.debug("Found chart logo placev: '" + placev + "'");
         }
 
         chartSection.setTitle(title);
         chartSection.setSubtitle(sub);
-        chartSection.setDisplayGird(Boolean.valueOf(grid));
+        chartSection.setDisplayGrid(Boolean.valueOf(grid));
+        chartSection.setDisplayLogo(logo);
+        chartSection.setLogoHPlacement(placeh);
+        chartSection.setLogoVPlacement(placev);
 
         target.setChartSection(chartSection);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChoiceStringAttribute.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,45 @@
+package de.intevation.flys.exports;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class ChoiceStringAttribute extends StringAttribute {
+
+    /** Indicator which type of choice is dealt with. */
+    protected String choiceType;
+
+
+    public ChoiceStringAttribute(String name,
+                           String value,
+                           boolean visible,
+                           String choiceType) {
+        super(name, value, visible);
+        this.choiceType = choiceType;
+    }
+
+
+    /**
+     * Calls VisibleAttribute.toXML() and appends afterwards an attribute
+     * <i>type</i> with value <i>string</i>.
+     *
+     * @param parent The parent Node.
+     *
+     * @return the new Node that represents this Attribute.
+     */
+    @Override
+    public Node toXML(Node parent) {
+        Document owner = parent.getOwnerDocument();
+
+        Element ele = (Element) super.toXML(parent);
+        ele.setAttribute("type", "string");
+        ele.setAttribute("choice", choiceType);
+
+        return ele;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,30 +1,23 @@
 package de.intevation.flys.exports;
 
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.log4j.Logger;
-
-import org.w3c.dom.Document;
-
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.title.TextTitle;
-import org.jfree.data.xy.XYSeries;
-
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
 import de.intevation.artifactdatabase.state.Facet;
-
 import de.intevation.flys.artifacts.StaticWKmsArtifact;
 import de.intevation.flys.artifacts.WINFOArtifact;
-
 import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.WKms;
 import de.intevation.flys.artifacts.model.WQKms;
-import de.intevation.flys.artifacts.model.WKms;
-
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StickyAxisAnnotation;
 import de.intevation.flys.jfree.StyledXYSeries;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
 
 /**
  * An OutGenerator that generates discharge curves.
@@ -80,16 +73,6 @@
 
 
     @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
-    }
-
-
-    @Override
     protected String getDefaultYAxisLabel(int pos) {
         return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,18 +1,5 @@
 package de.intevation.flys.exports;
 
-import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-import de.intevation.artifacts.DataProvider;
-import de.intevation.flys.artifacts.geom.Lines;
-import de.intevation.flys.artifacts.model.CrossSectionFacet;
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.HYKFactory;
-import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StyledXYSeries;
-import de.intevation.flys.model.FastCrossSectionLine;
-import de.intevation.flys.themes.ThemeAccess;
-import de.intevation.flys.utils.Formatter;
-import de.intevation.flys.utils.ThemeUtil;
-
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Paint;
@@ -21,15 +8,29 @@
 import java.util.List;
 
 import org.apache.log4j.Logger;
-import org.jfree.chart.JFreeChart;
 import org.jfree.chart.LegendItemCollection;
 import org.jfree.chart.annotations.XYBoxAnnotation;
 import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.title.TextTitle;
 import org.jfree.data.xy.XYSeries;
 import org.w3c.dom.Document;
 
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifacts.DataProvider;
+import de.intevation.flys.artifacts.geom.Lines;
+import de.intevation.flys.artifacts.model.CrossSectionFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.HYKFactory;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+import de.intevation.flys.model.FastCrossSectionLine;
+import de.intevation.flys.themes.LineStyle;
+import de.intevation.flys.themes.TextStyle;
+import de.intevation.flys.themes.ThemeAccess;
+import de.intevation.flys.utils.Formatter;
+import de.intevation.flys.utils.ThemeUtil;
+
 
 /**
  * An OutGenerator that generates cross section graphs.
@@ -40,19 +41,19 @@
 {
     /** The logger that is used in this generator. */
     private static Logger logger =
-        Logger.getLogger(CrossSectionGenerator.class);
+            Logger.getLogger(CrossSectionGenerator.class);
 
     public static final String I18N_CHART_TITLE =
-        "chart.cross_section.title";
+            "chart.cross_section.title";
 
     public static final String I18N_CHART_SUBTITLE =
-        "chart.cross_section.subtitle";
+            "chart.cross_section.subtitle";
 
     public static final String I18N_XAXIS_LABEL =
-        "chart.cross_section.xaxis.label";
+            "chart.cross_section.xaxis.label";
 
     public static final String I18N_YAXIS_LABEL =
-        "chart.cross_section.yaxis.label";
+            "chart.cross_section.yaxis.label";
 
     public static final String I18N_CHART_TITLE_DEFAULT = "Querprofildiagramm";
     public static final String I18N_XAXIS_LABEL_DEFAULT = "Abstand [m]";
@@ -88,7 +89,7 @@
     @Override
     public String getDefaultChartTitle() {
         Object[] i18n_msg_args = new Object[] {
-            getRiverName()
+                getRiverName()
         };
         return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT, i18n_msg_args);
     }
@@ -110,30 +111,26 @@
     @Override
     protected String getDefaultChartSubtitle() {
         List<DataProvider> providers =
-            context.getDataProvider(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA);
+                context.getDataProvider(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA);
         double km = 0d;
         if (providers.size() > 0) {
             FastCrossSectionLine csl = (FastCrossSectionLine) providers.get(0).
-                provideData(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA,
-                    null, context);
-            km = csl.getKm();
+                    provideData(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA,
+                            null, context);
+            km = csl == null ? -1 : csl.getKm();
         }
 
         Object[] args = new Object[] {
-            getRiverName(),
-            km
+                getRiverName(),
+                km
         };
 
+        logger.debug("Locale: " + Resources.getLocale(context.getMeta()));
+
         return msg(I18N_CHART_SUBTITLE, "", args);
     }
 
 
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-        chart.addSubtitle(new TextTitle(subtitle));
-    }
-
     /** Get color for hyk zones by their type (which is the name). */
     protected Paint colorForHYKZone(String zoneName) {
         if (zoneName.startsWith("R")) {
@@ -172,15 +169,15 @@
 
         // OPTMIMIZE: Pre-calculate positions
         ChartArea area = new ChartArea(
-            plot.getDomainAxis(0).getRange(),
-            plot.getRangeAxis().getRange());
+                plot.getDomainAxis(0).getRange(),
+                plot.getRangeAxis().getRange());
 
         for(FLYSAnnotation fa : this.annotations) {
 
             // Access text styling, if any.
             Document theme = fa.getTheme();
-            ThemeAccess.TextStyle textStyle = null;
-            ThemeAccess.LineStyle lineStyle = null;
+            TextStyle textStyle = null;
+            LineStyle lineStyle = null;
 
             // Get Themeing information and add legend item.
             if (theme != null) {
@@ -209,13 +206,13 @@
                 fillPaint = colorForHYKZone(zone.getName());
 
                 XYBoxAnnotation boxA = new XYBoxAnnotation(zone.getFrom(), area.atGround(),
-                    zone.getTo(), area.ofGround(0.03f), basicStroke, tranPaint, fillPaint);
+                        zone.getTo(), area.ofGround(0.03f), basicStroke, tranPaint, fillPaint);
                 XYBoxAnnotation boxB = new XYBoxAnnotation(zone.getFrom(), area.atGround(),
-                    zone.getTo(), area.atTop(), basicStroke, fillPaint, tranPaint);
+                        zone.getTo(), area.atTop(), basicStroke, fillPaint, tranPaint);
 
                 XYTextAnnotation tex = new XYTextAnnotation(zone.getName(),
-                    zone.getFrom() + (zone.getTo() - zone.getFrom()) / 1.0d,
-                    area.ofGround(0.015f));
+                        zone.getFrom() + (zone.getTo() - zone.getFrom()) / 1.0d,
+                        area.ofGround(0.015f));
                 if (textStyle != null) {
                     textStyle.apply(tex);
                 }
@@ -244,10 +241,10 @@
      */
     @Override
     public void doOut(
-        ArtifactAndFacet artifactFacet,
-        Document         attr,
-        boolean          visible
-    ) {
+            ArtifactAndFacet artifactFacet,
+            Document         attr,
+            boolean          visible
+            ) {
         String name = artifactFacet.getFacetName();
 
         logger.debug("CrossSectionGenerator.doOut: " + name);
@@ -259,41 +256,41 @@
 
         if (name.equals(CROSS_SECTION)) {
             doCrossSectionOut(
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                attr,
-                visible);
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    attr,
+                    visible);
         }
         else if (name.equals(CROSS_SECTION_WATER_LINE)) {
             doCrossSectionWaterLineOut(
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                attr,
-                visible);
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    attr,
+                    visible);
         }
         else if (FacetTypes.IS.AREA(name)) {
             doArea(artifactFacet.getData(context),
-                artifactFacet,
-                attr,
-                visible);
+                    artifactFacet,
+                    attr,
+                    visible);
         }
         else if (name.equals(HYK)) {
             doHyk(artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                attr,
-                visible);
+                    artifactFacet.getFacetDescription(),
+                    attr,
+                    visible);
         }
         else if (FacetTypes.IS.MANUALLINE(name)) {
             doCrossSectionWaterLineOut(
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                attr,
-                visible);
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    attr,
+                    visible);
         }
         else if (FacetTypes.IS.MANUALPOINTS(name)) {
             doPoints(artifactFacet.getData(context),
-                artifactFacet,
-                attr, visible, YAXIS.W.idx);
+                    artifactFacet,
+                    attr, visible, YAXIS.W.idx);
         }
         else {
             logger.warn("CrossSection.doOut: Unknown facet name: " + name);
@@ -317,11 +314,11 @@
      * @param theme Theme for the data series.
      */
     protected void doCrossSectionWaterLineOut(
-        Object   o,
-        String   seriesName,
-        Document theme,
-        boolean  visible
-    ) {
+            Object   o,
+            String   seriesName,
+            Document theme,
+            boolean  visible
+            ) {
         logger.debug("CrossSectionGenerator.doCrossSectionWaterLineOut");
 
         Lines.LineData lines = (Lines.LineData) o;
@@ -334,19 +331,19 @@
         if (ThemeUtil.parseShowWidth(theme)) {
             NumberFormat nf = Formatter.getMeterFormat(this.context);
             String labelAdd = "b=" + nf.format(lines.width) + "m";
-            if (series.getLabel().equals("")) {
-               series.setLabel(labelAdd);
+            if (series.getLabel().length() == 0) {
+                series.setLabel(labelAdd);
             }
             else {
                 series.setLabel(series.getLabel() + ", " + labelAdd);
             }
         }
-        if (ThemeUtil.parseShowLevel(theme) && lines.points.length >0
+        if (ThemeUtil.parseShowLevel(theme) && lines.points.length > 1
                 && lines.points[1].length > 0) {
             NumberFormat nf = Formatter.getMeterFormat(this.context);
             String labelAdd = "W=" + nf.format(lines.points[1][0]) + "NN+m";
-            if (series.getLabel().equals("")) {
-               series.setLabel(labelAdd);
+            if (series.getLabel().length() == 0) {
+                series.setLabel(labelAdd);
             }
             else {
                 series.setLabel(series.getLabel() + ", " + labelAdd);
@@ -354,10 +351,10 @@
         }
         if (ThemeUtil.parseShowMiddleHeight(theme) && lines.width != 0) {
             NumberFormat nf = Formatter.getMeterFormat(this.context);
-            String labelAdd = "H=" + nf.format(lines.area / lines.width) + "m";
-                // : " + lines.area + "/" + lines.width);
-            if (series.getLabel().equals("")) {
-               series.setLabel(labelAdd);
+            String labelAdd = "T=" + nf.format(lines.area / lines.width) + "m";
+            // : " + lines.area + "/" + lines.width);
+            if (series.getLabel().length() == 0) {
+                series.setLabel(labelAdd);
             }
             else {
                 series.setLabel(series.getLabel() + ", " + labelAdd);
@@ -372,16 +369,16 @@
 
     /** Add HYK-Annotations (colorize and label some areas, draw lines. */
     protected void doHyk(
-        Object   o,
-        String   seriesName,
-        Document theme,
-        boolean  visible
-    ) {
+            Object   o,
+            String   seriesName,
+            Document theme,
+            boolean  visible
+            ) {
         logger.debug("CrossSectionGenerator.doHyk");
 
         List<HYKFactory.Zone> zones = (List<HYKFactory.Zone>) o;
 
-        if (zones == null || zones.size() == 0) {
+        if (zones == null || zones.isEmpty()) {
             logger.warn("CrossSectionGenerator.doHYK: empty zone list received.");
             return;
         }
@@ -400,11 +397,11 @@
      * @param theme Theme for the data series.
      */
     protected void doCrossSectionOut(
-        Object   o,
-        String   seriesName,
-        Document theme,
-        boolean  visible
-    ) {
+            Object   o,
+            String   seriesName,
+            Document theme,
+            boolean  visible
+            ) {
         logger.debug("CrossSectionGenerator.doCrossSectionOut");
 
         XYSeries series = new StyledXYSeries(seriesName, theme);
@@ -418,13 +415,18 @@
     /**
      * Creates a new <i>ChartSection</i>.
      *
+     * Overridden to prevent inclusion of subtitle.
+     *
      * @return a new <i>ChartSection</i>.
      */
     @Override
     protected ChartSection buildChartSection() {
         ChartSection chartSection = new ChartSection();
         chartSection.setTitle(getChartTitle());
-        chartSection.setDisplayGird(isGridVisible());
+        chartSection.setDisplayGrid(isGridVisible());
+        chartSection.setDisplayLogo(showLogo());
+        chartSection.setLogoVPlacement(logoVPlace());
+        chartSection.setLogoHPlacement(logoHPlace());
         return chartSection;
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,30 +1,22 @@
 package de.intevation.flys.exports;
 
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.flys.artifacts.WINFOArtifact;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+import de.intevation.flys.model.Gauge;
+import de.intevation.flys.model.River;
+import de.intevation.flys.utils.FLYSUtils;
+
 import org.apache.log4j.Logger;
-
-
-import org.w3c.dom.Document;
-
-import org.jfree.chart.JFreeChart;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYSeries;
-
-import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.model.Gauge;
-import de.intevation.flys.model.River;
-
-import de.intevation.flys.artifacts.WINFOArtifact;
-
-import de.intevation.flys.artifacts.model.WQKms;
-
-import de.intevation.flys.utils.FLYSUtils;
-import de.intevation.flys.jfree.Bounds;
-import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StyledXYSeries;
+import org.w3c.dom.Document;
 
 
 /**
@@ -87,17 +79,12 @@
     }
 
 
+    /**
+     * Returns always null to suppress subtitles.
+     */
     @Override
     protected String getDefaultChartTitle() {
-        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
-    }
-
-
-    /**
-     * Empty (suppress subtitle).
-     */
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
+        return null;
     }
 
 
@@ -125,6 +112,7 @@
     }
 
 
+    @Override
     public void doOut(
         ArtifactAndFacet artifactFacet,
         Document         theme,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -42,7 +42,7 @@
 public class DurationCurveExporter extends AbstractExporter {
 
     /** The logger used in this exporter. */
-    private static Logger logger = Logger.getLogger(WaterlevelExporter.class);
+    private static Logger logger = Logger.getLogger(DurationCurveExporter.class);
 
 
     public static final String CSV_DURATION_HEADER =
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,28 +1,22 @@
 package de.intevation.flys.exports;
 
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.WQDay;
+import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
 import java.awt.Font;
 import java.awt.geom.Point2D;
 
-import org.w3c.dom.Document;
-
 import org.apache.log4j.Logger;
-
-import org.jfree.chart.JFreeChart;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.title.TextTitle;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYSeries;
-
-import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.WQDay;
-
-import de.intevation.flys.jfree.Bounds;
-import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StyledXYSeries;
+import org.w3c.dom.Document;
 
 
 /**
@@ -43,6 +37,7 @@
         }
     }
 
+    /** Local logger. */
     private static Logger logger =
         Logger.getLogger(DurationCurveGenerator.class);
 
@@ -111,16 +106,6 @@
 
 
     @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
-    }
-
-
-    @Override
     protected String getDefaultXAxisLabel() {
         return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
     }
@@ -257,7 +242,7 @@
             int  day = wqdays.getDay(i);
             double w = wqdays.getW(i);
 
-            series.add((double) day, w);
+            series.add(day, w);
         }
 
         addAxisSeries(series, YAXIS.W.idx, visible);
@@ -300,7 +285,7 @@
             int  day = wqdays.getDay(i);
             double q = wqdays.getQ(i);
 
-            series.add((double) day, q);
+            series.add(day, q);
         }
 
         addAxisSeries(series, YAXIS.Q.idx, visible);
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/HistoricalDischargeCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/HistoricalDischargeCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,22 +1,6 @@
 package de.intevation.flys.exports;
 
-import java.util.Date;
-
-import org.w3c.dom.Document;
-
-import org.apache.log4j.Logger;
-
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.title.TextTitle;
-
-import org.jfree.data.general.SeriesException;
-import org.jfree.data.time.Day;
-import org.jfree.data.time.RegularTimePeriod;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-
 import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.HistoricalWQTimerange;
@@ -25,6 +9,16 @@
 import de.intevation.flys.jfree.StyledTimeSeries;
 import de.intevation.flys.utils.FLYSUtils;
 
+import java.util.Date;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.general.SeriesException;
+import org.jfree.data.time.Day;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.w3c.dom.Document;
+
 
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
@@ -95,19 +89,6 @@
     }
 
 
-    /**
-     * Empty (suppress subtitle).
-     */
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
-    }
-
-
     @Override
     protected String getDefaultXAxisLabel() {
         return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL);
@@ -127,6 +108,7 @@
     }
 
 
+    @Override
     public void doOut(
         ArtifactAndFacet artifactFacet,
         Document         theme,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,34 +1,26 @@
 package de.intevation.flys.exports;
 
-import org.apache.log4j.Logger;
-
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.title.TextTitle;
-import org.jfree.chart.axis.ValueAxis;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.data.xy.XYSeries;
-
-import org.w3c.dom.Document;
-
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
 import de.intevation.artifactdatabase.state.Facet;
-
 import de.intevation.flys.artifacts.FLYSArtifact;
-
+import de.intevation.flys.artifacts.geom.Lines;
 import de.intevation.flys.artifacts.model.AreaFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.WKms;
 import de.intevation.flys.artifacts.model.WQKms;
-
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StyledAreaSeriesCollection;
 import de.intevation.flys.jfree.StyledXYSeries;
-
+import de.intevation.flys.utils.DataUtil;
 import de.intevation.flys.utils.FLYSUtils;
-import de.intevation.flys.utils.DataUtil;
+import de.intevation.flys.utils.ThemeUtil;
 
-import de.intevation.flys.artifacts.geom.Lines;
+import org.apache.log4j.Logger;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
 
 
 /**
@@ -124,15 +116,42 @@
     }
 
 
+    /** True if x axis has been inverted. */
     public boolean isInverted() {
         return inverted;
     }
 
 
+    /** Set to true if x axis has been inverted. */
     public void setInverted(boolean inverted) {
         this.inverted = inverted;
     }
 
+    /**
+     * Return left most data points x value (on first axis).
+     * Overridden because axis could be inverted.
+     */
+    @Override
+    protected double getLeftX() {
+        if (isInverted()) {
+            return (Double)getXBounds(0).getUpper();
+        }
+        return (Double)getXBounds(0).getLower();
+    }
+
+
+    /**
+     * Return right most data points x value (on first axis).
+     * Overridden because axis could be inverted.
+     */
+    @Override
+    protected double getRightX() {
+        if (isInverted()) {
+            return (Double)getXBounds(0).getLower();
+        }
+        return (Double)getXBounds(0).getUpper();
+    }
+
 
     /**
      * Returns the default title for this chart.
@@ -188,20 +207,6 @@
 
 
     /**
-     * Add (internationalized) subtitle to chart.
-     * @see getChartSubtitleKey
-     */
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
-    }
-
-
-    /**
      * Get internationalized label for the x axis.
      */
     @Override
@@ -315,6 +320,7 @@
      * @param artifactAndFacet current facet and artifact.
      * @param attr  theme for facet
      */
+    @Override
     public void doOut(
         ArtifactAndFacet artifactAndFacet,
         Document         attr,
@@ -429,8 +435,24 @@
         XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
 
         StyledSeriesBuilder.addPoints(series, wkms);
+        addAxisSeries(series, YAXIS.W.idx, visible);
 
-        addAxisSeries(series, YAXIS.W.idx, visible);
+        // If a "band around the curve shall be drawn, add according area.
+        double bandWidth = ThemeUtil.parseBandWidth(theme);
+        if (bandWidth > 0 ) {
+            XYSeries seriesDown = new StyledXYSeries(
+                "band " + aandf.getFacetDescription(), false, theme);
+            XYSeries seriesUp = new StyledXYSeries(
+                aandf.getFacetDescription()+"+/-"+bandWidth, false, theme);
+            StyledSeriesBuilder.addUpperBand(seriesUp, wkms, bandWidth);
+            StyledSeriesBuilder.addLowerBand(seriesDown, wkms, bandWidth);
+
+            StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
+            area.addSeries(seriesUp);
+            area.addSeries(seriesDown);
+            area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN);
+            addAreaSeries(area, YAXIS.W.idx, visible);
+        }
 
         if (needInvertAxis(wkms)) {
             setInverted(true);
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/MapGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/MapGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -15,6 +15,7 @@
 import de.intevation.flys.artifacts.model.map.WMSDBLayerFacet;
 import de.intevation.flys.artifacts.model.map.WMSLayerFacet;
 import de.intevation.flys.artifacts.model.map.WSPLGENLayerFacet;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 import de.intevation.flys.utils.GeometryUtils;
 import de.intevation.flys.utils.MapfileGenerator;
 import de.intevation.flys.utils.ThemeUtil;
@@ -35,6 +36,8 @@
 
     private static Logger logger = Logger.getLogger(MapGenerator.class);
 
+    protected FLYSArtifactCollection collection;
+
     protected Artifact master;
 
     protected Settings settings;
@@ -75,6 +78,10 @@
         this.master = master;
     }
 
+    @Override
+    public void setCollection(FLYSArtifactCollection collection) {
+        this.collection = collection;
+    }
 
     @Override
     public void doOut(
@@ -92,7 +99,7 @@
 
         if (nativeFacet instanceof WMSLayerFacet) {
             WMSLayerFacet wms = (WMSLayerFacet) nativeFacet;
-            Envelope   extent = wms.getExtent();
+            Envelope   extent = wms.getOriginalExtent();
 
             layers.add(wms);
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/MiddleBedHeightGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/MiddleBedHeightGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -212,7 +212,7 @@
 
         XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
 
-        StyledSeriesBuilder.addPoints(series, data.getMiddleHeightsPoints(), true);
+        StyledSeriesBuilder.addPoints(series, data.getMiddleHeightsPoints(), false);
 
         addAxisSeries(series, YAXIS.H.idx, visible);
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/OutGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/OutGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -9,6 +9,7 @@
 import de.intevation.artifactdatabase.state.Settings;
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 
 
 /**
@@ -38,6 +39,13 @@
     void setMasterArtifact(Artifact master);
 
     /**
+     * This method is used to set the Collection of the OutGenerator.
+     *
+     * @param collection A reference to the collection.
+     */
+    void setCollection(FLYSArtifactCollection collection);
+
+    /**
      * Creates the output of an Artifact and appends that single output to the
      * total output.
      *
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/OutputHelper.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/OutputHelper.java	Fri Sep 28 12:15:40 2012 +0200
@@ -459,9 +459,13 @@
                       "default");
 
         if (t != null) {
+            log.debug("found theme for facet '" + facet + "'");
             t.setFacet(facet);
             t.setIndex(index);
         }
+        else {
+            log.warn("unable to find theme for facet '" + facet + "'");
+        }
 
         return t;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ReferenceCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ReferenceCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,33 +1,23 @@
 package de.intevation.flys.exports;
 
-import java.awt.geom.Point2D;
-
-import org.w3c.dom.Document;
-
-import org.apache.log4j.Logger;
-
-import org.jfree.chart.JFreeChart;
-
-import org.jfree.chart.title.TextTitle;
-
-import org.jfree.data.xy.XYSeries;
-
-import org.jfree.chart.axis.ValueAxis;
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.axis.NumberTickUnit;
-import org.jfree.chart.axis.TickUnits;
-
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.WW;
 import de.intevation.flys.artifacts.model.WW.ApplyFunctionIterator;
 import de.intevation.flys.artifacts.model.WWAxisTypes;
-
+import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StyledXYSeries;
-import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.utils.Formatter;
 
-import de.intevation.flys.utils.Formatter;
+import java.awt.geom.Point2D;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.NumberTickUnit;
+import org.jfree.chart.axis.TickUnits;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
 
 /**
  * An OutGenerator that generates reference curves.
@@ -102,15 +92,7 @@
     }
 
 
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
-    }
-
+    /** True if axis is in cm (because at gauge). */
     protected boolean getInCm(int index) {
         Object obj = context.getContextValue("reference.curve.axis.scale");
         return obj instanceof WWAxisTypes && ((WWAxisTypes)obj).getInCm(index);
@@ -240,9 +222,11 @@
         addAxisSeries(series, YAXIS.W.idx, visible);
     }
 
-    protected void setAxisTickUnit(ValueAxis axis) {
+
+    /** Set the tick units for given axis. */
+    protected void setAxisTickUnit(double tick, ValueAxis axis) {
         TickUnits units = new TickUnits();
-        units.add(new NumberTickUnit(1d, Formatter.getWaterlevelW(context)));
+        units.add(new NumberTickUnit(tick, Formatter.getWaterlevelW(context)));
         axis.setStandardTickUnits(units);
         axis.setAutoTickUnitSelection(true);
     }
@@ -250,14 +234,19 @@
     @Override
     protected void localizeDomainAxis(ValueAxis domainAxis) {
         super.localizeDomainAxis(domainAxis);
-        setAxisTickUnit(domainAxis);
+        if (getInCm(0)) {
+            setAxisTickUnit(100d, domainAxis);
+        }
+        else {
+            setAxisTickUnit(1d, domainAxis);
+        }
     }
 
 
     @Override
     protected void localizeRangeAxis(ValueAxis rangeAxis) {
         super.localizeRangeAxis(rangeAxis);
-        setAxisTickUnit(rangeAxis);
+        setAxisTickUnit(1d, rangeAxis);
     }
 
     /** Get Walker to iterate over all axes. */
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ReportGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ReportGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -15,6 +15,7 @@
 import de.intevation.artifactdatabase.state.Settings;
 
 import de.intevation.flys.artifacts.model.Calculation;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 
 import org.w3c.dom.Document;
 
@@ -44,6 +45,11 @@
     }
 
     @Override
+    public void setCollection(FLYSArtifactCollection collection) {
+        // not needed
+    }
+
+    @Override
     public void doOut(
         ArtifactAndFacet artifactFacet,
         Document         attr,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/StyledSeriesBuilder.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/StyledSeriesBuilder.java	Fri Sep 28 12:15:40 2012 +0200
@@ -76,6 +76,37 @@
 
 
     /**
+     * Add points to dataset with an offset (shift all points by given amount).
+     * @param series series to add data to.
+     * @param wkms WKms of which the Ws will be shifted.
+     * @param off the offset.
+     */
+    public static void addUpperBand(XYSeries series, WKms wkms, double off) {
+        if (wkms == null) {
+            return;
+        }
+
+        int size = wkms.size();
+
+        for (int i = 0; i < size; i++) {
+            series.add(wkms.getKm(i), wkms.getW(i)+off, false);
+        }
+    }
+
+
+    /**
+     * Add points to dataset with an offset (shift all points 'down' by given
+     * amount).
+     * @param series series to add data to.
+     * @param wkms WKms of which the Ws will be shifted.
+     * @param off the offset.
+     */
+    public static void addLowerBand(XYSeries series, WKms wkms, double off) {
+        addUpperBand(series, wkms, -off);
+    }
+
+
+    /**
      * Add points to series (km to 1st dim, q to 2nd dim).
      *
      * @param series Series to add points to.
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -16,9 +16,13 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.swing.ImageIcon;
+
 import org.apache.log4j.Logger;
 import org.jfree.chart.ChartFactory;
 import org.jfree.chart.JFreeChart;
+import org.jfree.chart.annotations.XYAnnotation;
+import org.jfree.chart.annotations.XYImageAnnotation;
 import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.Marker;
@@ -123,8 +127,11 @@
 
             // Determine min/max of range axis.
             for (int i = 0; i < dataset.getSeriesCount(); i++) {
-                double min = 0;
-                double max = 0;
+                if (dataset.getSeries(i).getItemCount() == 0) {
+                    continue;
+                }
+                double min = Double.MAX_VALUE;
+                double max = -Double.MAX_VALUE;
                 TimeSeries series = dataset.getSeries(i);
                 for (int j = 0; j < series.getItemCount(); j++) {
                     double tmp = series.getValue(j).doubleValue();
@@ -169,16 +176,13 @@
     private static final Logger logger =
         Logger.getLogger(TimeseriesChartGenerator.class);
 
-
     public static final int AXIS_SPACE = 5;
 
-
     protected Map<Integer, Bounds> xBounds;
 
     protected Map<Integer, Bounds> yBounds;
 
 
-
     /**
      * The default constructor that initializes internal datastructures.
      */
@@ -222,11 +226,146 @@
 
         applySeriesAttributes(plot);
         addAnnotationsToRenderer(plot);
+        addLogo(plot);
         aggregateLegendEntries(plot);
         return chart;
     }
 
 
+    /**
+     * Return left most data points x value (on first axis).
+     * Shortcut, especially to be overridden in (LS) charts where
+     * axis could be inverted.
+     */
+    protected double getLeftX() {
+        return (Long)getXBounds(0).getLower();
+    }
+
+
+    /**
+     * Return right most data points x value (on first axis).
+     * Shortcut, especially to be overridden in (LS) charts where
+     * axis could be inverted.
+     */
+    protected double getRightX() {
+        return (Long)getXBounds(0).getUpper();
+    }
+
+
+    /**
+     * Add a logo as background annotation to plot.
+     * Copy from XYChartGenerator.
+     */
+    protected void addLogo(XYPlot plot) {
+        String logo = showLogo();
+        if (logo  == null) {
+            logger.debug("No logo to show chosen");
+            return;
+        }
+
+        ImageIcon imageIcon = null;
+        if (logo.equals("none")) {
+            return;
+        }
+        /*
+         If you want to add images, remember to change code in these places:
+         flys-artifacts:
+         XYChartGenerator.java
+         Timeseries*Generator.java and
+         in the flys-client projects Chart*Propert*Editor.java.
+         Also, these images have to be put in
+         flys-artifacts/src/main/resources/images/
+         flys-client/src/main/webapp/images/
+         */
+        java.net.URL imageURL;
+        if (logo.equals("Intevation")) {
+            imageURL = XYChartGenerator.class.getResource("/images/intevation.png");
+        }
+        else { // TODO else if ...
+            imageURL = XYChartGenerator.class.getResource("/images/bfg_logo.gif");
+        }
+        imageIcon = new ImageIcon(imageURL);
+        double xPos = 0d, yPos = 0d;
+
+        String placeh = logoHPlace();
+        String placev = logoVPlace();
+
+        if (placev == null || placev.equals("none")) {
+            placev = "top";
+        }
+        if (placev.equals("top")) {
+            yPos = (Double)getYBounds(0).getUpper();
+        }
+        else if (placev.equals("bottom")) {
+            yPos = (Double)getYBounds(0).getLower();
+        }
+        else if (placev.equals("center")) {
+            yPos = ((Double)getYBounds(0).getUpper() + (Double)getYBounds(0).getLower())/2d;
+        }
+        else {
+            logger.debug("Unknown place-v value: " + placev);
+        }
+
+        if (placeh == null || placeh.equals("none")) {
+            placeh = "center";
+        }
+        if (placeh.equals("left")) {
+            xPos = getLeftX();
+        }
+        else if (placeh.equals("right")) {
+            xPos = getRightX();
+        }
+        else if (placeh.equals("center")) {
+            xPos = ((Long)getXBounds(0).getUpper() + (Long)getXBounds(0).getLower())/2d;
+        }
+        else {
+            logger.debug("Unknown place-h value: " + placeh);
+        }
+
+        logger.debug("logo position: " + xPos + "/" + yPos);
+
+        org.jfree.ui.RectangleAnchor anchor
+            = org.jfree.ui.RectangleAnchor.TOP;
+        if (placev.equals("top")) {
+            if (placeh.equals("left")) {
+                anchor = org.jfree.ui.RectangleAnchor.TOP_LEFT;
+            }
+            else if (placeh.equals("right")) {
+                anchor = org.jfree.ui.RectangleAnchor.TOP_RIGHT;
+            }
+            else if (placeh.equals("center")) {
+                anchor = org.jfree.ui.RectangleAnchor.TOP;
+            }
+        }
+        else if (placev.equals("bottom")) {
+            if (placeh.equals("left")) {
+                anchor = org.jfree.ui.RectangleAnchor.BOTTOM_LEFT;
+            }
+            else if (placeh.equals("right")) {
+                anchor = org.jfree.ui.RectangleAnchor.BOTTOM_RIGHT;
+            }
+            else if (placeh.equals("center")) {
+                anchor = org.jfree.ui.RectangleAnchor.BOTTOM;
+            }
+        }
+        else if (placev.equals("center")) {
+            if (placeh.equals("left")) {
+                anchor = org.jfree.ui.RectangleAnchor.LEFT;
+            }
+            else if (placeh.equals("right")) {
+                anchor = org.jfree.ui.RectangleAnchor.RIGHT;
+            }
+            else if (placeh.equals("center")) {
+                anchor = org.jfree.ui.RectangleAnchor.CENTER;
+            }
+        }
+
+        XYAnnotation xyannotation =
+            new XYImageAnnotation(xPos, yPos, imageIcon.getImage(), anchor);
+        plot.getRenderer().addAnnotation(xyannotation, org.jfree.ui.Layer.BACKGROUND);
+    }
+
+
     @Override
     protected Series getSeriesOf(XYDataset dataset, int idx) {
         return ((TimeSeriesCollection) dataset).getSeries(idx);
@@ -341,6 +480,7 @@
     }
 
 
+    /** Get (zoom)values from request. */
     public Bounds getDomainAxisRange() {
         String[] ranges = getDomainAxisRangeFromRequest();
 
@@ -412,10 +552,15 @@
     }
 
 
+    /**
+     * @param plot the plot.
+     * @param axis the value (x, time) axis of which to set bounds.
+     * @param total the current bounds (?).
+     */
     protected void zoomX(
         XYPlot    plot,
         ValueAxis axis,
-        Bounds    total,
+        Bounds    total,//we could equally nicely getXBounds(0)
         Bounds    user
     ) {
         if (logger.isDebugEnabled()) {
@@ -447,6 +592,9 @@
     }
 
 
+    /**
+     * @param user zoom values in percent.
+     */
     protected void zoomY(
         XYPlot    plot,
         ValueAxis axis,
@@ -486,6 +634,8 @@
      * Adjusts the axes of a plot. This method sets the <i>labelFont</i> of the
      * X axis.
      *
+     * (Duplicate in XYChartGenerator).
+     *
      * @param plot The XYPlot of the chart.
      */
     protected void adjustAxes(XYPlot plot) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/TypeSection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/TypeSection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,5 +1,7 @@
 package de.intevation.flys.exports;
 
+import org.apache.log4j.Logger;
+
 import de.intevation.artifactdatabase.state.Attribute;
 import de.intevation.artifactdatabase.state.DefaultSection;
 
@@ -9,11 +11,30 @@
  */
 public class TypeSection extends DefaultSection {
 
+    private static final Logger logger = Logger.getLogger(TypeSection.class);
+
     public TypeSection(String key) {
         super(key);
     }
 
 
+    /** Set a string value for a attribute with additional (choice) type. */
+    public void setChoiceStringValue(String key, String value, String choiceType) {
+        if (value == null || value.length() == 0) {
+            return;
+        }
+
+        Attribute attr = getAttribute(key);
+        if (attr == null) {
+            attr = new ChoiceStringAttribute(key, value, true, choiceType);
+            addAttribute(key, attr);
+        }
+        else {
+            attr.setValue(value);
+        }
+    }
+
+
     public void setStringValue(String key, String value) {
         if (value == null || value.length() == 0) {
             return;
@@ -37,6 +58,8 @@
             return (String) attr.getValue();
         }
 
+        logger.debug("attribute " + key + " not found in typesection.getString");
+
         return null;
     }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/WDifferencesCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/WDifferencesCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,15 +1,12 @@
 package de.intevation.flys.exports;
 
-import org.apache.log4j.Logger;
-
-import org.jfree.chart.title.TextTitle;
-
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.plot.XYPlot;
-
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.WKms;
 
+import org.apache.log4j.Logger;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.XYPlot;
+
 
 /**
  * An OutGenerator that generates w differences curves.
@@ -86,21 +83,6 @@
 
 
     /**
-     * Add (internationalized) subtitle to chart.
-     * Overridden to avoid trying to access the range of masterartifact.
-     * @see getChartSubtitleKey
-     */
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
-    }
-
-
-    /**
      *
      */
     @Override
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -36,6 +36,7 @@
 import de.intevation.flys.artifacts.model.WQCKms;
 import de.intevation.flys.artifacts.model.WQKms;
 import de.intevation.flys.artifacts.model.WKmsJRDataSource;
+import de.intevation.flys.artifacts.model.fixings.FixRealizingResult;
 import de.intevation.flys.artifacts.resources.Resources;
 
 import de.intevation.flys.utils.FLYSUtils;
@@ -162,6 +163,9 @@
             if (d instanceof WQKms []) {
                 data.add((WQKms [])d);
             }
+            else if (d instanceof FixRealizingResult) {
+                data.add(((FixRealizingResult) d).getWQKms());
+            }
         }
     }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,37 @@
 package de.intevation.flys.exports;
 
+import java.awt.Color;
+import java.awt.Font;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.ImageIcon;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.LegendItem;
+import org.jfree.chart.annotations.XYAnnotation;
+import org.jfree.chart.annotations.XYImageAnnotation;
+import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.Marker;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.Range;
+import org.jfree.data.general.Series;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.w3c.dom.Document;
+
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-
 import de.intevation.flys.jfree.Bounds;
 import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
 import de.intevation.flys.jfree.DoubleBounds;
@@ -9,44 +39,6 @@
 import de.intevation.flys.jfree.StyledAreaSeriesCollection;
 import de.intevation.flys.jfree.StyledXYSeries;
 
-import java.awt.Color;
-import java.awt.Font;
-
-import java.text.NumberFormat;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.LegendItem;
-
-import org.jfree.chart.annotations.XYTextAnnotation;
-
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.axis.ValueAxis;
-
-import org.jfree.chart.plot.Marker;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.plot.XYPlot;
-
-import org.jfree.data.Range;
-
-import org.jfree.data.general.Series;
-
-import org.jfree.data.xy.XYDataset;
-import org.jfree.data.xy.XYSeries;
-import org.jfree.data.xy.XYSeriesCollection;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import org.w3c.dom.Document;
-
 
 /**
  * An abstract base class for creating XY charts.
@@ -68,10 +60,13 @@
     public class XYAxisDataset implements AxisDataset {
         /** Symbolic integer, but also coding the priority (0 goes first). */
         protected int axisSymbol;
+
         /** List of assigned datasets (in order). */
         protected List<XYDataset> datasets;
+
         /** Range to use to include all given datasets. */
         protected Range range;
+
         /** Index of axis in plot. */
         protected int plotAxisIndex;
 
@@ -127,17 +122,19 @@
         /** Get Array of Datasets. */
         @Override
         public XYDataset[] getDatasets() {
-            return (XYDataset[])
-                datasets.toArray(new XYDataset[datasets.size()]);
+            return datasets.toArray(new XYDataset[datasets.size()]);
         }
 
 
         /** Add a Dataset that describes an area. */
         public void addArea(StyledAreaSeriesCollection series) {
             this.datasets.add(series);
+            List<?> allSeries = series.getSeries();
+            for (int n = 0; n < allSeries.size(); n++) {
+                includeYRange((XYSeries)allSeries.get(n));
+            }
         }
 
-        // TODO obsolete?
         /** True if to be rendered as area. */
         @Override
         public boolean isArea(XYDataset series) {
@@ -169,6 +166,7 @@
     } // class AxisDataset
 
     /** Enumerator over existing axes. */
+    @Override
     protected abstract YAxisWalker getYAxisWalker();
 
     public static final int AXIS_SPACE = 5;
@@ -197,6 +195,7 @@
     /**
      * Generate the chart anew (including localized axis and all).
      */
+    @Override
     public JFreeChart generateChart() {
         logger.debug("XYChartGenerator.generateChart");
 
@@ -240,12 +239,148 @@
         // These have to go after the autozoom.
         addAnnotationsToRenderer(plot);
 
+        // Add a logo (maybe).
+        addLogo(plot);
+
         aggregateLegendEntries(plot);
 
         return chart;
     }
 
 
+    /**
+     * Return left most data points x value (on first axis).
+     * Shortcut, especially to be overridden in (LS) charts where
+     * axis could be inverted.
+     */
+    protected double getLeftX() {
+        return (Double)getXBounds(0).getLower();
+    }
+
+
+    /**
+     * Return right most data points x value (on first axis).
+     * Shortcut, especially to be overridden in (LS) charts where
+     * axis could be inverted.
+     */
+    protected double getRightX() {
+        return (Double)getXBounds(0).getUpper();
+    }
+
+
+    /** Add a logo as background annotation to plot. */
+    protected void addLogo(XYPlot plot) {
+        String logo = showLogo();
+        if (logo  == null) {
+            logger.debug("No logo to show chosen");
+            return;
+        }
+
+        ImageIcon imageIcon = null;
+        if (logo.equals("none")) {
+            return;
+        }
+        /*
+         If you want to add images, remember to change code in these places:
+         flys-artifacts:
+         XYChartGenerator.java
+         Timeseries*Generator.java and
+         in the flys-client projects Chart*Propert*Editor.java.
+         Also, these images have to be put in
+         flys-artifacts/src/main/resources/images/
+         flys-client/src/main/webapp/images/
+         */
+        java.net.URL imageURL;
+        if (logo.equals("Intevation")) {
+            imageURL = XYChartGenerator.class.getResource("/images/intevation.png");
+        }
+        else { // TODO else if ...
+            imageURL = XYChartGenerator.class.getResource("/images/bfg_logo.gif");
+        }
+        imageIcon = new ImageIcon(imageURL);
+
+
+        double xPos = 0d, yPos = 0d;
+
+        String placeh = logoHPlace();
+        String placev = logoVPlace();
+
+        if (placev == null || placev.equals("none")) {
+            placev = "top";
+        }
+        if (placev.equals("top")) {
+            yPos = (Double)getYBounds(0).getUpper();
+        }
+        else if (placev.equals("bottom")) {
+            yPos = (Double)getYBounds(0).getLower();
+        }
+        else if (placev.equals("center")) {
+            yPos = ((Double)getYBounds(0).getUpper() + (Double)getYBounds(0).getLower())/2d;
+        }
+        else {
+            logger.debug("Unknown place-v value: " + placev);
+        }
+
+        if (placeh == null || placeh.equals("none")) {
+            placeh = "center";
+        }
+        if (placeh.equals("left")) {
+            xPos = getLeftX();
+        }
+        else if (placeh.equals("right")) {
+            xPos = getRightX();
+        }
+        else if (placeh.equals("center")) {
+            xPos = ((Double)getXBounds(0).getUpper() + (Double)getXBounds(0).getLower())/2d;
+        }
+        else {
+            logger.debug("Unknown place-h value: " + placeh);
+        }
+
+        logger.debug("logo position: " + xPos + "/" + yPos);
+
+        org.jfree.ui.RectangleAnchor anchor
+            = org.jfree.ui.RectangleAnchor.TOP;
+        if (placev.equals("top")) {
+            if (placeh.equals("left")) {
+                anchor = org.jfree.ui.RectangleAnchor.TOP_LEFT;
+            }
+            else if (placeh.equals("right")) {
+                anchor = org.jfree.ui.RectangleAnchor.TOP_RIGHT;
+            }
+            else if (placeh.equals("center")) {
+                anchor = org.jfree.ui.RectangleAnchor.TOP;
+            }
+        }
+        else if (placev.equals("bottom")) {
+            if (placeh.equals("left")) {
+                anchor = org.jfree.ui.RectangleAnchor.BOTTOM_LEFT;
+            }
+            else if (placeh.equals("right")) {
+                anchor = org.jfree.ui.RectangleAnchor.BOTTOM_RIGHT;
+            }
+            else if (placeh.equals("center")) {
+                anchor = org.jfree.ui.RectangleAnchor.BOTTOM;
+            }
+        }
+        else if (placev.equals("center")) {
+            if (placeh.equals("left")) {
+                anchor = org.jfree.ui.RectangleAnchor.LEFT;
+            }
+            else if (placeh.equals("right")) {
+                anchor = org.jfree.ui.RectangleAnchor.RIGHT;
+            }
+            else if (placeh.equals("center")) {
+                anchor = org.jfree.ui.RectangleAnchor.CENTER;
+            }
+        }
+
+        XYAnnotation xyannotation =
+            new XYImageAnnotation(xPos, yPos, imageIcon.getImage(), anchor);
+        plot.getRenderer().addAnnotation(xyannotation, org.jfree.ui.Layer.BACKGROUND);
+    }
+
+
     protected NumberAxis createXAxis(String label) {
         return new NumberAxis(label);
     }
@@ -340,7 +475,7 @@
     /**
      * Add given series if visible, if not visible adjust ranges (such that
      * all points in data would be plotted once visible).
-     * @param series the dataseries to include in plot.
+     * @param series the data series to include in plot.
      * @param index  ('symbolic') index of the series and of its axis.
      * @param visible whether or not the data should be plotted.
      */
@@ -723,6 +858,8 @@
      * Adjusts the axes of a plot. This method sets the <i>labelFont</i> of the
      * X axis.
      *
+     * (Duplicate in TimeseriesChartGenerator)
+     *
      * @param plot The XYPlot of the chart.
      */
     protected void adjustAxes(XYPlot plot) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/DeltaWtExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,7 +8,7 @@
 import de.intevation.flys.artifacts.model.CalculationResult;
 
 import de.intevation.flys.artifacts.model.fixings.AnalysisPeriod;
-import de.intevation.flys.artifacts.model.fixings.FixResult;
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisResult;
 import de.intevation.flys.artifacts.model.fixings.QWD;
 
 import de.intevation.flys.artifacts.resources.Resources;
@@ -22,20 +22,21 @@
 import java.io.OutputStream;
 
 import java.text.DateFormat;
+import java.text.MessageFormat;
 import java.text.NumberFormat;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
-import java.util.Locale;
 
 import org.apache.log4j.Logger;
 
 import org.w3c.dom.Document;
 
+/** Exports fixation analysis deltaw(t) computation results to csv. */
 public class DeltaWtExporter
 extends      AbstractExporter
 {
+    /** Private logger. */
     private static Logger log = Logger.getLogger(DeltaWtExporter.class);
 
     public static final String CSV_KM_HEADER =
@@ -44,19 +45,48 @@
     public static final String CSV_DELTA_W_HEADER =
         "export.fixings.deltawt.csv.header.deltaw";
 
+    public static final String CSV_Q_HEADER =
+        "export.fixings.deltawt.csv.header.q";
+
+    public static final String CSV_W_HEADER =
+        "export.fixings.deltawt.csv.header.w";
+
+    public static final String CSV_TRANGE_HEADER =
+        "export.fixings.deltawt.csv.header.time.range";
+
     public static final String CSV_T_HEADER =
         "export.fixings.deltawt.csv.header.t";
 
-    public static final String CSV_T_DESC_HEADER =
-        "export.fixings.deltawt.csv.header.description";
+    public static final String CSV_T_FORMAT =
+        "export.fixings.deltawt.csv.t.format";
 
     public static final String DEFAULT_CSV_KM_HEADER = "km";
 
     public static final String DEFAULT_CSV_DELTA_W_HEADER = "\u0394 W [cm]";
 
+    public static final String DEFAULT_CSV_W_HEADER = "Wasserstand [m]";
+
+    public static final String DEFAULT_CSV_Q_HEADER = "Abfluss [m\u00b3/s]";
+
     public static final String DEFAULT_CSV_T_HEADER = "Datum";
 
-    public static final String DEFAULT_CSV_T_DESC_HEADER = "Beschreibung";
+    public static final String DEFAULT_CSV_TRANGE_DESC_HEADER =
+        "Status";
+
+    public static final String CSV_REFERENCE =
+        "export.fixings.deltawt.csv.reference";
+
+    public static final String CSV_ANALYSIS =
+        "export.fixings.deltawt.csv.analysis";
+
+    public static final String DEFAULT_CSV_REFERENCE =
+        "B";
+
+    public static final String DEFAULT_CSV_ANALYSIS =
+        "A{0,number,integer}";
+
+    public static final String DEFAULT_CSV_T_FORMAT =
+        "dd.MM.yyyy";
 
     protected List<KMIndex<AnalysisPeriod []>> analysisPeriods;
 
@@ -79,10 +109,10 @@
         }
 
         Object data = ((CalculationResult)d).getData();
-        if (!(data instanceof FixResult)) {
+        if (!(data instanceof FixAnalysisResult)) {
             log.warn("Invalid data stored in result.");
         }
-        FixResult result = (FixResult)data;
+        FixAnalysisResult result = (FixAnalysisResult)data;
         analysisPeriods.add(result.getAnalysisPeriods());
         referenceEvents.add(result.getReferenced());
     }
@@ -96,10 +126,12 @@
 
         NumberFormat kmF = getKMFormatter();
         NumberFormat dwF = getDeltaWFormatter();
+        NumberFormat qF  = getQFormatter();
+        NumberFormat wF  = getWFormatter();
 
-        CallMeta meta = context.getMeta();
-        Locale locale = Resources.getLocale(meta);
-        DateFormat dF = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        DateFormat dF = getDateFormatter();
+
+        String referenceS = getReference();
 
         for (KMIndex<QWD[]> reference: referenceEvents) {
 
@@ -107,18 +139,19 @@
 
                String kmS = kmF.format(kmEntry.getKm());
                for (QWD qwd: kmEntry.getValue()) {
-                    double deltaW = qwd.getDeltaW();
-                    Date   date   = qwd.getDate();
-                    String desc   = qwd.getDescription();
-
-                    String deltaWS = dwF.format(deltaW);
-                    String dateS   = dF.format(date);
+                    String deltaWS = dwF.format(qwd.getDeltaW());
+                    String qS      = qF.format(qwd.getQ());
+                    String wS      = wF.format(qwd.getW());
+                    String dateS   = dF.format(qwd.getDate());
 
                     writer.writeNext(new String[] {
                         kmS,
-                        deltaWS,
                         dateS,
-                        desc != null ? desc : "" });
+                        qS,
+                        wS,
+                        referenceS,
+                        deltaWS
+                        });
                }
             }
         }
@@ -127,36 +160,61 @@
             log.debug("AnalysisPeriods: " + analysisPeriods.size());
         }
 
+        String analysisTemplate = getAnalysisTemplate();
+
+        int analysisCount = 1;
+
         for (KMIndex<AnalysisPeriod []> periods: analysisPeriods) {
 
+            // Typically resulting in A1,A2...
+            String analyisS = MessageFormat.format(
+                analysisTemplate, analysisCount);
+
             for (KMIndex.Entry<AnalysisPeriod []> kmEntry: periods) {
 
                 String kmS = kmF.format(kmEntry.getKm());
 
                 for (AnalysisPeriod period: kmEntry.getValue()) {
                     QWD [] qwds = period.getQWDs();
+                    /* issue825
+                    km; Ereignis, Abfluss, GEMESSENER Wasserstand; Status (RECHTSBÃœNDIG), del W
+                    */
+
                     if (qwds != null) {
                         for (QWD qwd: qwds) {
-                            double deltaW = qwd.getDeltaW();
-                            Date   date   = qwd.getDate();
-                            String desc   = qwd.getDescription();
-
-                            String deltaWS = dwF.format(deltaW);
-                            String dateS   = dF.format(date);
+                            String deltaWS = dwF.format(qwd.getDeltaW());
+                            String qS      = qF.format(qwd.getQ());
+                            String wS      = wF.format(qwd.getW());
+                            String dateS   = dF.format(qwd.getDate());
 
                             writer.writeNext(new String[] {
                                 kmS,
-                                deltaWS,
                                 dateS,
-                                desc != null ? desc : "" });
+                                qS,
+                                wS,
+                                analyisS,
+                                deltaWS });
                         }
                     }
                 }
             }
+            ++analysisCount;
         }
         writer.flush();
     }
 
+    /** Template to create "State" strings like A1,A2... */
+    protected String getAnalysisTemplate() {
+        return Resources.getMsg(
+            context.getMeta(),
+            CSV_ANALYSIS, DEFAULT_CSV_ANALYSIS);
+    }
+
+    protected String getReference() {
+        return Resources.getMsg(
+            context.getMeta(),
+            CSV_REFERENCE, DEFAULT_CSV_REFERENCE);
+    }
 
     protected NumberFormat getKMFormatter() {
         return Formatter.getFixDeltaWKM(context);
@@ -166,14 +224,38 @@
         return Formatter.getFixDeltaWDeltaW(context);
     }
 
+    protected NumberFormat getQFormatter() {
+        return Formatter.getFixDeltaWQ(context);
+    }
+
+    protected NumberFormat getWFormatter() {
+        return Formatter.getFixDeltaWW(context);
+    }
+
+    protected DateFormat getDateFormatter() {
+        CallMeta meta = context.getMeta();
+        return Formatter.getDateFormatter(
+            meta,
+            Resources.getMsg(
+                meta,
+                CSV_T_FORMAT,
+                DEFAULT_CSV_T_FORMAT));
+    }
+
     protected void writeCSVHeader(CSVWriter writer) {
         log.debug("DeltaWtExporter.writeCSVHeader");
 
+        /* issue825
+        km; Ereignis, Abfluss, GEMESSENER Wasserstand; Status (RECHTSBÃœNDIG), del W
+        */
+
         writer.writeNext(new String[] {
             msg(CSV_KM_HEADER,      DEFAULT_CSV_KM_HEADER),
-            msg(CSV_DELTA_W_HEADER, DEFAULT_CSV_DELTA_W_HEADER),
             msg(CSV_T_HEADER,       DEFAULT_CSV_T_HEADER),
-            msg(CSV_T_DESC_HEADER,  DEFAULT_CSV_T_DESC_HEADER)
+            msg(CSV_Q_HEADER,       DEFAULT_CSV_Q_HEADER),
+            msg(CSV_W_HEADER,       DEFAULT_CSV_W_HEADER),
+            msg(CSV_TRANGE_HEADER,  DEFAULT_CSV_TRANGE_DESC_HEADER),
+            msg(CSV_DELTA_W_HEADER, DEFAULT_CSV_DELTA_W_HEADER)
         });
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATExport.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,101 @@
+package de.intevation.flys.exports.fixings;
+
+import au.com.bytecode.opencsv.CSVWriter;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.access.FixAccess;
+
+import de.intevation.flys.artifacts.math.fitting.Function;
+import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
+
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.Parameters;
+
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisResult;
+
+import de.intevation.flys.exports.AbstractExporter;
+
+import de.intevation.flys.utils.FLYSUtils;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+/** Export result of fixation analysis. */
+public class FixATExport extends AbstractExporter {
+
+    /** Private logger. */
+    private static Logger logger =
+        Logger.getLogger(FixATExport.class);
+
+    protected Function function;
+    protected Parameters parameters;
+
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        logger.debug("AT Export doOut().");
+        Object data = bundle.getData(context);
+        if (data instanceof CalculationResult) {
+            CalculationResult cr = (CalculationResult)data;
+            Object resData = cr.getData();
+            if (resData instanceof FixAnalysisResult) {
+                this.parameters = ((FixAnalysisResult)resData).getParameters();
+            }
+        }
+        else {
+            logger.debug("No CalculationResult found for AT export.");
+            return;
+        }
+        FixAccess access = new FixAccess((FLYSArtifact)this.master);
+        String f = access.getFunction();
+        if (f == null || f.length() == 0) {
+            logger.debug("No function found for AT export.");
+            return;
+        }
+        this.function = FunctionFactory.getInstance().getFunction(f);
+    }
+
+    @Override
+    public void generate() throws IOException {
+        if (this.function == null || this.parameters == null) {
+            logger.debug("No function or paramters for AT export.");
+            return;
+        }
+
+        Writer writer = new OutputStreamWriter(out, DEFAULT_CSV_CHARSET);
+
+        FixATWriter atWriter = new FixATWriter(this.function, this.parameters);
+        NodeList nodes = request.getElementsByTagName("km");
+        String km = nodes.item(0).getTextContent();
+        double dkm = Double.parseDouble(km);
+        String river = FLYSUtils.getRivername((FLYSArtifact)master);
+        atWriter.write(writer, context.getMeta(), river, dkm);
+        writer.close();
+    }
+
+    @Override
+    protected void writeCSVData(CSVWriter writer) throws IOException {
+        // The concrete writer is used to write csv data.
+    }
+
+    @Override
+    protected void writePDF(OutputStream out) {
+        // Implement me!
+    }
+
+    @Override
+    protected void addData(Object data) {
+        // Nothing to do here.
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -14,14 +14,14 @@
 import java.io.PrintWriter;
 import java.io.Writer;
 
-import java.util.ArrayDeque;
-import java.util.Collection;
 import java.util.Locale;
 
 import org.apache.log4j.Logger;
 
+/** Export Fixation Analysis Results to AT. */
 public class FixATWriter
 {
+    /** Private logger. */
     private static Logger log = Logger.getLogger(FixATWriter.class);
 
     public static final String I18N_HEADER_KEY =
@@ -32,19 +32,9 @@
 
     public static final String [] Q_MAX_COLUMN = new String [] { "max_q" };
 
-    public static class WQ {
-
-        protected double w;
-        protected double q;
-
-        public WQ() {
-        }
-
-        public WQ(double w, double q) {
-            this.w = w;
-            this.q = q;
-        }
-    } // class WQ
+    private static final int    MAX_ITERATIONS = 10000;
+    private static final double EPSILON        = 1e-8;
+    private static final double MIN_Q          = 1e-4;
 
     protected Function   function;
     protected Parameters parameters;
@@ -81,6 +71,9 @@
         de.intevation.flys.artifacts.math.Function funcInst =
             function.instantiate(coeffs);
 
+        // Increase Q max about 5%.
+        qMax[0] += Math.abs(qMax[0])*0.05;
+
         double wMax = funcInst.value(qMax[0]);
 
         if (Double.isNaN(wMax) || wMax < 0d) {
@@ -94,73 +87,61 @@
         de.intevation.flys.artifacts.math.Function invInst =
             inverse.instantiate(coeffs);
 
-        /* TODO: Do some fancy root finding stuff with the
-         * first derivative of the inverse function to find
-         * the minimum of function and directly export
-         * the longest strict monotonous ascending run of
-         * ws of the inverse in range [0, wMax].
-         *
-         * To simplify the situation we iterate in steps
-         * of 10cm over the range and export the longest
-         * run.
-         */
-
-        ArrayDeque<WQ> longest = new ArrayDeque<WQ>();
-        ArrayDeque<WQ> current = new ArrayDeque<WQ>();
+        double wMin = minW(invInst, wMax, qMax[0]);
 
-        for (double w = 0d; w <= wMax; w += 0.1d) {
-            double q = invInst.value(w);
-
-            if (Double.isNaN(q)) {
-                log.debug("Eval of inverse for " + w + " failed.");
-                continue;
-            }
+        double wMinCM = wMin * 100d;
+        double wMaxCM = wMax * 100d;
 
-            WQ wq = new WQ(w, q);
+        int wRow = ((int)wMinCM / 10) * 10;
 
-            if (current.isEmpty() || current.getLast().q < q) {
-                current.add(wq);
-            }
-            else {
-                if (current.size() >= longest.size()) {
-                    longest = current;
-                }
-                current = new ArrayDeque<WQ>();
-                current.add(wq);
+        if ((wMinCM - (int)wMinCM) > 0d) {
+            wMinCM = (int)wMinCM + 1d;
+        }
+
+        double w = wMinCM / 100.0;
+
+        int wcm = ((int)wMinCM) % 10;
+
+        if (log.isDebugEnabled()) {
+            log.debug("wMinCM: " + wMinCM);
+            log.debug("wMaxCM: " + wMaxCM);
+            log.debug("wcm: " + wcm);
+        }
+
+        out.printf(Locale.US, "%8d", wRow);
+
+        if (wcm > 0) {
+            int rest = 10 - wcm;
+            while (rest-- > 0) {
+                out.print(ATWriter.EMPTY);
             }
         }
 
-        if (current.size() >= longest.size()) {
-            longest = current;
+        for (;;) {
+            while (wcm++ < 10) {
+                if (w > wMax) {
+                    break;
+                }
+                double q = invInst.value(w);
+                if (Double.isNaN(w)) {
+                    out.print(ATWriter.EMPTY);
+                }
+                else {
+                    ATWriter.printQ(out, q);
+                }
+                w += 0.01d;
+            }
+            out.println();
+            if (w > wMax) {
+                break;
+            }
+            out.printf(Locale.US, "%8d", wRow += 10);
+            wcm = 0;
         }
 
-        printWQs(out, longest);
         out.flush();
     }
 
-    protected void printWQs(PrintWriter out, Collection<WQ> wqs) {
-        int lastColumn = 10;
-        for (WQ wq: wqs) {
-            int column = (int)(wq.w * 10d) % 10;
-
-            if (lastColumn > column) {
-                for (; lastColumn < 10; ++lastColumn) {
-                    out.print(ATWriter.EMPTY);
-                }
-                out.println();
-                out.printf(Locale.US, "%8d", (int)Math.round(wq.w*100.0));
-                lastColumn = 0;
-            }
-            for (;lastColumn < column-1; ++lastColumn) {
-                out.print(ATWriter.EMPTY);
-            }
-            ATWriter.printQ(out, wq.q);
-
-            lastColumn = column;
-        }
-        out.println();
-    }
-
     protected void printHeader(
         PrintWriter out,
         CallMeta    meta,
@@ -173,5 +154,34 @@
             I18N_HEADER_DEFAULT,
             river, km));
     }
+
+    private static double minW(
+        de.intevation.flys.artifacts.math.Function function,
+        double maxW,
+        double maxQ
+    ) {
+        double stepWidth = 10d;
+
+        double lastW = maxW;
+        double lastQ = maxQ;
+
+        for (int i = 0; i < MAX_ITERATIONS; ++i) {
+            double w = lastW - stepWidth;
+            double q = function.value(w);
+
+            if (Double.isNaN(q) || q > lastQ || q < MIN_Q) {
+                if (stepWidth < EPSILON) {
+                    break;
+                }
+                stepWidth *= 0.5d;
+                continue;
+            }
+
+            lastW = w;
+            lastQ = q;
+        }
+
+        return lastW;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixChartGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixChartGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,24 +1,26 @@
 package de.intevation.flys.exports.fixings;
 
-import org.w3c.dom.Document;
-
-import org.apache.log4j.Logger;
+import de.intevation.artifacts.ArtifactNamespaceContext;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.exports.XYChartGenerator;
 
 import java.io.OutputStream;
 
-import de.intevation.artifacts.ArtifactNamespaceContext;
-import de.intevation.artifacts.common.utils.XMLUtils;
-import de.intevation.artifacts.CallContext;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
 
-import de.intevation.flys.exports.XYChartGenerator;
-
+/**
+ * Base class for FixChartGenerator.
+ */
 public abstract class FixChartGenerator
 extends XYChartGenerator
 {
+    /** Private logger. */
     private static Logger logger = Logger.getLogger(FixChartGenerator.class);
 
     public static final Double INVALID_KM = Double.valueOf(-1d);
-
+    public static final String CURRENT_KM = "currentKm";
     public static final String XPATH_CHART_CURRENTKM =
         "/art:action/art:attributes/art:currentKm/@art:km";
 
@@ -32,10 +34,10 @@
             logger.debug("currentKm = " + currentKm);
         }
 
-        context.putContextValue("currentKm", currentKm);
+        context.putContextValue(CURRENT_KM, currentKm);
     }
 
-    public static Double getCurrentKmFromRequest(Document request) {
+    public static final Double getCurrentKmFromRequest(Document request) {
 
         String km = XMLUtils.xpathString(
             request,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,13 +1,29 @@
 package de.intevation.flys.exports.fixings;
 
+import java.io.OutputStream;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.data.time.Day;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.w3c.dom.Document;
+
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-import de.intevation.artifacts.ArtifactNamespaceContext;
 import de.intevation.artifacts.CallContext;
-import de.intevation.artifacts.common.utils.XMLUtils;
 import de.intevation.flys.artifacts.FLYSArtifact;
-import de.intevation.flys.artifacts.access.FixationArtifactAccess;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
 import de.intevation.flys.artifacts.model.DateRange;
 import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.QWDDateRange;
 import de.intevation.flys.artifacts.model.fixings.QWD;
 import de.intevation.flys.artifacts.resources.Resources;
 import de.intevation.flys.exports.TimeseriesChartGenerator;
@@ -18,27 +34,6 @@
 import de.intevation.flys.jfree.StyledValueMarker;
 import de.intevation.flys.utils.ThemeUtil;
 
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.xpath.XPathConstants;
-
-import org.apache.log4j.Logger;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.annotations.XYTextAnnotation;
-import org.jfree.chart.title.TextTitle;
-import org.jfree.data.time.Day;
-import org.jfree.data.time.Month;
-import org.jfree.data.time.RegularTimePeriod;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
 
 /**
  * Generator for Delta W(t) charts.
@@ -48,26 +43,24 @@
 extends      TimeseriesChartGenerator
 implements   FacetTypes
 {
+    /** Private logger. */
     private static Logger logger =
-        Logger.getLogger(FixDeltaWtGenerator.class);
-
-    public static final String XPATH_CHART_CURRENTKM =
-        "/art:action/art:attributes/art:currentKm";
+            Logger.getLogger(FixDeltaWtGenerator.class);
 
     public static final String I18N_CHART_TITLE =
-        "chart.fix.deltawt.title";
+            "chart.fix.deltawt.title";
 
     public static final String I18N_CHART_SUBTITLE =
-        "chart.fix.deltawt.subtitle";
+            "chart.fix.deltawt.subtitle";
 
     public static final String I18N_XAXIS_LABEL =
-        "chart.fix.deltawt.xaxis.label";
+            "chart.fix.deltawt.xaxis.label";
 
     public static final String I18N_YAXIS_LABEL =
-        "chart.fix.deltawt.yaxis.label";
+            "chart.fix.deltawt.yaxis.label";
 
     public static final String I18N_YAXIS_SECOND_LABEL =
-        "chart.fix.deltawt.yaxis.second.label";
+            "chart.fix.deltawt.yaxis.second.label";
 
 
     public static enum YAXIS {
@@ -106,29 +99,30 @@
 
 
     @Override
+    protected String getChartTitle() {
+        return Resources.format(
+                context.getMeta(),
+                I18N_CHART_TITLE,
+                "",
+                FixChartGenerator
+                .getCurrentKmFromRequest(request).doubleValue());
+    }
+
+
+    @Override
     protected String getDefaultChartSubtitle() {
-        FixationArtifactAccess access = new FixationArtifactAccess(artifact);
-        DateRange range = access.getDateRange();
+        FixAnalysisAccess access = new FixAnalysisAccess(artifact);
+        DateRange dateRange = access.getDateRange();
+        DateRange refRange  = access.getReferencePeriod();
         return Resources.format(
                 context.getMeta(),
                 I18N_CHART_SUBTITLE,
                 "",
                 access.getRiver(),
-                range.getFrom(),
-                range.getTo());
-    }
-
-
-    /**
-     * Empty (suppress subtitle).
-     */
-    @Override
-    protected void addSubtitles(JFreeChart chart) {
-        String subtitle = getChartSubtitle();
-
-        if (subtitle != null && subtitle.length() > 0) {
-            chart.addSubtitle(new TextTitle(subtitle));
-        }
+                dateRange.getFrom(),
+                dateRange.getTo(),
+                refRange.getFrom(),
+                refRange.getTo());
     }
 
 
@@ -153,10 +147,10 @@
 
     @Override
     public void doOut(
-        ArtifactAndFacet artifactFacet,
-        Document         theme,
-        boolean          visible
-    ) {
+            ArtifactAndFacet artifactFacet,
+            Document         theme,
+            boolean          visible
+            ) {
         String name = artifactFacet.getFacetName();
         logger.debug("FixDeltaWtGenerator.doOut: " + name);
         logger.debug("Theme description is: " + artifactFacet.getFacetDescription());
@@ -165,102 +159,154 @@
 
         if (name.contains(FIX_SECTOR_AVERAGE_DWT)) {
             doSectorAverageOut(
-                (FLYSArtifact) artifactFacet.getArtifact(),
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                theme,
-                visible);
+                    (FLYSArtifact) artifactFacet.getArtifact(),
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    theme,
+                    visible);
         }
         else if (name.equals(FIX_REFERENCE_EVENTS_DWT)) {
             doReferenceEventsOut(
-                (FLYSArtifact) artifactFacet.getArtifact(),
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                theme,
-                visible);
+                    (FLYSArtifact) artifactFacet.getArtifact(),
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    theme,
+                    visible);
         }
         else if (name.equals(FIX_ANALYSIS_EVENTS_DWT)) {
             doAnalysisEventsOut(
-                (FLYSArtifact) artifactFacet.getArtifact(),
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                theme,
-                visible);
+                    (FLYSArtifact) artifactFacet.getArtifact(),
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    theme,
+                    visible);
         }
         else if (name.equals(FIX_DEVIATION_DWT)) {
             doDeviationOut(
-                (FLYSArtifact) artifactFacet.getArtifact(),
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                theme,
-                visible);
+                    (FLYSArtifact) artifactFacet.getArtifact(),
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    theme,
+                    visible);
         }
         else if (name.equals(FIX_ANALYSIS_PERIODS_DWT)) {
             doAnalysisPeriodsOut(
-                (FLYSArtifact) artifactFacet.getArtifact(),
-                artifactFacet.getData(context),
-                artifactFacet.getFacetDescription(),
-                theme,
-                visible);
+                    (FLYSArtifact) artifactFacet.getArtifact(),
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    theme,
+                    visible);
+        }
+        else if (name.equals(FIX_REFERENCE_PERIOD_DWT)) {
+            doReferencePeriodsOut(
+                    (FLYSArtifact) artifactFacet.getArtifact(),
+                    artifactFacet.getData(context),
+                    artifactFacet.getFacetDescription(),
+                    theme,
+                    visible);
+        }
+        else if (FacetTypes.IS.MANUALPOINTS(name)) {
+            doPoints (artifactFacet.getData(context),
+                    artifactFacet,
+                    theme, visible, YAXIS.dW.idx);
         }
         else {
-           logger.warn("doOut(): unknown facet name: " + name);
-           return;
+            logger.warn("doOut(): unknown facet name: " + name);
+            return;
         }
     }
 
 
+    protected void doReferencePeriodsOut(
+            FLYSArtifact artifact,
+            Object       data,
+            String       desc,
+            Document     theme,
+            boolean      visible)
+    {
+        logger.debug("doReferencePeriodsOut()");
+
+        FixAnalysisAccess access = new FixAnalysisAccess(artifact);
+        DateRange refRange  = access.getReferencePeriod();
+
+        RegularTimePeriod start = new Day(refRange.getFrom());
+        RegularTimePeriod end = new Day(refRange.getTo());
+        StyledDomainMarker marker = new StyledDomainMarker(
+                start.getMiddleMillisecond(),
+                end.getMiddleMillisecond(),
+                theme);
+        domainMarker.add(marker);
+    }
+
+
     protected void doSectorAverageOut(
-        FLYSArtifact artifact,
-        Object       data,
-        String       desc,
-        Document     theme,
-        boolean      visible)
+            FLYSArtifact artifact,
+            Object       data,
+            String       desc,
+            Document     theme,
+            boolean      visible)
     {
         logger.debug("doSectorAverageOut(): description = " + desc);
 
-        QWD qwd = (QWD) data;
+        QWDDateRange qwd = (QWDDateRange) data;
         TimeSeriesCollection tsc = new TimeSeriesCollection();
         TimeSeries        series = new StyledTimeSeries(desc, theme);
 
-        if (qwd == null) {
+        if (qwd == null || qwd.qwd == null || qwd.dateRange == null) {
             return;
         }
-        RegularTimePeriod rtp = new Day(qwd.getDate());
-        double value = qwd.getDeltaW();
+        RegularTimePeriod rtp = new Day(qwd.qwd.getDate());
+        double value = qwd.qwd.getDeltaW();
+
+        // Draw a line spanning the analysis time.
         series.add(rtp, value);
+        rtp = new Day(qwd.dateRange.getFrom());
+        series.addOrUpdate(rtp, value);
+        rtp = new Day(qwd.dateRange.getTo());
+        series.addOrUpdate(rtp, value);
+
         tsc.addSeries(series);
 
         addAxisDataset(tsc, 0, visible);
-        addAttribute(desc, "outline");
-        Map<Integer, int[]> annoIdxMap = new HashMap<Integer, int[]>();
-        annoIdxMap.put (0, new int[]{0,0});
-        doQWDTextAnnotations(annoIdxMap, tsc, new QWD[]{qwd}, theme, visible);
+
+        if (visible && ThemeUtil.parseShowLineLabel(theme)) {
+            List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
+            XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
+                    "\u0394 W(t) [cm] " + (float)Math.round(qwd.qwd.getDeltaW() * 10000) / 10000,
+                    tsc.getXValue(0, 0),
+                    qwd.qwd.getDeltaW());
+            textAnnos.add(anno);
+
+            FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
+            flysAnno.setTextAnnotations(textAnnos);
+            addAnnotations(flysAnno);
+        }
     }
 
 
     protected void doAnalysisEventsOut(
-        FLYSArtifact artifact,
-        Object       data,
-        String       desc,
-        Document     theme,
-        boolean      visible
-    ) {
+            FLYSArtifact artifact,
+            Object       data,
+            String       desc,
+            Document     theme,
+            boolean      visible
+            ) {
         logger.debug("doAnalysisEventsOut: desc = " + desc);
 
-        QWD[] qwds = (QWD[]) data;
+        QWD qwd = (QWD) data;
+        doQWDEventsOut(qwd, desc, theme, visible);
+    }
+
+
+    protected void doQWDEventsOut(QWD qwd, String desc, Document theme, boolean visible)
+    {
         TimeSeriesCollection tsc = new TimeSeriesCollection();
 
         TimeSeries   series = new StyledTimeSeries(desc, theme);
         TimeSeries interpol = new StyledTimeSeries(desc + "interpol", theme);
 
-        if (qwds == null) {
-            logger.debug("doAnalysisEventsOut: qwds == null");
-            return;
-        }
-
-        if (qwds.length == 0) {
-            logger.debug("doAnalysisEventsOut: qwds.length == 0");
+        if (qwd == null) {
+            logger.debug("doQWDEventsOut: qwd == null");
             return;
         }
 
@@ -268,44 +314,41 @@
 
         int idxInterpol = 0;
         int idxRegular = 0;
-        for (int i = 0; i < qwds.length; i++) {
-            if (qwds[i] == null) {
-                logger.debug("doAnalysisEventsOut: qwds[" + i + "] == null");
-                continue;
-            }
-            RegularTimePeriod rtp = new Day(qwds[i].getDate());
-            double value =  qwds[i].getDeltaW();
-            boolean interpolate = qwds[i].getInterpolated();
-            if (interpolate) {
-                interpol.add(rtp, value);
+        RegularTimePeriod rtp = new Day(qwd.getDate());
+        double value =  qwd.getDeltaW();
+        boolean interpolate = qwd.getInterpolated();
+        if (interpolate) {
+            if(interpol.addOrUpdate(rtp, value) == null) {
                 annoIdxMap.put(
-                    i,
-                    new int[]{1, idxInterpol++});
-            }
-            else {
-                series.add(rtp, value);
-                annoIdxMap.put(
-                    i,
-                    new int[]{0, idxRegular++});
+                        0,
+                        new int[]{1, idxInterpol});
+                idxInterpol++;
             }
         }
+        else {
+            if(series.addOrUpdate(rtp, value) == null) {
+                annoIdxMap.put(
+                        0,
+                        new int[]{0, idxRegular});
+                idxRegular++;
+            }
+        }
+
         tsc.addSeries(series);
         tsc.addSeries(interpol);
         addAxisDataset(tsc, 0, visible);
         addAttribute(desc + "interpol", "interpolate");
         addAttribute(desc, "outline");
 
-        if (visible) {
-            doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible);
-        }
+        doQWDTextAnnotations(annoIdxMap, tsc, qwd, theme, visible);
     }
 
 
     /**
-     * @param annoIdxMap map of index in qwds to series/dataitem indices in tsc.
+     * @param annoIdxMap map of index in qwds to series/data item indices in tsc.
      */
     protected void doQWDTextAnnotations(Map<Integer, int[]> annoIdxMap,
-            TimeSeriesCollection tsc, QWD[] qwds, Document theme,
+            TimeSeriesCollection tsc, QWD qwd, Document theme,
             boolean visible) {
         logger.debug("doQWDTextAnnotation()");
 
@@ -314,19 +357,21 @@
             return;
         }
 
+        Locale locale = Resources.getLocale(context.getMeta());
+        NumberFormat nf = NumberFormat.getInstance(locale);
+
         List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
         Set<Map.Entry<Integer, int[]>> entries = annoIdxMap.entrySet();
 
         for(Map.Entry<Integer, int[]> entry : entries) {
-            QWD qwd = qwds[entry.getKey()];
             int[] idxs = entry.getValue();
             double x = tsc.getXValue(idxs[0], idxs[1]);
+
             XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
-                qwd.getQ() + " m\u00B3/s",
-                x,
-                qwd.getDeltaW());
+                    nf.format(qwd.getQ()) + " m\u00B3/s",
+                    x,
+                    qwd.getDeltaW());
             textAnnos.add(anno);
-            logger.debug("annotation: " + x + "/" + qwd.getDeltaW());
         }
 
         FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
@@ -336,70 +381,26 @@
 
 
     protected void doReferenceEventsOut(
-        FLYSArtifact artifact,
-        Object       data,
-        String       desc,
-        Document     theme,
-        boolean      visible
-    ) {
+            FLYSArtifact artifact,
+            Object       data,
+            String       desc,
+            Document     theme,
+            boolean      visible
+            ) {
         logger.debug("doReferenceEventsOut: desc = " + desc);
 
-        QWD[] qwds = (QWD[]) data;
-        TimeSeriesCollection tsc = new TimeSeriesCollection();
-
-        TimeSeries   series = new StyledTimeSeries(desc, theme);
-        TimeSeries interpol = new StyledTimeSeries(desc + "interpol", theme);
-
-        if (qwds == null) {
-            return;
-        }
-
-        Map<Integer, int[]> annoIdxMap = new HashMap<Integer, int[]>();
-
-        int idxInterpol = 0;
-        int idxRegular = 0;
-        for (int i = 0; i < qwds.length; i++) {
-            if (qwds[i] == null) {
-                continue;
-            }
-            RegularTimePeriod rtp = new Day(qwds[i].getDate());
-            double value =  qwds[i].getDeltaW();
-            boolean interpolate = qwds[i].getInterpolated();
-            if (interpolate) {
-                if(interpol.addOrUpdate(rtp, value) == null) {
-                    annoIdxMap.put(
-                            i,
-                            new int[]{1, idxInterpol});
-                    idxInterpol++;
-                }
-            }
-            else {
-                if(series.addOrUpdate(rtp, value) == null) {
-                    annoIdxMap.put(
-                            i,
-                            new int[]{0, idxRegular});
-                    idxRegular++;
-                }
-            }
-        }
-        tsc.addSeries(series);
-        tsc.addSeries(interpol);
-
-        addAxisDataset(tsc, 0, visible);
-        addAttribute(desc + "interpol", "interpolate");
-        addAttribute(desc, "outline");
-
-        doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible);
+        QWD qwd = (QWD) data;
+        doQWDEventsOut(qwd, desc, theme, visible);
     }
 
 
     protected void doDeviationOut(
-        FLYSArtifact artifact,
-        Object       data,
-        String       desc,
-        Document     theme,
-        boolean      visible
-    ) {
+            FLYSArtifact artifact,
+            Object       data,
+            String       desc,
+            Document     theme,
+            boolean      visible
+            ) {
         logger.debug("doDeviationOut: desc = " + desc);
 
         if (data == null || !visible) {
@@ -416,25 +417,23 @@
 
 
     protected void doAnalysisPeriodsOut(
-        FLYSArtifact artifact,
-        Object       data,
-        String       desc,
-        Document     theme,
-        boolean      visible
-    ) {
-        logger.debug("doHistoricalDischargeDifferenceOut: desc = " + desc);
-
+            FLYSArtifact artifact,
+            Object       data,
+            String       desc,
+            Document     theme,
+            boolean      visible)
+    {
         DateRange[] ranges = (DateRange[]) data;
         if (ranges == null || !visible) {
             return;
         }
         for (int i = 0; i < ranges.length; i++) {
             logger.debug("creating domain marker");
-            RegularTimePeriod start = new Month(ranges[i].getFrom());
-            RegularTimePeriod end = new Month(ranges[i].getTo());
+            RegularTimePeriod start = new Day(ranges[i].getFrom());
+            RegularTimePeriod end = new Day(ranges[i].getTo());
             StyledDomainMarker marker =
-                new StyledDomainMarker(start.getMiddleMillisecond(),
-                                   end.getMiddleMillisecond(), theme);
+                    new StyledDomainMarker(start.getMiddleMillisecond(),
+                            end.getMiddleMillisecond(), theme);
             marker.useSecondColor(i % 2 == 0);
             domainMarker.add(marker);
         }
@@ -446,36 +445,16 @@
     public void init(Document request, OutputStream out, CallContext context) {
         super.init(request, out, context);
 
-        logger.debug("currentKm = " + new Double(getCurrentKmFromRequest()));
-        context.putContextValue("currentKm", new Double(getCurrentKmFromRequest()));
+        Double currentKm = FixChartGenerator.getCurrentKmFromRequest(request);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("currentKm = " + currentKm);
+        }
+
+        context.putContextValue("currentKm", currentKm);
 
         StyledValueMarker marker = new StyledValueMarker(0, request);
         valueMarker.add(marker);
     }
-
-    public double getCurrentKmFromRequest() {
-        Element km = (Element)XMLUtils.xpath(
-            request,
-            XPATH_CHART_CURRENTKM,
-            XPathConstants.NODE,
-            ArtifactNamespaceContext.INSTANCE);
-
-        if (km == null) {
-            return -1d;
-        }
-
-        String uri = ArtifactNamespaceContext.NAMESPACE_URI;
-
-        String currentKm = km.getAttributeNS(uri, "km");
-        try {
-            double d = Double.valueOf(currentKm).doubleValue();
-            return d;
-        }
-        catch(NumberFormatException nfe) {
-            return -1d;
-        }
-    }
-
-
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDerivedCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDerivedCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,21 +1,17 @@
 package de.intevation.flys.exports.fixings;
 
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-
 import de.intevation.flys.artifacts.model.FacetTypes;
-
 import de.intevation.flys.artifacts.model.fixings.FixDerivateFacet;
 import de.intevation.flys.artifacts.model.fixings.FixFunction;
-
+import de.intevation.flys.artifacts.resources.Resources;
 import de.intevation.flys.exports.ChartGenerator;
-
 import de.intevation.flys.jfree.JFreeUtil;
 import de.intevation.flys.jfree.StyledXYSeries;
 
-import org.apache.log4j.Logger;
-
-import org.w3c.dom.Document;
-
 /**
  * Generator for fixation derived function curve.
  *
@@ -25,29 +21,30 @@
 extends FixChartGenerator
 implements FacetTypes
 {
+    /** Private logger. */
     private static Logger logger =
-        Logger.getLogger(FixDerivedCurveGenerator.class);
+            Logger.getLogger(FixDerivedCurveGenerator.class);
 
     public static final String I18N_CHART_TITLE =
-        "chart.fixings.derived.title";
+            "chart.fixings.derivedcurve.title";
 
     public static final String I18N_CHART_SUBTITLE =
-        "chart.fixings.derived.subtitle";
+            "chart.fixings.derivedcurve.subtitle";
 
     public static final String I18N_XAXIS_LABEL =
-        "chart.fixings.derived.xaxis.label";
+            "chart.fixings.derivedcurve.xaxis.label";
 
     public static final String I18N_YAXIS_LABEL =
-        "chart.fixings.derived.yaxis.label";
+            "chart.fixings.derivedcurve.yaxis.label";
 
     public static final String I18N_CHART_TITLE_DEFAULT =
-        "Ableitungskurve";
+            "Ableitungskurve";
 
     public static final String I18N_XAXIS_LABEL_DEFAULT =
-        "Q [m\u00B3/s]";
+            "Q [m\u00B3/s]";
 
     public static final String I18N_YAXIS_LABEL_DEFAULT =
-        "W [NN + m]";
+            "W [NN + m]";
 
     public static enum YAXIS {
         W(0),
@@ -63,26 +60,33 @@
     public void doOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
         logger.debug("doOut");
 
-        FixDerivateFacet facet = (FixDerivateFacet)aaf.getFacet();
-        FixFunction func = (FixFunction)facet.getData(
-            aaf.getArtifact(), context);
-
-        if (func == null) {
-            logger.warn("doOut: Facet does not contain FixFunction");
-            return;
+        if (FacetTypes.IS.MANUALPOINTS(aaf.getFacetName())) {
+            doPoints(aaf.getData(context),
+                    aaf,
+                    doc, visible, YAXIS.W.idx);
         }
+        else {
+            FixDerivateFacet facet = (FixDerivateFacet)aaf.getFacet();
+            FixFunction func = (FixFunction)facet.getData(
+                    aaf.getArtifact(), context);
 
-        double maxQ = func.getMaxQ();
+            if (func == null) {
+                logger.warn("doOut: Facet does not contain FixFunction");
+                return;
+            }
 
-        if (maxQ > 0) {
-            StyledXYSeries series = JFreeUtil.sampleFunction2D(
-                func.getFunction(),
-                doc,
-                aaf.getFacetDescription(),
-                500,   // number of samples
-                0.0 ,  // start
-                maxQ); // end
-            addAxisSeries(series, 0, visible);
+            double maxQ = func.getMaxQ();
+
+            if (maxQ > 0) {
+                StyledXYSeries series = JFreeUtil.sampleFunction2D(
+                        func.getFunction(),
+                        doc,
+                        aaf.getFacetDescription(),
+                        500,   // number of samples
+                        0.0 ,  // start
+                        maxQ); // end
+                addAxisSeries(series, 0, visible);
+            }
         }
     }
 
@@ -94,6 +98,16 @@
 
 
     @Override
+    protected String getChartTitle() {
+        return Resources.format(
+                context.getMeta(),
+                I18N_CHART_TITLE,
+                I18N_CHART_TITLE_DEFAULT,
+                context.getContextValue(CURRENT_KM));
+    }
+
+
+    @Override
     protected String getDefaultXAxisLabel() {
         return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
     }
@@ -114,12 +128,11 @@
             }
 
             @Override
-             public String getId(int idx) {
+            public String getId(int idx) {
                 YAXIS[] yaxes = YAXIS.values();
                 return yaxes[idx].toString();
             }
         };
     }
 }
-
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,19 +1,7 @@
 package de.intevation.flys.exports.fixings;
 
-import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.fixings.AnalysisPeriod;
-import de.intevation.flys.artifacts.model.fixings.QWD;
-import de.intevation.flys.exports.ChartGenerator;
-import de.intevation.flys.exports.XYChartGenerator;
-import de.intevation.flys.jfree.StyledAreaSeriesCollection;
-import de.intevation.flys.jfree.StyledXYSeries;
-import de.intevation.flys.utils.KMIndex;
-
 import java.awt.BasicStroke;
 import java.awt.Color;
-import java.util.ArrayList;
-import java.util.List;
 
 import org.apache.log4j.Logger;
 import org.jfree.chart.plot.Marker;
@@ -22,33 +10,43 @@
 import org.jfree.data.xy.XYSeriesCollection;
 import org.w3c.dom.Document;
 
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.fixings.AnalysisPeriod;
+import de.intevation.flys.artifacts.model.fixings.QWD;
+import de.intevation.flys.exports.ChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledAreaSeriesCollection;
+import de.intevation.flys.jfree.StyledXYSeries;
+import de.intevation.flys.utils.KMIndex;
+
 public class FixLongitudinalSectionGenerator
-extends XYChartGenerator
+extends FixChartGenerator
 implements FacetTypes
 {
     private static Logger logger =
-        Logger.getLogger(FixLongitudinalSectionGenerator.class);
+            Logger.getLogger(FixLongitudinalSectionGenerator.class);
 
     public static final String I18N_CHART_TITLE =
-        "chart.fixings.longitudinalsection.title";
+            "chart.fixings.longitudinalsection.title";
 
     public static final String I18N_CHART_SUBTITLE =
-        "chart.fixings.longitudinalsection.subtitle";
+            "chart.fixings.longitudinalsection.subtitle";
 
     public static final String I18N_XAXIS_LABEL =
-        "chart.fixings.longitudinalsection.xaxis.label";
+            "chart.fixings.longitudinalsection.xaxis.label";
 
     public static final String I18N_YAXIS_LABEL =
-        "chart.fixings.longitudinalsection.yaxis.label";
+            "chart.fixings.longitudinalsection.yaxis.label";
 
     public static final String I18N_CHART_TITLE_DEFAULT  =
-        "Fixierungsanalyse";
+            "Fixierungsanalyse";
 
     public static final String I18N_XAXIS_LABEL_DEFAULT  =
-        "[m]";
+            "[km]";
 
     public static final String I18N_YAXIS_LABEL_DEFAULT  =
-        "delta W [cm]";
+            "delta W [cm]";
 
     public static enum YAXIS {
         dW(0);
@@ -61,7 +59,7 @@
     @Override
     public void doOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
         String name = aaf.getFacetName();
-        logger.debug("doOut: " + name);
+        logger.debug("FixLongitudinalSectionGenerator: doOut: " + name);
 
         if (name.contains(FIX_SECTOR_AVERAGE_LS_DEVIATION)) {
             doSectorAverageDeviationOut(aaf, doc, visible);
@@ -78,6 +76,18 @@
         else if (name.equals(FIX_DEVIATION_LS)) {
             doReferenceDeviationOut(aaf, doc, visible);
         }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                    (FLYSAnnotation) aaf.getData(context),
+                    aaf,
+                    doc,
+                    visible);
+        }
+        else if (FacetTypes.IS.MANUALPOINTS(name)) {
+            doPoints (aaf.getData(context),
+                    aaf,
+                    doc, visible, YAXIS.dW.idx);
+        }
         else {
             logger.warn("Unknown facet name " + name);
             return;
@@ -86,18 +96,17 @@
 
     @SuppressWarnings("unchecked")
     protected void doSectorAverageOut(
-        ArtifactAndFacet aaf,
-        Document doc,
-        boolean visible)
+            ArtifactAndFacet aaf,
+            Document doc,
+            boolean visible)
     {
         logger.debug("doSectorAverageOut" + aaf.getFacet().getIndex());
 
         int index = aaf.getFacet().getIndex();
         int sectorNdx = index & 3;
-        int periodNdx = index >> 2;
 
-        KMIndex<AnalysisPeriod[]> kms =
-            (KMIndex<AnalysisPeriod[]>)aaf.getData(context);
+        KMIndex<AnalysisPeriod> kms =
+                (KMIndex<AnalysisPeriod>)aaf.getData(context);
 
         if(kms == null) {
             return;
@@ -105,10 +114,10 @@
 
         XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), doc);
 
-        for (KMIndex.Entry<AnalysisPeriod[]> entry: kms) {
+        for (KMIndex.Entry<AnalysisPeriod> entry: kms) {
             double km = entry.getKm();
-            AnalysisPeriod[] ap = entry.getValue();
-            QWD qwd = ap[periodNdx].getQSectorAverages()[sectorNdx];
+            AnalysisPeriod ap = entry.getValue();
+            QWD qwd = ap.getQSectorAverages()[sectorNdx];
             if (qwd == null) {
                 continue;
             }
@@ -123,18 +132,17 @@
 
     @SuppressWarnings("unchecked")
     protected void doSectorAverageDeviationOut(
-        ArtifactAndFacet aaf,
-        Document doc,
-        boolean visible)
+            ArtifactAndFacet aaf,
+            Document doc,
+            boolean visible)
     {
         logger.debug("doSectorAverageOut" + aaf.getFacet().getIndex());
 
         int index = aaf.getFacet().getIndex();
         int sectorNdx = index & 3;
-        int periodNdx = index >> 2;
 
-        KMIndex<AnalysisPeriod[]> kms =
-            (KMIndex<AnalysisPeriod[]>)aaf.getData(context);
+        KMIndex<AnalysisPeriod> kms =
+                (KMIndex<AnalysisPeriod>)aaf.getData(context);
 
         if(kms == null) {
             return;
@@ -142,16 +150,15 @@
 
         StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(doc);
         XYSeries upper =
-            new StyledXYSeries(aaf.getFacetDescription(), false, doc);
+                new StyledXYSeries(aaf.getFacetDescription(), false, doc);
         XYSeries lower =
-            new StyledXYSeries(aaf.getFacetDescription() + " ", false, doc);
-
+                new StyledXYSeries(aaf.getFacetDescription() + " ", false, doc);
 
-        for (KMIndex.Entry<AnalysisPeriod[]> entry: kms) {
+        for (KMIndex.Entry<AnalysisPeriod> entry: kms) {
             double km = entry.getKm();
-            AnalysisPeriod[] ap = entry.getValue();
-            QWD qwd = ap[periodNdx].getQSectorAverages()[sectorNdx];
-            double dev = ap[periodNdx].getQSectorStdDev(sectorNdx);
+            AnalysisPeriod ap = entry.getValue();
+            QWD qwd = ap.getQSectorAverages()[sectorNdx];
+            double dev = ap.getQSectorStdDev(sectorNdx);
             logger.debug("std-dev: " + dev);
             if (qwd == null) {
                 continue;
@@ -171,14 +178,14 @@
 
     @SuppressWarnings("unchecked")
     protected void doReferenceDeviationOut(
-        ArtifactAndFacet aaf,
-        Document doc,
-        boolean visible)
+            ArtifactAndFacet aaf,
+            Document doc,
+            boolean visible)
     {
         logger.debug("doReferenceOut");
 
         KMIndex<double[]> kms =
-            (KMIndex<double[]>)aaf.getData(context);
+                (KMIndex<double[]>)aaf.getData(context);
 
         if(kms == null) {
             return;
@@ -186,9 +193,9 @@
 
         StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(doc);
         XYSeries upper =
-            new StyledXYSeries(aaf.getFacetDescription(), false, doc);
+                new StyledXYSeries(aaf.getFacetDescription(), false, doc);
         XYSeries lower =
-            new StyledXYSeries(aaf.getFacetDescription() + " ", false, doc);
+                new StyledXYSeries(aaf.getFacetDescription() + " ", false, doc);
 
 
         for (KMIndex.Entry<double[]> entry: kms) {
@@ -215,16 +222,14 @@
 
     @SuppressWarnings("unchecked")
     protected void doAnalysisEventsOut(
-        ArtifactAndFacet aaf,
-        Document doc,
-        boolean visible)
+            ArtifactAndFacet aaf,
+            Document doc,
+            boolean visible)
     {
         logger.debug("doAnalysisEventsOut");
-        int index = aaf.getFacet().getIndex();
-        int periodNdx = index >> 2;
 
-        KMIndex<AnalysisPeriod[]> kms =
-            (KMIndex<AnalysisPeriod[]>)aaf.getData(context);
+        KMIndex<QWD> kms =
+                (KMIndex<QWD>)aaf.getData(context);
 
         if(kms == null) {
             return;
@@ -232,41 +237,29 @@
 
         XYSeriesCollection col = new XYSeriesCollection();
 
-        List<StyledXYSeries> series = new ArrayList<StyledXYSeries>();
-
-        for (KMIndex.Entry<AnalysisPeriod[]> entry: kms) {
-            double km = entry.getKm();
-            AnalysisPeriod[] ap = entry.getValue();
-            QWD[] qwds = ap[periodNdx].getQWDs();
+        StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
 
-            String space = "";
-            for (int i = 0; i < qwds.length; i++) {
-                if (series.size() <= i && qwds.length > i) {
-                    StyledXYSeries s = new StyledXYSeries(aaf.getFacetDescription() + space, false, doc);
-                    series.add (s);
-                }
-                StyledXYSeries s = series.get(i);
-                s.add(km, qwds[i].getDeltaW());
-                space+= " ";
-            }
+        for (KMIndex.Entry<QWD> entry: kms) {
+            double km = entry.getKm();
+            QWD qwd = entry.getValue();
+
+            series.add(km, qwd.getDeltaW());
         }
-        for (StyledXYSeries s: series) {
-            col.addSeries(s);
-        }
+        col.addSeries(series);
 
         addAxisDataset(col, 0, visible);
     }
 
     @SuppressWarnings("unchecked")
     protected void doReferenceEventsOut(
-        ArtifactAndFacet aaf,
-        Document doc,
-        boolean visible)
+            ArtifactAndFacet aaf,
+            Document doc,
+            boolean visible)
     {
         logger.debug("doReferenceEventOut");
 
-        KMIndex<QWD[]> kms =
-            (KMIndex<QWD[]>)aaf.getData(context);
+        KMIndex<QWD> kms =
+                (KMIndex<QWD>)aaf.getData(context);
 
         if(kms == null) {
             return;
@@ -274,26 +267,15 @@
 
         XYSeriesCollection col = new XYSeriesCollection();
 
-        List<StyledXYSeries> series = new ArrayList<StyledXYSeries>();
-
-        for (KMIndex.Entry<QWD[]> entry: kms) {
-            double km = entry.getKm();
-            QWD[] qwds = entry.getValue();
+        StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
 
-            String space = "";
-            for (int i = 0; i < qwds.length; i++) {
-                if (series.size() <= i && qwds.length > i) {
-                    StyledXYSeries s = new StyledXYSeries(aaf.getFacetDescription() + space, false, doc);
-                    series.add (s);
-                }
-                StyledXYSeries s = series.get(i);
-                s.add(km, qwds[i].getDeltaW());
-                space += " ";
-            }
+        for (KMIndex.Entry<QWD> entry: kms) {
+            double km = entry.getKm();
+            QWD qwd = entry.getValue();
+
+            series.add(km, qwd.getDeltaW());
         }
-        for (StyledXYSeries s: series) {
-            col.addSeries(s);
-        }
+        col.addSeries(series);
 
         addAxisDataset(col, 0, visible);
     }
@@ -323,7 +305,7 @@
             }
 
             @Override
-             public String getId(int idx) {
+            public String getId(int idx) {
                 YAXIS[] yaxes = YAXIS.values();
                 return yaxes[idx].toString();
             }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,27 +1,52 @@
 package de.intevation.flys.exports.fixings;
 
-import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.fixings.FixFunction;
-import de.intevation.flys.artifacts.model.fixings.FixWQCurveFacet;
-import de.intevation.flys.artifacts.model.fixings.QW;
-import de.intevation.flys.artifacts.model.fixings.QWD;
-import de.intevation.flys.exports.ChartGenerator;
-import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
-import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.JFreeUtil;
-import de.intevation.flys.jfree.StyledXYSeries;
-import de.intevation.flys.utils.ThemeUtil;
-
+import java.awt.BasicStroke;
+import java.awt.Color;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
+import org.jfree.chart.JFreeChart;
 import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.chart.plot.Marker;
+import org.jfree.chart.plot.ValueMarker;
+import org.jfree.chart.title.TextTitle;
 import org.jfree.data.xy.XYSeries;
+import org.jfree.ui.RectangleAnchor;
+import org.jfree.ui.RectangleInsets;
+import org.jfree.ui.TextAnchor;
 import org.w3c.dom.Document;
 
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.StaticWKmsArtifact;
+import de.intevation.flys.artifacts.WINFOArtifact;
+import de.intevation.flys.artifacts.access.FixAnalysisAccess;
+import de.intevation.flys.artifacts.model.DateRange;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.NamedDouble;
+import de.intevation.flys.artifacts.model.QWDDateRange;
+import de.intevation.flys.artifacts.model.WKms;
+import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.artifacts.model.fixings.FixFunction;
+import de.intevation.flys.artifacts.model.fixings.FixWQCurveFacet;
+import de.intevation.flys.artifacts.model.fixings.QWD;
+import de.intevation.flys.artifacts.model.fixings.QWI;
+import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.exports.ChartGenerator;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.JFreeUtil;
+import de.intevation.flys.jfree.StickyAxisAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+import de.intevation.flys.model.Gauge;
+import de.intevation.flys.model.River;
+import de.intevation.flys.utils.FLYSUtils;
+import de.intevation.flys.utils.ThemeUtil;
+
 /**
  * Generator for WQ fixing charts.
  * @author <a href="mailto:christian.lins@intevation.de">Christian Lins</a>
@@ -31,28 +56,31 @@
 implements   FacetTypes
 {
     private static Logger logger =
-        Logger.getLogger(FixWQCurveGenerator.class);
+            Logger.getLogger(FixWQCurveGenerator.class);
 
     public static final String I18N_CHART_TITLE =
-        "chart.fixings.wq.title";
+            "chart.fixings.wq.title";
 
     public static final String I18N_CHART_SUBTITLE =
-        "chart.fixings.wq.subtitle";
+            "chart.fixings.wq.subtitle";
+
+    public static final String I18N_CHART_SUBTITLE1 =
+            "chart.fixings.wq.subtitle1";
 
     public static final String I18N_XAXIS_LABEL =
-        "chart.fixings.wq.xaxis.label";
+            "chart.fixings.wq.xaxis.label";
 
     public static final String I18N_YAXIS_LABEL =
-        "chart.fixings.wq.yaxis.label";
+            "chart.fixings.wq.yaxis.label";
 
     public static final String I18N_CHART_TITLE_DEFAULT  =
-        "Fixierungsanalyse";
+            "Fixierungsanalyse";
 
     public static final String I18N_XAXIS_LABEL_DEFAULT  =
-        "Q [m\u00B3/s]";
+            "Q [m\u00B3/s]";
 
     public static final String I18N_YAXIS_LABEL_DEFAULT  =
-        "W [NN + m]";
+            "W [NN + m]";
 
     public static enum YAXIS {
         W(0),
@@ -63,11 +91,17 @@
         }
     }
 
+
+    private FLYSArtifact artifact;
+
+
     @Override
     public void doOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
         String name = aaf.getFacetName();
         logger.debug("doOut: " + name);
 
+        this.artifact = (FLYSArtifact)aaf.getArtifact();
+
         if(name.startsWith(FIX_SECTOR_AVERAGE_WQ)) {
             doSectorAverageOut(aaf, doc, visible);
         }
@@ -83,6 +117,34 @@
         else if(FIX_OUTLIER.equals(name)) {
             doOutlierOut(aaf, doc, visible);
         }
+        else if(QSECTOR.equals(name)) {
+            doQSectorOut(aaf, doc, visible);
+        }
+        else if(STATIC_WKMS_INTERPOL.equals(name) ||
+                STATIC_WKMS.equals(name) ||
+                HEIGHTMARKS_POINTS.equals(name) ) {
+            doWAnnotations(
+                    aaf.getData(context),
+                    aaf,
+                    doc,
+                    visible);
+        }
+        else if (LONGITUDINAL_W.equals(name) || STATIC_WQ.equals(name)) {
+            doWQOut(aaf.getData(context), aaf, doc, visible);
+        }
+        else if (name.equals(DISCHARGE_CURVE)) {
+            doDischargeOut(
+                    (WINFOArtifact) aaf.getArtifact(),
+                    aaf.getData(context),
+                    aaf.getFacetDescription(),
+                    doc,
+                    visible);
+        }
+        else if (FacetTypes.IS.MANUALPOINTS(aaf.getFacetName())) {
+            doPoints(aaf.getData(context),
+                    aaf,
+                    doc, visible, YAXIS.W.idx);
+        }
         else {
             logger.warn("Unknown facet name " + name);
             return;
@@ -93,7 +155,9 @@
     protected void doSectorAverageOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
         logger.debug("doSectorAverageOut");
 
-        QWD qwd = (QWD)aaf.getData(context);
+        QWDDateRange qwdd = (QWDDateRange) aaf.getData(context);
+        QWD qwd = qwdd != null ? qwdd.getQWD() : null;
+
         if(qwd != null) {
             addQWSeries(new QWD[] { qwd }, aaf, doc, visible);
         }
@@ -106,9 +170,28 @@
     protected void doAnalysisEventsOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
         logger.debug("doAnalysisEventsOut");
 
-        QWD[] qwds = (QWD[])aaf.getData(context);
-        if(qwds != null) {
-            addQWSeries(qwds, aaf, doc, visible);
+        QWD qwd = (QWD)aaf.getData(context);
+        if(qwd != null) {
+            XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), doc);
+            List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
+
+            DateFormat dateFormat = DateFormat.getDateInstance(
+                    DateFormat.SHORT);
+
+            series.add(qwd.getQ(), qwd.getW());
+
+            XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
+                    dateFormat.format(qwd.getDate()),
+                    qwd.getQ(),
+                    qwd.getW());
+            textAnnos.add(anno);
+
+            addAxisSeries(series, 0, visible);
+            if(visible && ThemeUtil.parseShowPointLabel(doc)) {
+                FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, doc);
+                flysAnno.setTextAnnotations(textAnnos);
+                addAnnotations(flysAnno);
+            }
         }
         else {
             logger.debug("doAnalysisEventsOut: qwds == null");
@@ -117,10 +200,34 @@
 
     /** Add reference event points to chart */
     protected void doReferenceEventsOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
-       logger.debug("doReferenceEventsOut");
+        logger.debug("doReferenceEventsOut");
 
-       QW[] qws = (QW[])aaf.getData(context);
-       addQWSeries(qws, aaf, doc, visible);
+        QWI qwd = (QWI)aaf.getData(context);
+        if(qwd != null) {
+            XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), doc);
+            List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
+
+            DateFormat dateFormat = DateFormat.getDateInstance(
+                    DateFormat.SHORT);
+
+            series.add(qwd.getQ(), qwd.getW());
+
+            XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
+                    dateFormat.format(qwd.getDate()),
+                    qwd.getQ(),
+                    qwd.getW());
+            textAnnos.add(anno);
+
+            addAxisSeries(series, 0, visible);
+            if(visible && ThemeUtil.parseShowPointLabel(doc)) {
+                FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, doc);
+                flysAnno.setTextAnnotations(textAnnos);
+                addAnnotations(flysAnno);
+            }
+        }
+        else {
+            logger.debug("doAnalysisEventsOut: qwds == null");
+        }
     }
 
     protected void doWQCurveOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
@@ -128,7 +235,7 @@
 
         FixWQCurveFacet facet = (FixWQCurveFacet)aaf.getFacet();
         FixFunction func = (FixFunction)facet.getData(
-            aaf.getArtifact(), context);
+                aaf.getArtifact(), context);
 
         if (func == null) {
             logger.warn("doWQCurveOut: Facet does not contain FixFunction");
@@ -139,12 +246,12 @@
 
         if (maxQ > 0) {
             StyledXYSeries series = JFreeUtil.sampleFunction2D(
-                func.getFunction(),
-                doc,
-                aaf.getFacetDescription(),
-                500,   // number of samples
-                0.0 ,  // start
-                maxQ); // end
+                    func.getFunction(),
+                    doc,
+                    aaf.getFacetDescription(),
+                    500,   // number of samples
+                    0.0 ,  // start
+                    maxQ); // end
 
             addAxisSeries(series, 0, visible);
         }
@@ -156,43 +263,286 @@
     protected void doOutlierOut(ArtifactAndFacet aaf, Document doc, boolean visible) {
         logger.debug("doOutlierOut");
 
-        QW[] qws = (QW[])aaf.getData(context);
+        QWI[] qws = (QWI[])aaf.getData(context);
         addQWSeries(qws, aaf, doc, visible);
     }
 
-    protected void addQWSeries(QW[] qws, ArtifactAndFacet aaf, Document theme, boolean visible) {
-         if(qws != null) {
+
+    /** Add markers for q sectors. */
+    protected void doQSectorOut(ArtifactAndFacet aaf, Document theme, boolean visible) {
+        logger.debug("doQSectorOut");
+        if (!visible) {
+            return;
+        }
+
+        Object qsectorsObj = aaf.getData(context);
+        if (qsectorsObj == null || !(qsectorsObj instanceof List)) {
+            logger.warn("No QSectors coming from data.");
+            return;
+        }
+
+        List<?> qsectorsList = (List<?>) qsectorsObj;
+        if (qsectorsList.size() == 0 || !(qsectorsList.get(0) instanceof NamedDouble)) {
+            logger.warn("No QSectors coming from data.");
+            return;
+        }
+
+        @SuppressWarnings("unchecked")
+        List<NamedDouble> qsectors = (List<NamedDouble>) qsectorsList;
+
+        for (NamedDouble qsector : qsectors) {
+            if (Double.isNaN(qsector.getValue())) {
+                continue;
+            }
+            Marker m = new ValueMarker(qsector.getValue());
+            m.setPaint(Color.black);
+
+            float[] dashes = ThemeUtil.parseLineStyle(theme);
+            int size       = ThemeUtil.parseLineWidth(theme);
+            BasicStroke stroke;
+            if (dashes.length <= 1) {
+                stroke = new BasicStroke(size);
+            }
+            else {
+                stroke = new BasicStroke(size,
+                        BasicStroke.CAP_BUTT,
+                        BasicStroke.JOIN_ROUND,
+                        1.0f,
+                        dashes,
+                        0.0f);
+            }
+            m.setStroke(stroke);
+
+            if (ThemeUtil.parseShowLineLabel(theme)) {
+                m.setLabel(qsector.getName());
+                m.setPaint(ThemeUtil.parseTextColor(theme));
+                m.setLabelFont(ThemeUtil.parseTextFont(theme));
+            }
+            Color paint = ThemeUtil.parseLineColorField(theme);
+            if (paint != null) {
+                m.setPaint(paint);
+            }
+            m.setLabelAnchor(RectangleAnchor.TOP_LEFT);
+            m.setLabelTextAnchor(TextAnchor.TOP_LEFT);
+            m.setLabelOffset(new RectangleInsets(5, 5, 10, 10));
+            addDomainMarker(m);
+        }
+    }
+
+
+    /**
+     * Add W-Annotations to plot.
+     * @param wqkms actual data (double[][]).
+     * @param theme theme to use.
+     */
+    protected void doWAnnotations(
+            Object   wqkms,
+            ArtifactAndFacet aandf,
+            Document theme,
+            boolean  visible
+            ) {
+        Facet facet = aandf.getFacet();
+
+        List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
+        if (wqkms instanceof double[][]) {
+            logger.debug("Got double[][]");
+            double [][] data = (double [][]) wqkms;
+            for (int i = 0; i< data[0].length; i++) {
+                xy.add(new StickyAxisAnnotation(aandf.getFacetDescription(),
+                        (float) data[1][i], StickyAxisAnnotation.SimpleAxis.Y_AXIS));
+            }
+
+            doAnnotations(new FLYSAnnotation(facet.getDescription(), xy),
+                    aandf, theme, visible);
+        }
+        else {
+            // Assume its WKms.
+            logger.debug("Got WKms");
+            WKms data = (WKms) wqkms;
+
+            Double ckm = (Double) context.getContextValue(CURRENT_KM);
+            double location = (ckm != null)
+                    ? ckm.doubleValue()
+                            : getRange()[0];
+                    double w = StaticWKmsArtifact.getWAtKmLin(data, location);
+                    xy.add(new StickyAxisAnnotation(aandf.getFacetDescription(),
+                            (float) w, StickyAxisAnnotation.SimpleAxis.Y_AXIS));
+
+                    doAnnotations(new FLYSAnnotation(facet.getDescription(), xy),
+                            aandf, theme, visible);
+        }
+    }
+
+
+    /**
+     * Add series with discharge curve to diagram.
+     */
+    protected void doDischargeOut(
+            WINFOArtifact artifact,
+            Object        o,
+            String        description,
+            Document      theme,
+            boolean       visible)
+    {
+        WQKms wqkms = (WQKms) o;
+
+        String gaugeName = wqkms.getName();
+
+        River river = FLYSUtils.getRiver(artifact);
+
+        if (river == null) {
+            logger.debug("no river found");
+            return;
+        }
+
+        Gauge gauge = river.determineGaugeByName(gaugeName);
+
+        if (gauge == null) {
+            logger.debug("no gauge found");
+            return;
+        }
+
+        XYSeries series = new StyledXYSeries(description, theme);
+        StyledSeriesBuilder.addPointsQW(series, wqkms);
+        addAxisSeries(series, YAXIS.W.idx, visible);
+    }
+
+
+    /**
+     * Add WQ Data to plot.
+     * @param wqkms data as double[][]
+     */
+    protected void doWQOut(
+            Object           wqkms,
+            ArtifactAndFacet aaf,
+            Document         theme,
+            boolean          visible
+            ) {
+        logger.debug("FixWQCurveGenerator: doWQOut");
+        if (wqkms instanceof WQKms) {
+            WQKms data = (WQKms) wqkms;
+
             XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
-            List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
+            StyledSeriesBuilder.addPointsQW(series, data);
 
-            DateFormat dateFormat = DateFormat.getDateInstance(
+            addAxisSeries(series, YAXIS.W.idx, visible);
+        }
+        else {
+            double [][] data = (double [][]) wqkms;
+
+            XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
+            StyledSeriesBuilder.addPoints(series, data, true);
+
+            addAxisSeries(series, YAXIS.W.idx, visible);
+        }
+    }
+
+
+    protected void addQWSeries(
+            QWI []           qws,
+            ArtifactAndFacet aaf,
+            Document         theme,
+            boolean          visible
+            ) {
+        if (qws == null) {
+            return;
+        }
+
+        XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
+        List<XYTextAnnotation> textAnnos =
+                new ArrayList<XYTextAnnotation>(qws.length);
+
+        DateFormat dateFormat = DateFormat.getDateInstance(
                 DateFormat.SHORT);
 
-            for(QW qw : qws) {
-                series.add(qw.getQ(), qw.getW());
+        for (QWI qw: qws) {
+            series.add(qw.getQ(), qw.getW());
 
-                XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
+            XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
                     dateFormat.format(qw.getDate()),
                     qw.getQ(),
                     qw.getW());
-                textAnnos.add(anno);
-            }
+            textAnnos.add(anno);
+        }
 
-            addAxisSeries(series, 0, visible);
-            if(visible && ThemeUtil.parseShowPointLabel(theme)) {
-                FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
-                flysAnno.setTextAnnotations(textAnnos);
-                addAnnotations(flysAnno);
-            }
+        addAxisSeries(series, 0, visible);
+        if (visible && ThemeUtil.parseShowPointLabel(theme)) {
+            FLYSAnnotation flysAnno =
+                    new FLYSAnnotation(null, null, null, theme);
+            flysAnno.setTextAnnotations(textAnnos);
+            addAnnotations(flysAnno);
         }
     }
 
     @Override
+    protected String getChartTitle() {
+        return Resources.format(
+                context.getMeta(),
+                I18N_CHART_TITLE,
+                I18N_CHART_TITLE_DEFAULT,
+                context.getContextValue(CURRENT_KM));
+    }
+
+    @Override
     protected String getDefaultChartTitle() {
         return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
     }
 
     @Override
+    protected String getDefaultChartSubtitle() {
+        FixAnalysisAccess access = new FixAnalysisAccess(artifact);
+        DateRange dateRange = access.getDateRange();
+        DateRange refRange  = access.getReferencePeriod();
+
+        if (dateRange != null && refRange != null) {
+            return Resources.format(
+                    context.getMeta(),
+                    I18N_CHART_SUBTITLE,
+                    "",
+                    access.getRiver(),
+                    dateRange.getFrom(),
+                    dateRange.getTo(),
+                    refRange.getFrom(),
+                    refRange.getTo());
+        }
+
+        return null;
+    }
+
+    @Override
+    protected void addSubtitles(JFreeChart chart) {
+        String defaultSubtitle = getDefaultChartSubtitle();
+
+        if (defaultSubtitle == null || defaultSubtitle.length() == 0) {
+            return;
+        }
+
+        chart.addSubtitle(new TextTitle(defaultSubtitle));
+
+        StringBuilder buf = new StringBuilder();
+
+        // Add analysis periods as additional subtitle
+        FixAnalysisAccess access = new FixAnalysisAccess(artifact);
+        DateRange[] aperiods = access.getAnalysisPeriods();
+        buf.append(msg("fix.analysis.periods"));
+        buf.append(": ");
+        for(int n = 0; n < aperiods.length; n++) {
+            buf.append(
+                    Resources.format(
+                            context.getMeta(),
+                            I18N_CHART_SUBTITLE1,
+                            "",
+                            aperiods[n].getFrom(),
+                            aperiods[n].getTo()));
+            if(n + 1 < aperiods.length) {
+                buf.append("; ");
+            }
+        }
+
+        chart.addSubtitle(new TextTitle(buf.toString()));
+    }
+
+    @Override
     protected String getDefaultXAxisLabel() {
         return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
     }
@@ -211,7 +561,7 @@
             }
 
             @Override
-             public String getId(int idx) {
+            public String getId(int idx) {
                 YAXIS[] yaxes = YAXIS.values();
                 return yaxes[idx].toString();
             }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/ParametersExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/ParametersExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -7,7 +7,7 @@
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.Parameters;
 
-import de.intevation.flys.artifacts.model.fixings.FixResult;
+import de.intevation.flys.artifacts.model.fixings.FixAnalysisResult;
 
 import de.intevation.flys.artifacts.resources.Resources;
 
@@ -28,7 +28,7 @@
 public class ParametersExporter
 extends      AbstractExporter
 {
-    private static Logger log = Logger.getLogger(DeltaWtExporter.class);
+    private static Logger log = Logger.getLogger(ParametersExporter.class);
 
     protected List<Parameters> parametersList;
 
@@ -48,10 +48,12 @@
         }
 
         Object data = ((CalculationResult)d).getData();
-        if (!(data instanceof FixResult)) {
+        if (!(data instanceof FixAnalysisResult)) {
             log.warn("Invalid data stored in result.");
+            return;
         }
-        FixResult result = (FixResult)data;
+
+        FixAnalysisResult result = (FixAnalysisResult)data;
         parametersList.add(result.getParameters());
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffEpochInfoGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class BedDiffEpochInfoGenerator
+extends ChartInfoGenerator
+{
+   public BedDiffEpochInfoGenerator() {
+        super(new BedDifferenceEpochGenerator());
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,113 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class BedDiffHeightYearGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        D(0);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedDiffHeightYearGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.beddifference.height.title";
+    public static final String I18N_XAXIS_LABEL = "chart.beddifference.height.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.beddifference.height.yaxis.label";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlenhöhen Differenz";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "delta S [cm / Jahr]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(BED_DIFFERENCE_HEIGHT_YEAR)) {
+            doBedDifferenceYearOut(
+                (BedDiffYearResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+    }
+
+    protected void doBedDifferenceYearOut(BedDiffYearResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getHeightPerYearData(), true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearInfoGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class BedDiffHeightYearInfoGenerator
+extends ChartInfoGenerator
+{
+    public BedDiffHeightYearInfoGenerator() {
+        super (new BedDiffHeightYearGenerator());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffYearInfoGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class BedDiffYearInfoGenerator
+extends ChartInfoGenerator
+{
+    public BedDiffYearInfoGenerator() {
+        super(new BedDifferenceYearGenerator());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,151 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffEpochResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class BedDifferenceEpochGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        D(0), H(1);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedQualityGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.beddifference.epoch.title";
+    public static final String I18N_XAXIS_LABEL = "chart.beddifference.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.beddifference.yaxis.label.diff";
+    public static final String I18N_SECOND_YAXIS_LABEL = "chart.beddifference.yaxis.label.height";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlenhöhen Differenz";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "delta S [m]";
+    public static final String I18N_SECOND_YAXIS_LABEL_DEFAULT = "Höhe [m]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(BED_DIFFERENCE_EPOCH)) {
+            doBedDifferenceEpochOut(
+                (BedDiffEpochResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(BED_DIFFERENCE_EPOCH_HEIGHT1)) {
+            doBedDifferenceHeightsOut((BedDiffEpochResult)bundle.getData(context),
+                bundle, attr, visible, 0);
+        }
+        else if (name.equals(BED_DIFFERENCE_EPOCH_HEIGHT2)) {
+            doBedDifferenceHeightsOut((BedDiffEpochResult)bundle.getData(context),
+                bundle, attr, visible, 1);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        String label = "default";
+        if (pos == YAXIS.D.idx) {
+            label = msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.H.idx) {
+            label = msg(I18N_SECOND_YAXIS_LABEL, I18N_SECOND_YAXIS_LABEL_DEFAULT);
+        }
+
+        return label;
+    }
+
+    protected void doBedDifferenceEpochOut(BedDiffEpochResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDifferencesData(), true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+
+    private void doBedDifferenceHeightsOut(
+        BedDiffEpochResult data,
+        ArtifactAndFacet bundle,
+        Document attr,
+        boolean visible,
+        int idx) {
+         logger.debug("doBedDifferenceHeightOut()");
+
+        XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), attr);
+        if (idx == 0) {
+            StyledSeriesBuilder.addPoints(series, data.getHeights1Data(), true);
+        }
+        else {
+            StyledSeriesBuilder.addPoints(series, data.getHeights2Data(), true);
+        }
+
+        addAxisSeries(series, YAXIS.H.idx, visible);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,173 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class BedDifferenceYearGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        D(0), M(1), H(2);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedDifferenceYearGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.beddifference.year.title";
+    public static final String I18N_XAXIS_LABEL = "chart.beddifference.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.beddifference.yaxis.label.diff";
+    public static final String I18N_SECOND_YAXIS_LABEL = "chart.beddifference.yaxis.label.morph";
+    public static final String I18N_THIRD_YAXIS_LABEL = "chart.beddifference.yaxis.label.heights";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlenhöhen Differenz";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "delta S [m]";
+    public static final String I18N_SECOND_YAXIS_LABEL_DEFAULT = "Morph. Breite [m]";
+    public static final String I18N_THIRD_YAXIS_LABEL_DEFAULT = "Höhe [m]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(BED_DIFFERENCE_YEAR)) {
+            doBedDifferenceYearOut(
+                (BedDiffYearResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(BED_DIFFERENCE_MORPH_WIDTH)) {
+            doBedDifferenceMorphWidthOut(
+                (BedDiffYearResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(BED_DIFFERENCE_YEAR_HEIGHT1)) {
+            doBedDifferenceHeightsOut(
+                (BedDiffYearResult)bundle.getData(context),
+                bundle, attr, visible, 0);
+        }
+        else if (name.equals(BED_DIFFERENCE_YEAR_HEIGHT2)) {
+            doBedDifferenceHeightsOut(
+                (BedDiffYearResult)bundle.getData(context),
+                bundle, attr, visible, 1);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    private void doBedDifferenceHeightsOut(
+        BedDiffYearResult data,
+        ArtifactAndFacet bundle,
+        Document attr,
+        boolean visible,
+        int idx) {
+         logger.debug("doBedDifferenceYearOut()");
+
+        XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), attr);
+        if (idx == 0) {
+            StyledSeriesBuilder.addPoints(series, data.getHeights1Data(), true);
+        }
+        else {
+            StyledSeriesBuilder.addPoints(series, data.getHeights2Data(), true);
+        }
+
+        addAxisSeries(series, YAXIS.H.idx, visible);
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        String label = "default";
+        if (pos == YAXIS.D.idx) {
+            label = msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.M.idx) {
+            label = msg(I18N_SECOND_YAXIS_LABEL, I18N_SECOND_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.H.idx) {
+            label = msg(I18N_THIRD_YAXIS_LABEL, I18N_THIRD_YAXIS_LABEL_DEFAULT);
+        }
+
+        return label;
+    }
+
+    protected void doBedDifferenceYearOut(BedDiffYearResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("doBedDifferenceYearOut()");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDifferencesData(), true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+
+    protected void doBedDifferenceMorphWidthOut(BedDiffYearResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("doBedDifferencesMorphWidthOut()");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getMorphWidthData(), true);
+
+        addAxisSeries(series, YAXIS.M.idx, visible);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedQualityExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,216 @@
+package de.intevation.flys.exports.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+import au.com.bytecode.opencsv.CSVWriter;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.minfo.BedDiameterResult;
+import de.intevation.flys.artifacts.model.minfo.BedParametersResult;
+import de.intevation.flys.artifacts.model.minfo.BedQualityResult;
+import de.intevation.flys.artifacts.model.minfo.BedloadDiameterResult;
+import de.intevation.flys.exports.AbstractExporter;
+import de.intevation.flys.utils.Formatter;
+
+
+public class BedQualityExporter
+extends AbstractExporter
+{
+    /** Private logger. */
+    private static Logger logger = Logger.getLogger(BedQualityExporter.class);
+
+    private static final String CSV_HEADER_KM = "export.minfo.bedquality.km";
+    private static final String CSV_HEADER_DENSITY_CAP =
+        "export.minfo.bedquality.density_cap";
+    private static final String CSV_HEADER_DENSITY_SUB =
+        "export.minfo.bedquality.density_sub";
+    private static final String CSV_HEADER_POROSITY_CAP =
+        "export.minfo.bedquality.porosity_cap";
+    private static final String CSV_HEADER_POROSITY_SUB =
+        "export.minfo.bedquality.porosity_sub";
+    private static final String CSV_HEADER_BEDLOAD =
+        "export.minfo.bedquality.bedload";
+    private static final String CSV_HEADER_BED_CAP =
+        "export.minfo.bedquality.bed_cap";
+    private static final String CSV_HEADER_BED_SUB =
+        "export.minfo.bedquality.bed_sub";
+
+    private BedQualityResult[] results;
+
+    @Override
+    public void init(Document request, OutputStream out, CallContext context) {
+        logger.debug("BedQualityExporter.init");
+        super.init(request, out, context);
+        results = new BedQualityResult[0];
+    }
+
+    @Override
+    protected void writeCSVData(CSVWriter writer) throws IOException {
+        // TODO Auto-generated method stub
+        writeCSVHeader(writer);
+
+        NumberFormat kmf = Formatter.getCalculationKm(context.getMeta());
+
+        TDoubleArrayList kms = new TDoubleArrayList();
+        int cols = 1;
+        for (int i = 0; i < results.length; i++) {
+            BedDiameterResult[] beds = results[i].getBedResults();
+            for (int j = 0; j < beds.length; j++) {
+                TDoubleArrayList bkms = beds[j].getKms();
+                for (int k = 0; k < bkms.size(); k++) {
+                    if (!kms.contains(bkms.get(k))) {
+                        kms.add(bkms.get(k));
+                    }
+                }
+            }
+            BedloadDiameterResult[] loads = results[i].getBedloadResults();
+            for (int j = 0; j < loads.length; j++) {
+                TDoubleArrayList lkms = loads[i].getKms();
+                for (int k = 0; k < lkms.size(); k++) {
+                    if (!kms.contains(lkms.get(k))) {
+                        kms.add(lkms.get(k));
+                    }
+                }
+            }
+            cols += beds.length * 2;
+            cols += loads.length;
+            if (beds.length > 0) {
+                cols += 4;
+            }
+        }
+
+        kms.sort();
+        List<double[]> rows = new LinkedList<double[]>();
+        for (int i = 0; i < kms.size(); i++) {
+            double[] row = new double[cols];
+            double km = kms.get(i);
+            row[0] = km;
+            for (int j = 0; j < results.length; j++) {
+                BedloadDiameterResult[] loads = results[j].getBedloadResults();
+
+                for(int k = 0; k < loads.length; k++) {
+                    // k + 1: shift km column.
+                    // j* loads.length: shift periods.
+                    row[(k + 1) + (j * loads.length)] =
+                        loads[k].getDiameter(km);
+                }
+                BedDiameterResult[] beds = results[j].getBedResults();
+                for (int k = 0; k < beds.length; k++) {
+                    // k + 1: shift km column.
+                    // j * beds.length: shift periods.
+                    // loads.length * results.length: shift bed load columns.
+                    int ndx = (k + 1) + (j * beds.length) + (loads.length * results.length);
+                    row[ndx] = beds[k].getDiameterCap(km);
+                    row[ndx + 1] = beds[k].getDiameterSub(km);
+                }
+                BedParametersResult[] params = results[j].getParameters();
+                for(int k = 0; k < params.length; k++) {
+                    // loads.length + (beds.lenght * 2) * (j + 1): shift bed and bedload columns.
+                    int ndx = 1 + (loads.length + (beds.length * 2) * (j + 1));
+                    row[ndx] = params[k].getLoadDensityCap(km);
+                    row[ndx + 1] = params[k].getLoadDensitySub(km);
+                    row[ndx + 2] = params[k].getPorosityCap(km);
+                    row[ndx + 3] = params[k].getPorositySub(km);
+                }
+            }
+            rows.add(row);
+        }
+        for (double[] d : rows) {
+            logger.debug(Arrays.toString(d));
+            List<String> cells = new LinkedList<String>();
+            for (int i = 0; i < d.length; i++) {
+                if (!Double.isNaN(d[i])) {
+                    NumberFormat nf = Formatter.getFormatter(context, 1, 3);
+                    cells.add(nf.format(d[i]));
+                }
+                else {
+                    cells.add("");
+                }
+            }
+            writer.writeNext(cells.toArray(new String[cells.size()]));
+        }
+    }
+
+    @Override
+    protected void writePDF(OutputStream out) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    protected void addData(Object data) {
+        // TODO Auto-generated method stub
+        logger.debug("addData()");
+        if (!(data instanceof CalculationResult)) {
+            logger.warn("Invalid data type.");
+            return;
+        }
+        Object[] d = (Object[])((CalculationResult)data).getData();
+
+        if (!(d instanceof BedQualityResult[])) {
+            logger.warn("Invalid result object.");
+            return;
+        }
+        results = (BedQualityResult[])d;
+    }
+
+    protected void writeCSVHeader(CSVWriter writer) {
+        logger.debug("writeCSVHeader()");
+
+        List<String> header = new LinkedList<String>();
+        if (results != null)  {
+            header.add(msg(CSV_HEADER_KM, "km"));
+            for (int i = 0; i < results.length; i++) {
+                DateFormat df = Formatter.getDateFormatter(context.getMeta(), "dd.MM.yyyy");
+                String d1 = df.format(results[i].getDateRange().getFrom());
+                String d2 = df.format(results[i].getDateRange().getTo());
+                BedloadDiameterResult[] loads = results[i].getBedloadResults();
+                BedDiameterResult[] beds = results[i].getBedResults();
+                BedParametersResult[] params = results[i].getParameters();
+                for (int j = 0; j < loads.length; j++) {
+                    header.add(msg(CSV_HEADER_BEDLOAD, CSV_HEADER_BEDLOAD) +
+                        " - " +
+                        msg(loads[j].getType().toString(),
+                            loads[j].getType().toString()) + " - " +
+                        d1 + "-" + d2);
+                }
+                for (int j = 0; j < beds.length; j++) {
+                    header.add(msg(CSV_HEADER_BED_CAP, CSV_HEADER_BED_CAP) + " - " +
+                        msg(beds[j].getType().toString(),
+                            beds[j].getType().toString()) + " - " +
+                        d1 + "-" + d2);
+                    header.add(msg(CSV_HEADER_BED_SUB, CSV_HEADER_BED_SUB) + " - " +
+                        msg(beds[j].getType().toString(),
+                            beds[j].getType().toString()) + " - " +
+                        d1 + "-" + d2);
+                }
+                if (params.length > 0) {
+                    header.add(
+                        msg(CSV_HEADER_DENSITY_CAP, CSV_HEADER_DENSITY_CAP) +
+                        " - " + d1 + "-" + d2);
+                    header.add(
+                        msg(CSV_HEADER_DENSITY_SUB, CSV_HEADER_DENSITY_SUB) +
+                        " - " + d1 + "-" + d2);
+                    header.add(
+                        msg(CSV_HEADER_POROSITY_CAP, CSV_HEADER_POROSITY_CAP) +
+                        " - " + d1 + "-" + d2);
+                    header.add(
+                        msg(CSV_HEADER_POROSITY_SUB, CSV_HEADER_POROSITY_SUB) +
+                        " - " + d1 + "-" + d2);
+                }
+            }
+        }
+        writer.writeNext(header.toArray(new String[header.size()]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedQualityGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,273 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiameterResult;
+import de.intevation.flys.artifacts.model.minfo.BedParametersResult;
+import de.intevation.flys.artifacts.model.minfo.BedloadDiameterResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+/**
+ * An OutGenerator that generates bed quality charts.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class BedQualityGenerator extends XYChartGenerator implements FacetTypes {
+
+    public enum YAXIS {
+        W(0), P(1), D(2);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedQualityGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.bedquality.title";
+    public static final String I18N_XAXIS_LABEL = "chart.bedquality.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.bedquality.yaxis.label";
+    public static final String I18N_SECOND_YAXIS_LABEL = "chart.bedquality.yaxis.label.porosity";
+    public static final String I18N_THIRD_YAXIS_LABEL = "chart.bedquality.yaxis.label.diameter";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlen Längsschnitt";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "Durchmesser [m]";
+    public static final String I18N_SECOND_YAXIS_LABEL_DEFAULT = "Porosität [%]";
+    public static final String I18N_THIRD_YAXIS_LABEL_DEFAULT = "Dichte [t/m^3]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    /**
+     * Returns the default title for this chart.
+     *
+     * @return the default title for this chart.
+     */
+    @Override
+    public String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    /**
+     * Get internationalized label for the x axis.
+     */
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int index) {
+        String label = "default";
+
+        if (index == YAXIS.W.idx) {
+            label = getWAxisLabel();
+        }
+        else if (index == YAXIS.P.idx) {
+            label = getPAxisLabel();
+        }
+        else if (index == YAXIS.D.idx) {
+            label = getDAxisLabel();
+        }
+
+        return label;
+    }
+
+    /**
+     * Get internationalized label for the y axis displaying the diameter.
+     */
+    protected String getWAxisLabel() {
+        return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+    }
+
+    /**
+     * Get internationalized label for the y axis displaying the porosity.
+     */
+    protected String getPAxisLabel() {
+        return msg(I18N_SECOND_YAXIS_LABEL, I18N_SECOND_YAXIS_LABEL_DEFAULT);
+    }
+
+    /**
+     * Get internationalized label for the y axis displaying the density.
+     */
+    protected String getDAxisLabel() {
+        return msg(I18N_THIRD_YAXIS_LABEL, I18N_THIRD_YAXIS_LABEL_DEFAULT);
+    }
+
+    /**
+     * Produce output.
+     *
+     * @param artifactAndFacet
+     *            current facet.
+     * @param attr
+     *            theme for facet
+     */
+    public void doOut(ArtifactAndFacet artifactAndFacet, Document attr,
+        boolean visible) {
+        String name = artifactAndFacet.getFacetName();
+
+        logger.debug("BedQualityGenerator.doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = artifactAndFacet.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        // TODO BED_QUALITY_BED_DIAMETER_TOPLAYER
+        if (name.equals(BED_QUALITY_BED_DIAMETER_TOPLAYER)) {
+            doBedDiameterTopLayerOut(
+                (BedDiameterResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        else if (name.equals(BED_QUALITY_BED_DIAMETER_SUBLAYER)) {
+            doBedDiameterSubLayerOut(
+                (BedDiameterResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        // TODO BED_QUALITY_BED_DIAMETER_SUBLAYER
+        else if (name.equals(BED_QUALITY_BEDLOAD_DIAMETER)) {
+            doBedLoadDiameterOut(
+                (BedloadDiameterResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        else if (name.equals(BED_QUALITY_POROSITY_TOPLAYER)) {
+            doPorosityTopLayerOut(
+                (BedParametersResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        else if (name.equals(BED_QUALITY_POROSITY_SUBLAYER)) {
+            doPorositySubLayerOut(
+                (BedParametersResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        else if (name.equals(BED_QUALITY_SEDIMENT_DENSITY_TOPLAYER)) {
+            doDensityTopLayerOut(
+                (BedParametersResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        else if (name.equals(BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER)) {
+            doDensitySubLayerOut(
+                (BedParametersResult) artifactAndFacet.getData(context),
+                artifactAndFacet, attr, visible);
+        }
+        else if (FacetTypes.IS.MANUALPOINTS(name)) {
+            doPoints(artifactAndFacet.getData(context), artifactAndFacet, attr,
+                visible, YAXIS.W.idx);
+        }
+        else {
+            logger.warn("Unknown facet name: " + name);
+            return;
+        }
+    }
+
+    protected void doBedDiameterTopLayerOut(BedDiameterResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doBedDiameterTopLayerOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDiameterCapData(), true);
+
+        addAxisSeries(series, YAXIS.W.idx, visible);
+    }
+
+    protected void doBedDiameterSubLayerOut(BedDiameterResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doBedDiameterSubLayerOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDiameterSubData(), true);
+
+        addAxisSeries(series, YAXIS.W.idx, visible);
+    }
+
+    protected void doBedLoadDiameterOut(BedloadDiameterResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doBedLoadDiameterOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDiameterData(), true);
+
+        addAxisSeries(series, YAXIS.W.idx, visible);
+    }
+
+    protected void doPorosityTopLayerOut(BedParametersResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doPorosityTopLayerOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+
+        StyledSeriesBuilder.addPoints(series, data.getPorosityCapData(),
+            true);
+
+        addAxisSeries(series, YAXIS.P.idx, visible);
+    }
+
+    protected void doPorositySubLayerOut(BedParametersResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doPorositySubLayerOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+
+        StyledSeriesBuilder.addPoints(series, data.getPorositySubData(),
+            true);
+
+        addAxisSeries(series, YAXIS.P.idx, visible);
+    }
+
+    protected void doDensityTopLayerOut(BedParametersResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doDensityOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+
+        StyledSeriesBuilder.addPoints(series, data.getDensityCapData(),
+            true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+
+    protected void doDensitySubLayerOut(BedParametersResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("BedQuality.doDensityOut");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+
+        StyledSeriesBuilder.addPoints(series, data.getDensitySubData(),
+            true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+}
+// 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-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedQualityInfoGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,18 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+/**
+ * A ChartInfoGenerator that generates meta information for specific computed
+ * bed quality curves.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class BedQualityInfoGenerator extends ChartInfoGenerator {
+
+    public BedQualityInfoGenerator() {
+        super(new BedQualityGenerator());
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/sq/SQOverviewGenerator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/sq/SQOverviewGenerator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -26,8 +26,7 @@
 import de.intevation.artifacts.common.ArtifactNamespaceContext;
 import de.intevation.artifacts.common.utils.XMLUtils;
 import de.intevation.flys.artifacts.context.FLYSContext;
-import de.intevation.flys.collections.AttributeParser;
-import de.intevation.flys.collections.CollectionAttribute;
+import de.intevation.flys.collections.FLYSArtifactCollection;
 import de.intevation.flys.exports.ChartGenerator;
 import de.intevation.flys.exports.OutGenerator;
 import de.intevation.flys.exports.OutputHelper;
@@ -40,6 +39,8 @@
     public static final String XPATH_CHART_SIZE =
         "/art:action/art:attributes/art:size";
 
+    protected FLYSArtifactCollection collection;
+
     protected Artifact master;
 
     protected Settings settings;
@@ -57,6 +58,7 @@
      * @param artifactAndFacet current facet and artifact.
      * @param attr  theme for facet
      */
+    @Override
     public void doOut(
         ArtifactAndFacet artifactAndFacet,
         Document         attr,
@@ -64,7 +66,6 @@
     ) {
         logger.debug("doOut()");
 
-        logger.debug(XMLUtils.toString(attr));
         String name = artifactAndFacet.getData(context).toString();
         if(name != null) {
             logger.debug("name: " + name);
@@ -73,30 +74,34 @@
                     context,
                     name,
                     null);
+
             if (g == null) {
                 logger.debug("generator is null.");
                 return;
             }
-            logger.debug(XMLUtils.toString(attr));
+
             OutputHelper helper = new OutputHelper(master.identifier());
+            Document collectionAttribute = collection.getAttribute();
+
             try {
-                AttributeParser parser    = new AttributeParser(request);
-                CollectionAttribute cAttr = parser.getCollectionAttribute();
-
+                Document cAttr = getAttribute(context, collectionAttribute, name);
                 g.init(request, out, context);
-                Document chartAttr = getAttribute(context, cAttr, name);
-                logger.debug(XMLUtils.toString(chartAttr));
-                helper.doOut(g, name, name, request, context);
-                charts.add(g.generateChart());
-            } catch (IOException e) {
+
+                helper.doOut(g, name, name, cAttr, context);
+                JFreeChart chart = g.generateChart();
+                chart.removeLegend();
+                charts.add(chart);
+            }
+            catch (IOException e) {
                 logger.warn(e);
-            } catch (ArtifactDatabaseException e) {
-                // TODO Auto-generated catch block
+            }
+            catch (ArtifactDatabaseException e) {
                 logger.warn(e);
             }
         }
     }
 
+    @Override
     public void init(Document request, OutputStream out, CallContext context) {
         this.request = request;
         this.out = out;
@@ -104,10 +109,17 @@
         charts = new ArrayList<JFreeChart>();
     }
 
+    @Override
     public void setMasterArtifact(Artifact master) {
         this.master = master;
     }
 
+    @Override
+    public void setCollection(FLYSArtifactCollection collection) {
+        this.collection = collection;
+    }
+
+    @Override
     public void generate() throws IOException {
         logger.debug("SQOverviewGenerator.generate");
 
@@ -137,10 +149,12 @@
         ImageIO.write(result, "png", out);
     }
 
+    @Override
     public void setSettings(Settings settings) {
         this.settings = settings;
     }
 
+    @Override
     public Settings getSettings() {
         return this.settings;
     }
@@ -151,18 +165,18 @@
      * output type.
      *
      * @param context The CallContext object.
-     * @param cAttr The CollectionAttribute.
+     * @param attr The xml attribute saved at the collection.
      * @param output The name of the desired output type.
      *
      * @return the attribute for the desired output type.
      */
     protected Document getAttribute(
-        CallContext         context,
-        CollectionAttribute cAttr,
-        String              output)
+        CallContext context,
+        Document    attr,
+        String      output)
     throws    ArtifactDatabaseException
     {
-        Document attr = cAttr.toXML();
+        logger.debug("find specific XML node for Output: " + output);
 
         Map<String, String> vars = new HashMap<String, String>();
         vars.put("output", output);
@@ -174,10 +188,8 @@
             ArtifactNamespaceContext.INSTANCE,
             vars);
 
-
         if (out != null) {
             Document o = XMLUtils.newDocument();
-
             o.appendChild(o.importNode(out, true));
 
             return o;
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/sq/SQRelationExporter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/sq/SQRelationExporter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -6,15 +6,19 @@
 
 import org.w3c.dom.Document;
 
-import org.apache.log4j.Logger;
-
 import au.com.bytecode.opencsv.CSVWriter;
 
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.flys.artifacts.model.CalculationResult;
+
+import de.intevation.flys.artifacts.model.sq.SQFractionResult;
+import de.intevation.flys.artifacts.model.sq.SQResult;
+import de.intevation.flys.artifacts.model.Parameters;
+
 import de.intevation.flys.exports.AbstractExporter;
 
+import org.apache.log4j.Logger;
 
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
@@ -69,67 +73,83 @@
         "export.sqrelation.csv.header.variance";
 
 
-    // TODO use correct model class here!
-    protected List<Object[]> data;
+    protected List<SQResult []> data;
 
 
     public void init(Document request, OutputStream out, CallContext cc) {
         super.init(request, out, cc);
-        data = new ArrayList<Object[]>();
+        data = new ArrayList<SQResult []>();
     }
 
 
     @Override
     protected void addData(Object d) {
         if (d instanceof CalculationResult) {
-            d = ((CalculationResult) d).getData();
-
-            if (d instanceof Object[]) {
-                logger.debug("Add new data of type XXX");
-                data.add((Object[]) d);
+            d = ((CalculationResult)d).getData();
+            if (d instanceof SQResult []) {
+                data.add((SQResult [])d);
             }
         }
     }
 
+    protected void writeCSVHeader(CSVWriter writer) {
+        writer.writeNext(new String[] {
+            msg(CSV_KM        , CSV_KM),
+            msg(CSV_PARAMETER,  CSV_PARAMETER),
+            msg(CSV_COEFF_A   , CSV_COEFF_A),
+            msg(CSV_COEFF_B   , CSV_COEFF_B),
+            msg(CSV_N_TOTAL   , CSV_N_TOTAL),
+            msg(CSV_N_OUTLIERS, CSV_N_OUTLIERS),
+            msg(CSV_VARIANCE  , CSV_VARIANCE)
+        });
+    }
 
     @Override
     protected void writeCSVData(CSVWriter writer) {
         logger.debug("writeCSVData");
-        logger.error("NOT IMPLEMENTED: writeCSVData");
-
-        logger.debug("CSV gets " + data.size() + " rows.");
 
         writeCSVHeader(writer);
 
-        for (Object[] d: data) {
-            data2CSV(writer, d);
+        for (SQResult [] results: data) {
+            for (SQResult result: results) {
+                data2CSV(writer, result);
+            }
         }
     }
 
+    protected void data2CSV(CSVWriter writer, SQResult result) {
+        logger.debug("data2CSV");
 
-    protected void writeCSVHeader(CSVWriter writer) {
-        writer.writeNext(new String[] {
-            msg(CSV_PARAMETER, CSV_PARAMETER),
-            msg(CSV_STATION, CSV_STATION),
-            msg(CSV_KM        , CSV_KM),
-            msg(CSV_FUNCTION  , CSV_FUNCTION),
-            msg(CSV_GAUGE     , CSV_GAUGE),
-            msg(CSV_COEFF_A   , CSV_COEFF_A),
-            msg(CSV_COEFF_B   , CSV_COEFF_B),
-            msg(CSV_COEFF_Q   , CSV_COEFF_Q),
-            msg(CSV_COEFF_R   , CSV_COEFF_R),
-            msg(CSV_N_TOTAL   , CSV_N_TOTAL),
-            msg(CSV_N_OUTLIERS, CSV_N_OUTLIERS),
-            msg(CSV_C_DUAN    , CSV_C_DUAN),
-            msg(CSV_C_FERGUSON, CSV_C_FERGUSON),
-            msg(CSV_VARIANCE  , CSV_VARIANCE)
-        });
-    }
+        // TODO: i18n
+        String km = String.valueOf(result.getKm());
 
+        for (int i = 0; i < SQResult.NUMBER_FRACTIONS; ++i) {
+            SQFractionResult fraction = result.getFraction(i);
 
-    protected void data2CSV(CSVWriter writer, Object[] mData) {
-        logger.debug("data2CSV");
-        logger.error("NOT IMPLEMENTED: data2CSV");
+            String name = result.getFractionName(i);
+
+            Parameters parameters = fraction.getParameters();
+
+            if (parameters == null) {
+                continue;
+            }
+
+            double a  = parameters.getValue(0, "a");
+            double b  = parameters.getValue(0, "b");
+            double sd = Math.sqrt(parameters.getValue(0, "std_dev"));
+            int    o  = fraction.totalNumOutliers();
+            int    t  = fraction.numMeasurements() + o;
+
+            writer.writeNext(new String[] {
+                km,
+                name,
+                String.valueOf(a),
+                String.valueOf(b),
+                String.valueOf(t),
+                String.valueOf(o),
+                String.valueOf(sd)
+            });
+        }
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/Bounds.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/Bounds.java	Fri Sep 28 12:15:40 2012 +0200
@@ -6,6 +6,7 @@
 
 
 /**
+ * Somewhat better Ranges.
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public interface Bounds extends Serializable {
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/DoubleBounds.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/DoubleBounds.java	Fri Sep 28 12:15:40 2012 +0200
@@ -42,6 +42,11 @@
     }
 
 
+    /**
+     * Set extended range to ValueAxis.
+     * @param percent how many percent to extend (in each direction,
+     *        thus 10 percent on [0,100] -> [-10,110].
+     */
     @Override
     public void applyBounds(ValueAxis axis, int percent) {
         double space = (upper - lower) / 100 * percent;
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,8 +1,8 @@
 package de.intevation.flys.jfree;
 
 import java.awt.Color;
+import java.awt.Font;
 import java.awt.Graphics2D;
-import java.awt.Font;
 import java.awt.Paint;
 import java.awt.Shape;
 import java.awt.geom.Rectangle2D;
@@ -10,7 +10,6 @@
 import java.util.Map;
 
 import org.apache.log4j.Logger;
-
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.entity.EntityCollection;
 import org.jfree.chart.plot.CrosshairState;
@@ -20,11 +19,11 @@
 import org.jfree.data.xy.XYDataset;
 import org.jfree.data.xy.XYSeries;
 import org.jfree.data.xy.XYSeriesCollection;
+import org.jfree.text.TextUtilities;
 import org.jfree.ui.RectangleEdge;
 import org.jfree.ui.TextAnchor;
 import org.jfree.util.BooleanList;
 import org.jfree.util.ShapeUtilities;
-import org.jfree.text.TextUtilities;
 
 /**
  * Renderer with additional the additional functionality of renderering minima
@@ -32,6 +31,11 @@
  */
 public class EnhancedLineAndShapeRenderer extends XYLineAndShapeRenderer {
 
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
     /** Own logger. */
     private static final Logger logger =
         Logger.getLogger(EnhancedLineAndShapeRenderer.class);
@@ -123,6 +127,7 @@
     }
 
 
+    /** Get fill paint for the maximum indicators. */
     public Paint getMaximumFillPaint(int series, int column) {
         Paint p = getItemPaint(series, column);
 
@@ -142,6 +147,7 @@
     }
 
 
+    /** Get fill paint for the minimum indicators. */
     public Paint getMinimumFillPaint(int series, int column) {
         Paint p = getItemPaint(series, column);
 
@@ -274,14 +280,17 @@
             yy = transX1;
         }
 
-        // draw the item label if there is one...
+        // Draw the item label if there is one...
         if (isItemLabelVisible(series, item)) {
             drawItemLabel(g2, orientation, dataset, series, item, xx, yy,
                     (y1 < 0.0));
         }
 
         // Draw label of line.
-        if (dataset instanceof XYSeriesCollection && isShowLineLabel(series) && isMinimumX (dataset, series, item)) {
+        if (dataset instanceof XYSeriesCollection
+            && isShowLineLabel(series)
+            && isMinimumX (dataset, series, item)
+            ) {
             XYSeries xYSeries = ((XYSeriesCollection) dataset).getSeries(series);
             String waterlevelLabel = (xYSeries instanceof HasLabel)
                 ? ((HasLabel)xYSeries).getLabel()
@@ -295,11 +304,22 @@
             g2.setColor(this.getLineLabelTextColor(series));
             g2.setBackground(Color.black);
 
+            // Try to always display label if the data is visible.
+            if (!isPointInRect(dataArea, xx, yy)) {
+                // Move into the data area.
+                xx = Math.max(xx, dataArea.getMinX());
+                xx = Math.min(xx, dataArea.getMaxX());
+                yy = Math.max(yy, dataArea.getMinY());
+                yy = Math.min(yy, dataArea.getMaxY());
+            }
+
             // Move to right until no collisions exist anymore
             Shape hotspot = TextUtilities.calculateRotatedStringBounds(
-                waterlevelLabel, g2, (float)xx, (float)yy-3f, TextAnchor.CENTER_LEFT,
+                waterlevelLabel, g2, (float)xx, (float)yy-3f,
+                TextAnchor.CENTER_LEFT,
                 0f, TextAnchor.CENTER_LEFT);
-            while (JFreeUtil.collides(hotspot, entities, CollisionFreeLineLabelEntity.class)) {
+            while (JFreeUtil.collides(hotspot, entities,
+                                      CollisionFreeLineLabelEntity.class)) {
                 xx += 5f;
                 hotspot = TextUtilities.calculateRotatedStringBounds(
                     waterlevelLabel, g2, (float)xx, (float)yy-3f, TextAnchor.CENTER_LEFT,
@@ -327,7 +347,7 @@
         updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex,
                 rangeAxisIndex, transX1, transY1, orientation);
 
-        // add an entity for the item, but only if it falls within the data
+        // Add an entity for the item, but only if it falls within the data
         // area...
         if (entities != null && isPointInRect(dataArea, xx, yy)) {
             addEntity(entities, entityArea, dataset, series, item, xx, yy);
@@ -343,6 +363,9 @@
     }
 
 
+    /**
+     * Whether or not the minimum should be rendered with shape.
+     */
     public boolean isMinimumShapeVisible(int series) {
         if (this.isMinimumShapeVisible.size() <= series) {
             return false;
@@ -352,11 +375,17 @@
     }
 
 
+    /**
+     * Sets whether or not the maximum should be rendered with shape.
+     */
     public void setIsMaximumShapeVisible(int series, boolean isVisible) {
         this.isMaximumShapeVisible.setBoolean(series, isVisible);
     }
 
 
+    /**
+     * Whether or not the maximum should be rendered with shape.
+     */
     public boolean isMaximumShapeVisible(int series) {
         if (this.isMaximumShapeVisible.size() <= series) {
             return false;
@@ -380,6 +409,7 @@
         this.showLineLabel.setBoolean(series, showLineLabel);
     }
 
+
     /** Whether or not a label should be shown for series. */
     public boolean isShowLineLabelBG(int series) {
         if (this.showLineLabelBG.size() <= series) {
@@ -389,6 +419,7 @@
         return showLineLabelBG.getBoolean(series);
     }
 
+
     public void setShowLineLabelBG(int series, boolean doShow) {
         this.showLineLabelBG.setBoolean(series, doShow);
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/JFreeUtil.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/JFreeUtil.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,19 +1,20 @@
 package de.intevation.flys.jfree;
 
+import java.awt.Shape;
+import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
+import java.util.Random;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.entity.ChartEntity;
+import org.jfree.chart.entity.EntityCollection;
+import org.w3c.dom.Document;
+
 import de.intevation.flys.artifacts.math.Function;
 
-import java.awt.Shape;
-
-import java.awt.geom.Rectangle2D;
-
-import java.util.Iterator;
+public class JFreeUtil {
 
-import org.jfree.chart.entity.ChartEntity;
-import org.jfree.chart.entity.EntityCollection;
-
-import org.w3c.dom.Document;
-
-public class JFreeUtil {
+    private static final Logger logger = Logger.getLogger(JFreeUtil.class);
 
     /** Do not instantiate. */
     private JFreeUtil() {
@@ -52,6 +53,50 @@
     }
 
 
+    /**
+     * This function samples a randomized line that contains of x and y values
+     * between <i>startX</i>, <i>endX</i>, <i>startY</i> and <i>endY</i>. The
+     * number of points in the line is specified by <i>num</i>.
+     *
+     * @param num The number of points in the line.
+     * @param startX The min value of the x values.
+     * @param endX The max value of the x values.
+     * @param startY The min value of the y values.
+     * @param endY The max value of the y values.
+     * @return an array with [allX-values, allY-values].
+     * @throws IllegalArgumentException
+     */
+    public static double[][] randomizeLine(
+        int    num,
+        double startX,
+        double endX,
+        double startY,
+        double endY
+    ) throws IllegalArgumentException
+    {
+        if (num <= 0) {
+            throw new IllegalArgumentException("Parameter 'num' has to be > 0");
+        }
+
+        Random random = new Random();
+
+        double[] x = new double[num];
+        double[] y = new double[num];
+
+        for (int i = 0; i < num; i++) {
+            double xFac = random.nextDouble();
+            double yFac = random.nextDouble();
+
+            x[i] = startX + xFac * (endX - startX);
+            y[i] = startY + yFac * (endY - startY);
+
+            logger.debug("Created new point: " + x[i] + "|" + y[i]);
+        }
+
+        return new double[][] { x, y };
+    }
+
+
     public static StyledXYSeries sampleFunction2D(
         Function func,
         Document theme,
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java	Fri Sep 28 12:15:40 2012 +0200
@@ -123,6 +123,8 @@
 
 import de.intevation.flys.artifacts.math.Linear;
 
+import java.text.NumberFormat;
+
 import org.apache.log4j.Logger;
 
 /**
@@ -179,6 +181,12 @@
     /** Font to draw label of calculated area with. */
     protected Font labelFont;
 
+    /** Template to create i18ned label for area. */
+    protected String areaLabelTamplate;
+
+    /** NumberFormat to use for area. */
+    protected NumberFormat areaLabelNumberFormat;
+
     protected int areaCalculationMode;
 
     protected double positiveArea;
@@ -260,6 +268,18 @@
         this.areaCalculationMode = areaCalculationMode;
     }
 
+
+    /** Set template to use to create area label (e.g. 'Area=%dm2'). */
+    public void setAreaLabelTemplate(String areaTemplate) {
+        this.areaLabelTamplate = areaTemplate;
+    }
+
+
+    public void setAreaLabelNumberFormat(NumberFormat nf) {
+        this.areaLabelNumberFormat = nf;
+    }
+
+
     public boolean isLabelArea() {
         return this.labelArea;
     }
@@ -502,7 +522,7 @@
      * The renderer can do nothing if it chooses.
      *
      * @param g2  the graphics device.
-     * @param dataArea  the area inside the axes.
+     * @param dataArea  the (visible) area inside the axes.
      * @param plot  the plot.
      * @param data  the data.
      * @param info  an optional info collection object to return data back to
@@ -532,6 +552,10 @@
         return 2;
     }
 
+
+    /**
+     * Adds x/y data to series.
+     */
     private static final void addSeries(
         DefaultXYDataset ds,
         Comparable       key,
@@ -822,7 +846,7 @@
 
         switch (dataset.getSeriesCount()) {
             case 0:
-                return Collections.emptyList();
+                return Collections.<XYDataset>emptyList();
             case 1:
                 return splitByNaNsOneSeries(dataset);
             default: // two or more
@@ -830,6 +854,7 @@
         }
     }
 
+
     /**
      * Draws the visual representation of a single data item.
      *
@@ -875,8 +900,7 @@
         }
 
         // Find geometric middle, calculate area and paint a string with it here.
-        // TODO also i18n
-        if (pass == 1 && this.labelArea) {
+        if (pass == 1 && this.labelArea && areaLabelNumberFormat != null && areaLabelTamplate != null) {
             double center_x = centroid.getX();
             double center_y = centroid.getY();
             center_x = domainAxis.valueToJava2D(center_x, dataArea,
@@ -899,7 +923,8 @@
                 Color oldColor = g2.getColor();
                 Font oldFont = g2.getFont();
                 g2.setFont(labelFont);
-                String labelText = "Area= " + area + "m2";
+                String labelText = String.format(this.areaLabelTamplate,
+                    areaLabelNumberFormat.format(area));
                 if (labelBGColor != null) {
                     EnhancedLineAndShapeRenderer.drawTextBox(g2, labelText,
                         (float)center_x, (float)center_y, labelBGColor);
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,7 +4,6 @@
 import java.awt.Color;
 import java.awt.Stroke;
 
-import org.apache.log4j.Logger;
 import org.jfree.data.xy.XYSeriesCollection;
 import org.w3c.dom.Document;
 
@@ -20,6 +19,8 @@
  * dataset.
  */
 public class StyledAreaSeriesCollection extends XYSeriesCollection {
+    private static final long serialVersionUID = 5274940965666948237L;
+
     /** Mode, how to draw/which areas to fill. */
     public enum FILL_MODE {UNDER, ABOVE, BETWEEN};
 
@@ -29,10 +30,6 @@
     /** The theme-document with attributes about actual visual representation. */
     protected Document theme;
 
-    /** Own logger. */
-    private static final Logger logger =
-        Logger.getLogger(StyledAreaSeriesCollection.class);
-
 
     /**
      * @param theme the theme-document.
@@ -58,6 +55,8 @@
     /**
      * Applies line color, size and type attributes to renderer, also
      * whether to draw lines and/or points.
+     * @param renderer Renderer to apply theme to.
+     * @return \param renderer
      */
     public StableXYDifferenceRenderer applyTheme(
         StableXYDifferenceRenderer renderer
@@ -83,17 +82,19 @@
     }
 
 
-    /**
-     * Blindly (for now) apply the postiviepaint of renderer.
-     */
     protected void applyFillColor(StableXYDifferenceRenderer renderer) {
-        // Get color.
-        Color paint = ThemeUtil.parseFillColorField(theme);
-        // Get half-transparency flag.
-        if (ThemeUtil.parseTransparency(theme)) {
-            paint = new Color(paint.getRed(), paint.getGreen(), paint.getBlue(),
-                128);
+        Color paint = ThemeUtil.parseColor(
+                ThemeUtil.getBackgroundColorString(theme));
+
+        int transparency = ThemeUtil.parseTransparency(theme);
+        if (transparency > 0) {
+            paint = new Color(
+                        paint.getRed(),
+                        paint.getGreen(),
+                        paint.getBlue(),
+                        (int)((100 - transparency) * 2.55f));
         }
+
         if (paint != null && this.getMode() == FILL_MODE.ABOVE) {
             renderer.setPositivePaint(paint);
             renderer.setNegativePaint(new Color(0,0,0,0));
@@ -103,28 +104,26 @@
             renderer.setPositivePaint(new Color(0,0,0,0));
         }
         else {
-            if (paint == null) paint = new Color(177, 117, 102);
+            if (paint == null)
+                paint = new Color(177, 117, 102);
             renderer.setPositivePaint(paint);
             renderer.setNegativePaint(paint);
         }
     }
 
-    /**
-     * Blindly (for now) apply the postiviepaint of renderer.
-     */
+
     protected void applyShowShape(StableXYDifferenceRenderer renderer) {
         boolean show = ThemeUtil.parseShowBorder(theme);
         renderer.setDrawOutline(show);
     }
 
+
     protected void applyShowLine(StableXYDifferenceRenderer renderer) {
         boolean show = ThemeUtil.parseShowLine(theme);
         renderer.setShapesVisible(show);
     }
 
-    /**
-     *
-     */
+
     protected void applyOutlineColor(StableXYDifferenceRenderer renderer) {
         Color c = ThemeUtil.parseLineColorField(theme);
         renderer.setOutlinePaint(c);
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledDomainMarker.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledDomainMarker.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,19 +1,20 @@
 package de.intevation.flys.jfree;
 
-import de.intevation.flys.utils.ThemeUtil;
-
 import java.awt.Color;
 
 import org.jfree.chart.plot.IntervalMarker;
 import org.w3c.dom.Document;
 
+import de.intevation.flys.utils.ThemeUtil;
+
 /**
  * Marker that represents a highlighted interval.
+ *
  * @author <a href="mailto:christian.lins@intevation.de">Christian Lins</a>
  */
 public class StyledDomainMarker extends IntervalMarker {
 
-    private static final long serialVersionUID = -4369410661339512342L;
+    private static final long serialVersionUID = -4369417661339512342L;
 
     private final Color fillColor, backgroundColor;
 
@@ -26,8 +27,9 @@
                 ThemeUtil.getFillColorString(theme));
         useSecondColor(false);
 
-        int alpha = ThemeUtil.parseInteger(ThemeUtil.getTransparencyAlpha(theme), 128);
-        setAlpha(alpha / 255.0f);
+        int alpha = 100 - ThemeUtil.parseInteger(
+                ThemeUtil.getTransparencyString(theme), 50);
+        setAlpha(alpha / 100.0f);
     }
 
     /**
@@ -37,10 +39,12 @@
      */
     public void useSecondColor(boolean secondColor) {
         if(secondColor) {
-            setPaint(backgroundColor);
+            if(backgroundColor != null)
+                setPaint(backgroundColor);
         }
         else {
-            setPaint(fillColor);
+            if(fillColor != null)
+                setPaint(fillColor);
         }
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/XYStyle.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/XYStyle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,17 +1,15 @@
 package de.intevation.flys.jfree;
 
+import de.intevation.flys.utils.ThemeUtil;
+
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.geom.Ellipse2D;
 
 import org.apache.log4j.Logger;
-
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.w3c.dom.Document;
 
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
-
-import de.intevation.flys.utils.ThemeUtil;
-
 
 /**
  * Utility to apply theme-settings to a renderer.
@@ -36,6 +34,7 @@
      * Applies line color, size and type attributes to renderer, also
      * whether to draw lines and/or points.
      */
+    @Override
     public XYLineAndShapeRenderer applyTheme(XYLineAndShapeRenderer r, int idx){
         this.renderer = r;
         applyLineColor(r, idx);
@@ -47,12 +46,22 @@
         applyPointColor(r, idx);
         applyShowMinimum(r, idx);
         applyShowMaximum(r, idx);
+
+        // Line label styles
         applyShowLineLabel(r, idx);
+        applyShowLineLabelBG(r, idx);
         applyLineLabelFont(r, idx);
         applyLineLabelColor(r, idx);
-        applyShowLineLabelBG(r, idx);
         applyLineLabelBGColor(r, idx);
 
+        // Point label styles
+        // TODO: Currently point label are annotations and are not drawn this way
+        /*
+        applyShowPointLabelBG(r, idx);
+        applyLinePointFont(r, idx);
+        applyLinePointColor(r, idx);
+        applyLinePointBGColor(r, idx);*/
+
         return r;
     }
 
@@ -88,7 +97,7 @@
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
-        boolean showLabelLine = ThemeUtil.parseShowLineLabelBG(theme);
+        boolean showLabelLine = ThemeUtil.parseLabelShowBackground(theme);
         ((EnhancedLineAndShapeRenderer)r).setShowLineLabelBG(idx, showLabelLine);
     }
 
@@ -98,7 +107,8 @@
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
-        ((EnhancedLineAndShapeRenderer)r).setLineLabelFont(ThemeUtil.parseLineLabelFont(theme), idx);
+        ((EnhancedLineAndShapeRenderer)r).setLineLabelFont(
+                ThemeUtil.parseTextFont(theme), idx);
     }
 
     /** Tell the renderer which color to use for
@@ -107,7 +117,8 @@
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
-        ((EnhancedLineAndShapeRenderer)r).setLineLabelTextColor(idx, ThemeUtil.parseLineLabelTextColor(theme));
+        ((EnhancedLineAndShapeRenderer)r).setLineLabelTextColor(
+                idx, ThemeUtil.parseTextColor(theme));
     }
 
     /** Tell the renderer which color to use for bg of
@@ -117,7 +128,7 @@
             return;
         }
         ((EnhancedLineAndShapeRenderer)r).setLineLabelBGColor(idx,
-            ThemeUtil.parseLineLabelBGColor(theme));
+            ThemeUtil.parseTextBackground(theme));
     }
 
     /** Set stroke of series. */
@@ -125,7 +136,7 @@
         int size = ThemeUtil.parseLineWidth(theme);
         r.setSeriesStroke(
             idx,
-            new BasicStroke(Integer.valueOf(size)));
+            new BasicStroke(size));
     }
 
 
@@ -141,7 +152,7 @@
 
         r.setSeriesStroke(
             idx,
-            new BasicStroke(Integer.valueOf(size),
+            new BasicStroke(size,
                             BasicStroke.CAP_BUTT,
                             BasicStroke.JOIN_ROUND,
                             1.0f,
@@ -210,6 +221,7 @@
     }
 
 
+    @Override
     public XYLineAndShapeRenderer getRenderer() {
         return this.renderer;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/themes/DefaultTheme.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/DefaultTheme.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,6 @@
 package de.intevation.flys.themes;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 import org.w3c.dom.Document;
@@ -154,17 +153,14 @@
      * @param theme The document root element.
      */
     protected void appendAttributes(ElementCreator cr, Element theme) {
-        Iterator<String> iter = attr.keySet().iterator();
 
-        while (iter.hasNext()) {
-            String key = iter.next();
-            String val = getAttribute(key);
+        for (Map.Entry<String, String> entry: attr.entrySet()) {
+            String key = entry.getKey();
+            String val = entry.getValue();
 
-            if (key == null || val == null) {
-                continue;
+            if (key != null && val != null) {
+                cr.addAttr(theme, key, val);
             }
-
-            cr.addAttr(theme, key, val);
         }
     }
 
@@ -176,12 +172,10 @@
      * @param theme The document root element.
      */
     protected void appendFields(ElementCreator cr, Element theme) {
-        Iterator<String> iter = fields.keySet().iterator();
 
-        while (iter.hasNext()) {
-            String name = iter.next();
-
-            ThemeField field = getField(name);
+        for (Map.Entry<String, ThemeField> entry: fields.entrySet()) {
+            String     name  = entry.getKey();
+            ThemeField field = entry.getValue();
 
             Document doc = field.toXML();
             Node    root = doc.getFirstChild();
--- a/flys-artifacts/src/main/java/de/intevation/flys/themes/DefaultThemeField.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/DefaultThemeField.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,6 @@
 package de.intevation.flys.themes;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 import org.w3c.dom.Document;
@@ -68,13 +67,8 @@
 
         Element field = cr.create("field");
 
-        Iterator<String> iter = attr.keySet().iterator();
-
-        while (iter.hasNext()) {
-            String name  = iter.next();
-            String value = (String) getAttribute(name);
-
-            cr.addAttr(field, name, value);
+        for (Map.Entry<String, Object> entry: attr.entrySet()) {
+            cr.addAttr(field, entry.getKey(), (String)entry.getValue());
         }
 
         doc.appendChild(field);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/LineStyle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,21 @@
+package de.intevation.flys.themes;
+
+import java.awt.Color;
+
+public class LineStyle {
+    protected Color lineColor;
+    protected int   lineWidth;
+
+    public LineStyle(Color color, int width) {
+        this.lineColor = color;
+        this.lineWidth = width;
+    }
+
+    public int getWidth() {
+        return lineWidth;
+    }
+
+    public Color getColor() {
+        return lineColor;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/PointStyle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,5 @@
+package de.intevation.flys.themes;
+
+public class PointStyle {
+    // TODO tbd
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/TextStyle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,52 @@
+package de.intevation.flys.themes;
+
+import de.intevation.flys.jfree.StableXYDifferenceRenderer;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.annotations.XYTextAnnotation;
+
+public class TextStyle {
+    @SuppressWarnings("unused")
+    private static Logger log = Logger.getLogger(TextStyle.class);
+
+    protected Color   textColor;
+    protected Font    font;
+    protected Color   bgColor;
+    protected boolean showBg;
+    protected boolean isVertical;
+
+    public TextStyle(Color fgColor, Font font, Color bgColor,
+        boolean showBg, boolean isVertical
+    ) {
+        this.textColor  = fgColor;
+        this.font       = font;
+        this.bgColor    = bgColor;
+        this.showBg     = showBg;
+        this.isVertical = isVertical;
+    }
+
+    public void apply(XYTextAnnotation ta) {
+        ta.setPaint(textColor);
+        ta.setFont(font);
+        if (this.showBg) {
+            ta.setBackgroundPaint(bgColor);
+        }
+        if (this.isVertical) {
+            ta.setRotationAngle(270f*Math.PI/180f);
+        }
+        else {
+            ta.setRotationAngle(0);
+        }
+    }
+
+    public void apply(StableXYDifferenceRenderer renderer) {
+        renderer.setLabelColor(textColor);
+        renderer.setLabelFont(font);
+        if (this.showBg) {
+            renderer.setLabelBGColor(bgColor);
+        }
+    }
+}
\ No newline at end of file
--- a/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeAccess.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeAccess.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,16 +1,13 @@
 package de.intevation.flys.themes;
 
-import de.intevation.flys.jfree.StableXYDifferenceRenderer;
 import de.intevation.flys.utils.ThemeUtil;
 
 import java.awt.Color;
 import java.awt.Font;
 
-import org.jfree.chart.annotations.XYTextAnnotation;
 import org.w3c.dom.Document;
 
 
-/** Undocumented. */
 public class ThemeAccess
 {
     protected Document theme;
@@ -90,9 +87,9 @@
         return textBackground;
     }
 
-    public boolean parseShowTextBackground() {
+    public boolean parseLabelShowBackground() {
         if (showTextBackground == null) {
-            showTextBackground = ThemeUtil.parseShowTextBackground(theme);
+            showTextBackground = ThemeUtil.parseLabelShowBackground(theme);
         }
         return showTextBackground;
     }
@@ -115,77 +112,13 @@
         return new LineStyle(parseLineColorField(), Integer.valueOf(parseLineWidth()));
     }
 
-    public static class PointStyle {
-        // TODO tbd
-    }
-
-    public static class LineStyle {
-        protected Color lineColor;
-        protected int   lineWidth;
-
-        public LineStyle(Color color, int width) {
-            this.lineColor = color;
-            this.lineWidth = width;
-        }
-
-        public int getWidth() {
-            return lineWidth;
-        }
-
-        public Color getColor() {
-            return lineColor;
-        }
-    }
-
-
     public TextStyle parseTextStyle() {
         return new TextStyle(
             parseTextColor(),
             parseTextFont(),
             parseTextBackground(),
-            parseShowTextBackground(),
+            parseLabelShowBackground(),
             !parseTextOrientation().equals("horizontal"));
     }
-
-
-    public static class TextStyle {
-        protected Color   textColor;
-        protected Font    font;
-        protected Color   bgColor;
-        protected boolean showBg;
-        protected boolean isVertical;
-
-        public TextStyle(Color fgColor, Font font, Color bgColor,
-            boolean showBg, boolean isVertical
-        ) {
-            this.textColor  = fgColor;
-            this.font       = font;
-            this.bgColor    = bgColor;
-            this.showBg     = showBg;
-            this.isVertical = isVertical;
-        }
-
-        public void apply(XYTextAnnotation ta) {
-            ta.setPaint(textColor);
-            ta.setFont(font);
-            if (this.showBg) {
-                ta.setBackgroundPaint(bgColor);
-            }
-            if (this.isVertical) {
-                ta.setRotationAngle(270f*Math.PI/180f);
-            }
-            else {
-                ta.setRotationAngle(0);
-            }
-        }
-
-        public void apply(StableXYDifferenceRenderer renderer) {
-            renderer.setLabelColor(textColor);
-            renderer.setLabelFont(font);
-            if (this.showBg) {
-                renderer.setLabelBGColor(bgColor);
-            }
-        }
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,24 +1,22 @@
 package de.intevation.flys.themes;
 
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.context.FLYSContext;
+
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.ArrayList;
-import java.util.HashMap;
 
 import javax.xml.xpath.XPathConstants;
 
 import org.apache.log4j.Logger;
-
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.Element;
-
-import de.intevation.artifacts.common.utils.XMLUtils;
-
-import de.intevation.flys.artifacts.context.FLYSContext;
-import de.intevation.flys.artifacts.FLYSArtifact;
 
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
@@ -76,7 +74,10 @@
         String output,
         String groupName)
     {
-        logger.debug("Search theme for: " + name + " - pattern: " + pattern);
+        if (logger.isDebugEnabled()) {
+            logger.debug(
+                "Search theme for: " + name + " - pattern: " + pattern);
+        }
 
         if (c == null || name == null) {
             logger.warn("Cannot search for theme.");
@@ -84,20 +85,24 @@
         }
 
         // Fetch mapping and themes.
+        @SuppressWarnings("unchecked")
         Map<String, List<ThemeMapping>> map = (Map<String, List<ThemeMapping>>)
             c.get(FLYSContext.THEME_MAPPING);
 
+        @SuppressWarnings("unchecked")
         List<ThemeGroup> tgs = (List<ThemeGroup>)
             c.get(FLYSContext.THEMES);
 
         ThemeGroup group = null;
         for (ThemeGroup tg: tgs) {
-            if(tg.getName().equals(groupName)) {
+            if (tg.getName().equals(groupName)) {
                 group = tg;
+                break;
             }
         }
 
         if (group == null) {
+            logger.warn("No theme group found: '" + groupName + "'");
             return null;
         }
 
@@ -105,7 +110,7 @@
 
         FLYSArtifact artifact = (FLYSArtifact) c.get(FLYSContext.ARTIFACT_KEY);
 
-        if (map == null || map.size() == 0 || t == null || t.size() == 0) {
+        if (map == null || map.isEmpty() || t == null || t.isEmpty()) {
             logger.warn("No mappings or themes found. Cannot retrieve theme!");
             return null;
         }
@@ -124,7 +129,10 @@
                 && tm.masterAttrMatches(artifact)
                 && tm.outputMatches(output))
             {
-                return t.get(tm.getTo());
+                String target = tm.getTo();
+
+                logger.debug("Found theme '" + target + "'");
+                return t.get(target);
             }
         }
 
@@ -138,6 +146,7 @@
     }
 
 
+    @SuppressWarnings("unchecked")
     public static List<ThemeGroup> getThemeGroups(FLYSContext c) {
         List<ThemeGroup> tgs = (List<ThemeGroup>)
             c.get(FLYSContext.THEMES);
@@ -145,6 +154,7 @@
     }
 
 
+    @SuppressWarnings("unchecked")
     public static List<Theme> getThemes (FLYSContext c, String name) {
         List<ThemeGroup> tgs = (List<ThemeGroup>)
             c.get(FLYSContext.THEMES);
--- a/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeMapping.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeMapping.java	Fri Sep 28 12:15:40 2012 +0200
@@ -84,11 +84,20 @@
      * @return true if pattern matches text or pattern is empty.
      */
     public boolean applyPattern(String text) {
-        if (patternStr == null || patternStr.equals("")) {
+        if (patternStr == null || patternStr.length() == 0) {
             return true;
         }
         Matcher m = pattern.matcher(text);
-        return m.matches();
+
+       if (m.matches()) {
+           logger.debug("Pattern matches: " + text);
+           return true;
+       }
+       else {
+           logger.debug(
+               "Pattern '"+ text + "' does not match: " + this.patternStr);
+           return false;
+       }
     }
 
 
@@ -103,7 +112,7 @@
      * @return true if no condition is specified or condition is met.
      */
     public boolean masterAttrMatches(FLYSArtifact artifact) {
-        if (masterAttr == null || masterAttr.equals("")) {
+        if (masterAttr == null || masterAttr.length() == 0) {
            return true;
         }
 
@@ -116,7 +125,14 @@
         }
 
         // Test.
-        return artifact.getDataAsString(parts[0]).equals(parts[1]);
+        if (artifact.getDataAsString(parts[0]).equals(parts[1])) {
+            logger.debug("Matches master Attribute.");
+            return true;
+        }
+        else {
+            logger.debug("Does not match master Attribute.");
+            return false;
+        }
     }
 
 
@@ -125,11 +141,18 @@
      * in parameter output.
      */
     public boolean outputMatches(String output) {
-        if (this.output == null || this.output.equals("")) {
+        if (this.output == null || this.output.length() == 0) {
             return true;
         }
 
-        return this.output.equals(output);
+        if (this.output.equals(output)) {
+            logger.debug("Output matches this mapping: " + output);
+            return true;
+        }
+        else {
+            logger.debug("Output '"+ output +"' does not match: "+ this.output);
+            return false;
+        }
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/DoubleUtil.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/DoubleUtil.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,12 +1,17 @@
 package de.intevation.flys.utils;
 
+import de.intevation.flys.artifacts.math.Linear;
+
+import gnu.trove.TDoubleArrayList;
+
 import java.util.Arrays;
 
-import de.intevation.flys.artifacts.math.Linear;
-
+import org.apache.log4j.Logger;
 
 public class DoubleUtil
 {
+    private static Logger log = Logger.getLogger(DoubleUtil.class);
+
     public static final double DEFAULT_STEP_PRECISION = 1e6;
 
     private DoubleUtil() {
@@ -138,5 +143,50 @@
         Arrays.fill(result, value);
         return result;
     }
+
+    public interface SegmentCallback {
+        void newSegment(double from, double to, double [] values);
+    }
+
+    public static final void parseSegments(
+        String          input,
+        SegmentCallback callback
+    ) {
+        TDoubleArrayList vs = new TDoubleArrayList();
+
+        for (String segmentStr: input.split(":")) {
+            String [] parts = segmentStr.split(";");
+            if (parts.length < 3) {
+                log.warn("invalid segment: '" + segmentStr + "'");
+                continue;
+            }
+            try {
+                double from = Double.parseDouble(parts[0].trim());
+                double to   = Double.parseDouble(parts[1].trim());
+
+                vs.resetQuick();
+
+                for (String valueStr: parts[2].split(",")) {
+                    vs.add(round(Double.parseDouble(valueStr.trim())));
+                }
+
+                callback.newSegment(from, to, vs.toNativeArray());
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("invalid segment: '" + segmentStr + "'");
+            }
+        }
+    }
+
+    public static final boolean isValid(double [][] data) {
+        for (double [] ds: data) {
+            for (double d: ds) {
+                if (Double.isNaN(d)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/FLYSUtils.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/FLYSUtils.java	Fri Sep 28 12:15:40 2012 +0200
@@ -179,7 +179,7 @@
         }
 
         String values = flys.getDataAsString("wq_values");
-        Boolean isQ    = flys.getDataAsBoolean("wq_isq");
+        Boolean isQ   = flys.getDataAsBoolean("wq_isq");
 
         if (values != null) {
             return isQ ? WQ_MODE.QGAUGE : WQ_MODE.WGAUGE;
@@ -296,6 +296,14 @@
         String strFrom = flys.getDataAsString("ld_from");
         String strTo   = flys.getDataAsString("ld_to");
 
+        if (strFrom == null) {
+            strFrom = flys.getDataAsString("from");
+        }
+
+        if (strTo == null) {
+            strTo = flys.getDataAsString("to");
+        }
+
         if (strFrom == null || strTo == null) {
             return null;
         }
@@ -819,7 +827,7 @@
 
         for (String value: splitted) {
             try {
-                integers.add(Integer.valueOf(value));
+                integers.add(Integer.parseInt(value));
             }
             catch (NumberFormatException nfe) {
                 logger.warn("Parsing integer failed: " + nfe);
@@ -891,5 +899,32 @@
 
         return doubles.toNativeArray();
     }
+
+
+    /**
+     * Returns the gauges that match the selected kilometer range.
+     *
+     * @param flys the flys artifact.
+     *
+     * @return the gauges based on the selected kilometer range (null if
+     *         none/no range set).
+     */
+    public static List<Gauge> getGauges(FLYSArtifact flys) {
+
+        River river = getRiver(flys);
+        if (river == null) {
+            logger.debug("getGauges: no river!");
+            return null;
+        }
+
+        double [] dist = getKmRange(flys);
+        if (dist == null) {
+            logger.debug("getGauges: no dist!");
+            return null;
+        }
+        logger.debug("getGauges: " + dist[0] + " - " + dist[1]);
+
+        return river.determineGauges(dist[0], dist[1]);
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/Formatter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/Formatter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,11 +2,11 @@
 
 import java.text.DateFormat;
 import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
 import java.util.Locale;
 
 import de.intevation.artifacts.CallContext;
 import de.intevation.artifacts.CallMeta;
-
 import de.intevation.flys.artifacts.resources.Resources;
 
 
@@ -75,9 +75,11 @@
     public static final int FIX_DELTA_W_KM_MAX_DIGITS = 3;
     public static final int FIX_DELTA_W_DELTA_W_MIN_DIGITS = 3;
     public static final int FIX_DELTA_W_DELTA_W_MAX_DIGITS = 3;
+    public static final int FIX_DELTA_W_DELTA_Q_MIN_DIGITS  = 0;
+    public static final int FIX_DELTA_W_DELTA_Q_MAX_DIGITS  = 2;
 
     /**
-     * Creates a localised NumberFormatter with given range of decimal digits.
+     * Creates a localized NumberFormatter with given range of decimal digits.
      * @param m CallMeta to find the locale.
      * @param min minimum number of decimal ("fraction") digits.
      * @param max maximum number of decimal ("fraction") digits.
@@ -137,16 +139,16 @@
      */
     public static NumberFormat getWaterlevelKM(CallContext context) {
         return getFormatter(
-            context,
-            WATERLEVEL_KM_MIN_DIGITS,
-            WATERLEVEL_KM_MAX_DIGITS);
+                context,
+                WATERLEVEL_KM_MIN_DIGITS,
+                WATERLEVEL_KM_MAX_DIGITS);
     }
 
     public static NumberFormat getWaterlevelW(CallMeta meta) {
         return getFormatter(
-            meta,
-            WATERLEVEL_W_MIN_DIGITS,
-            WATERLEVEL_W_MAX_DIGITS);
+                meta,
+                WATERLEVEL_W_MIN_DIGITS,
+                WATERLEVEL_W_MAX_DIGITS);
     }
 
     /**
@@ -156,9 +158,9 @@
      */
     public static NumberFormat getWaterlevelW(CallContext context) {
         return getFormatter(
-            context,
-            WATERLEVEL_W_MIN_DIGITS,
-            WATERLEVEL_W_MAX_DIGITS);
+                context,
+                WATERLEVEL_W_MIN_DIGITS,
+                WATERLEVEL_W_MAX_DIGITS);
     }
 
 
@@ -169,16 +171,16 @@
      */
     public static NumberFormat getWaterlevelQ(CallContext context) {
         return getFormatter(
-            context,
-            WATERLEVEL_Q_MIN_DIGITS,
-            WATERLEVEL_Q_MAX_DIGITS);
+                context,
+                WATERLEVEL_Q_MIN_DIGITS,
+                WATERLEVEL_Q_MAX_DIGITS);
     }
 
     public static NumberFormat getWaterlevelQ(CallMeta meta) {
         return getFormatter(
-            meta,
-            WATERLEVEL_Q_MIN_DIGITS,
-            WATERLEVEL_Q_MAX_DIGITS);
+                meta,
+                WATERLEVEL_Q_MIN_DIGITS,
+                WATERLEVEL_Q_MAX_DIGITS);
     }
 
     /**
@@ -189,9 +191,9 @@
      */
     public static NumberFormat getComputedDischargeW(CallContext context) {
         return getFormatter(
-            context,
-            COMPUTED_DISCHARGE_W_MIN_DIGITS,
-            COMPUTED_DISCHARGE_W_MAX_DIGITS);
+                context,
+                COMPUTED_DISCHARGE_W_MIN_DIGITS,
+                COMPUTED_DISCHARGE_W_MAX_DIGITS);
     }
 
 
@@ -203,9 +205,9 @@
      */
     public static NumberFormat getComputedDischargeQ(CallContext context) {
         return getFormatter(
-            context,
-            COMPUTED_DISCHARGE_Q_MIN_DIGITS,
-            COMPUTED_DISCHARGE_Q_MAX_DIGITS);
+                context,
+                COMPUTED_DISCHARGE_Q_MIN_DIGITS,
+                COMPUTED_DISCHARGE_Q_MAX_DIGITS);
     }
 
 
@@ -217,9 +219,9 @@
      */
     public static NumberFormat getHistoricalDischargeW(CallContext context) {
         return getFormatter(
-            context,
-            HISTORICAL_DISCHARGE_W_MIN_DIGITS,
-            HISTORICAL_DISCHARGE_W_MAX_DIGITS);
+                context,
+                HISTORICAL_DISCHARGE_W_MIN_DIGITS,
+                HISTORICAL_DISCHARGE_W_MAX_DIGITS);
     }
 
 
@@ -231,9 +233,9 @@
      */
     public static NumberFormat getHistoricalDischargeQ(CallContext context) {
         return getFormatter(
-            context,
-            HISTORICAL_DISCHARGE_Q_MIN_DIGITS,
-            HISTORICAL_DISCHARGE_Q_MAX_DIGITS);
+                context,
+                HISTORICAL_DISCHARGE_Q_MIN_DIGITS,
+                HISTORICAL_DISCHARGE_Q_MAX_DIGITS);
     }
 
 
@@ -244,9 +246,9 @@
      */
     public static NumberFormat getDurationW(CallContext context) {
         return getFormatter(
-            context,
-            DURATION_W_MIN_DIGITS,
-            DURATION_W_MAX_DIGITS);
+                context,
+                DURATION_W_MIN_DIGITS,
+                DURATION_W_MAX_DIGITS);
     }
 
 
@@ -257,9 +259,9 @@
      */
     public static NumberFormat getDurationQ(CallContext context) {
         return getFormatter(
-            context,
-            DURATION_Q_MIN_DIGITS,
-            DURATION_Q_MAX_DIGITS);
+                context,
+                DURATION_Q_MIN_DIGITS,
+                DURATION_Q_MAX_DIGITS);
     }
 
 
@@ -270,110 +272,129 @@
      */
     public static NumberFormat getDurationD(CallContext context) {
         return getFormatter(
-            context,
-            DURATION_D_MIN_DIGITS,
-            DURATION_D_MAX_DIGITS);
+                context,
+                DURATION_D_MIN_DIGITS,
+                DURATION_D_MAX_DIGITS);
     }
 
     public static NumberFormat getCalculationKm(CallMeta meta) {
         return getFormatter(
-            meta,
-            CALCULATION_REPORT_KM_MIN_DIGITS,
-            CALCULATION_REPORT_KM_MAX_DIGITS);
+                meta,
+                CALCULATION_REPORT_KM_MIN_DIGITS,
+                CALCULATION_REPORT_KM_MAX_DIGITS);
     }
 
 
     public static NumberFormat getFlowVelocityKM(CallContext context) {
         return getFormatter(
-            context,
-            FLOW_VELOCITY_KM_MIN_DIGITS,
-            FLOW_VELOCITY_KM_MAX_DIGITS);
+                context,
+                FLOW_VELOCITY_KM_MIN_DIGITS,
+                FLOW_VELOCITY_KM_MAX_DIGITS);
     }
 
 
     public static NumberFormat getFlowVelocityValues(CallContext context) {
         return getFormatter(
-            context,
-            FLOW_VELOCITY_VALUES_MIN_DIGITS,
-            FLOW_VELOCITY_VALUES_MAX_DIGITS);
+                context,
+                FLOW_VELOCITY_VALUES_MIN_DIGITS,
+                FLOW_VELOCITY_VALUES_MAX_DIGITS);
     }
 
 
     public static NumberFormat getFlowVelocityQ(CallContext context) {
         return getFormatter(
-            context,
-            FLOW_VELOCITY_Q_MIN_DIGITS,
-            FLOW_VELOCITY_Q_MAX_DIGITS);
+                context,
+                FLOW_VELOCITY_Q_MIN_DIGITS,
+                FLOW_VELOCITY_Q_MAX_DIGITS);
     }
 
 
     public static NumberFormat getMiddleBedHeightKM(CallContext context) {
         return getFormatter(
-            context,
-            MIDDLE_BED_HEIGHT_KM_MIN_DIGITS,
-            MIDDLE_BED_HEIGHT_KM_MAX_DIGITS);
+                context,
+                MIDDLE_BED_HEIGHT_KM_MIN_DIGITS,
+                MIDDLE_BED_HEIGHT_KM_MAX_DIGITS);
     }
 
 
     public static NumberFormat getMiddleBedHeightHeight(CallContext context) {
         return getFormatter(
-            context,
-            MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS,
-            MIDDLE_BED_HEIGHT_HEIGHT_MAX_DIGITS);
+                context,
+                MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS,
+                MIDDLE_BED_HEIGHT_HEIGHT_MAX_DIGITS);
     }
 
 
     public static NumberFormat getMiddleBedHeightUncert(CallContext context) {
         return getFormatter(
-            context,
-            MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS,
-            MIDDLE_BED_HEIGHT_UNCERT_MAX_DIGITS);
+                context,
+                MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS,
+                MIDDLE_BED_HEIGHT_UNCERT_MAX_DIGITS);
     }
 
 
     public static NumberFormat getMiddleBedHeightDataGap(CallContext context) {
         return getFormatter(
-            context,
-            MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS,
-            MIDDLE_BED_HEIGHT_DATAGAP_MAX_DIGITS);
+                context,
+                MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS,
+                MIDDLE_BED_HEIGHT_DATAGAP_MAX_DIGITS);
     }
 
 
     public static NumberFormat getMiddleBedHeightSounding(CallContext context) {
         return getFormatter(
-            context,
-            MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MIN_DIGITS,
-            MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MAX_DIGITS);
+                context,
+                MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MIN_DIGITS,
+                MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MAX_DIGITS);
     }
 
 
     public static NumberFormat getMiddleBedHeightWidth(CallContext context) {
         return getFormatter(
-            context,
-            MIDDLE_BED_HEIGHT_WIDTH_MIN_DIGITS,
-            MIDDLE_BED_HEIGHT_WIDTH_MAX_DIGITS);
+                context,
+                MIDDLE_BED_HEIGHT_WIDTH_MIN_DIGITS,
+                MIDDLE_BED_HEIGHT_WIDTH_MAX_DIGITS);
     }
 
     public static NumberFormat getFixDeltaWKM(CallContext context) {
         return getFormatter(
-            context,
-            FIX_DELTA_W_KM_MIN_DIGITS,
-            FIX_DELTA_W_KM_MAX_DIGITS);
+                context,
+                FIX_DELTA_W_KM_MIN_DIGITS,
+                FIX_DELTA_W_KM_MAX_DIGITS);
     }
 
     public static NumberFormat getFixDeltaWDeltaW(CallContext context) {
         return getFormatter(
-            context,
-            FIX_DELTA_W_DELTA_W_MIN_DIGITS,
-            FIX_DELTA_W_DELTA_W_MAX_DIGITS);
+                context,
+                FIX_DELTA_W_DELTA_W_MIN_DIGITS,
+                FIX_DELTA_W_DELTA_W_MAX_DIGITS);
+    }
+
+    public static NumberFormat getFixDeltaWQ(CallContext context) {
+        return getFormatter(
+                context,
+                FIX_DELTA_W_DELTA_Q_MIN_DIGITS,
+                FIX_DELTA_W_DELTA_Q_MAX_DIGITS);
+    }
+
+    public static NumberFormat getFixDeltaWW(CallContext context) {
+        return getFormatter(
+                context,
+                FIX_DELTA_W_DELTA_W_MIN_DIGITS,
+                FIX_DELTA_W_DELTA_W_MAX_DIGITS);
     }
 
     public static NumberFormat getMeterFormat(CallContext context) {
         return getFormatter(
-            context,
-            0,
-            2);
+                context,
+                0,
+                2);
 
     }
+
+    public static DateFormat getDateFormatter(CallMeta m, String pattern) {
+        Locale locale = Resources.getLocale(m);
+        return new SimpleDateFormat(pattern, locale);
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,12 +1,5 @@
 package de.intevation.flys.utils;
 
-import de.intevation.artifacts.common.utils.XMLUtils;
-import de.intevation.flys.artifacts.model.MapserverStyle;
-import de.intevation.flys.artifacts.model.MapserverStyle.Clazz;
-import de.intevation.flys.artifacts.model.MapserverStyle.Expression;
-import de.intevation.flys.artifacts.model.MapserverStyle.Label;
-import de.intevation.flys.artifacts.model.MapserverStyle.Style;
-
 import java.awt.Color;
 import java.awt.Font;
 
@@ -17,122 +10,116 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.artifacts.model.MapserverStyle;
+import de.intevation.flys.artifacts.model.MapserverStyle.Clazz;
+import de.intevation.flys.artifacts.model.MapserverStyle.Expression;
+import de.intevation.flys.artifacts.model.MapserverStyle.Label;
+import de.intevation.flys.artifacts.model.MapserverStyle.Style;
+
 
 /**
  * Utility to deal with themes and their representations.
  */
 public class ThemeUtil {
 
+    /** Private logger. */
     private static Logger logger =
-        Logger.getLogger(ThemeUtil.class);
+            Logger.getLogger(ThemeUtil.class);
 
     public final static String XPATH_FILL_COLOR =
-        "/theme/field[@name='fillcolor']/@default";
+            "/theme/field[@name='fillcolor']/@default";
 
     public final static String XPATH_LINE_COLOR =
-        "/theme/field[@name='linecolor']/@default";
+            "/theme/field[@name='linecolor']/@default";
 
     public static final String XPATH_LINE_SIZE =
-        "/theme/field[@name='linesize']/@default";
+            "/theme/field[@name='linesize']/@default";
 
     public static final String XPATH_LINE_STYLE =
-        "/theme/field[@name='linetype']/@default";
+            "/theme/field[@name='linetype']/@default";
 
     public static final String XPATH_POINT_SIZE =
-        "/theme/field[@name='pointsize']/@default";
+            "/theme/field[@name='pointsize']/@default";
 
     public static final String XPATH_POINT_COLOR =
-        "/theme/field[@name='pointcolor']/@default";
+            "/theme/field[@name='pointcolor']/@default";
 
     public final static String XPATH_SHOW_BORDER =
-        "/theme/field[@name='showborder']/@default";
+            "/theme/field[@name='showborder']/@default";
 
     public final static String XPATH_SHOW_POINTS =
-        "/theme/field[@name='showpoints']/@default";
+            "/theme/field[@name='showpoints']/@default";
 
     public final static String XPATH_SHOW_LINE =
-        "/theme/field[@name='showlines']/@default";
+            "/theme/field[@name='showlines']/@default";
 
     public final static String XPATH_SHOW_VERTICAL_LINE =
-        "/theme/field[@name='showverticalline']/@default";
+            "/theme/field[@name='showverticalline']/@default";
 
     public final static String XPATH_SHOW_HORIZONTAL_LINE =
-        "/theme/field[@name='showhorizontalline']/@default";
+            "/theme/field[@name='showhorizontalline']/@default";
 
     public final static String XPATH_SHOW_LINE_LABEL =
-        "/theme/field[@name='showlinelabel']/@default";
+            "/theme/field[@name='showlinelabel']/@default";
 
     public final static String XPATH_SHOW_POINT_LABEL =
             "/theme/field[@name='showpointlabel']/@default";
 
-    public final static String XPATH_LINE_LABEL_FONT =
-        "/theme/field[@name='linelabelfont']/@default";
-
-    public final static String XPATH_LINE_LABEL_COLOR =
-        "/theme/field[@name='linelabelcolor']/@default";
-
-    public final static String XPATH_LINE_LABEL_SIZE =
-        "/theme/field[@name='linelabelsize']/@default";
-
-    public final static String XPATH_LINE_LABEL_STYLE =
-        "/theme/field[@name='linelabelstyle']/@default";
-
-    public final static String XPATH_LINE_LABEL_BGCOLOR =
-        "/theme/field[@name='linelabelbgcolor']/@default";
-
-    public final static String XPATH_LINE_LABEL_SHOWBG =
-        "/theme/field[@name='linelabelshowbg']/@default";
-
     public final static String XPATH_SHOW_WIDTH =
-        "/theme/field[@name='showwidth']/@default";
+            "/theme/field[@name='showwidth']/@default";
 
     public final static String XPATH_SHOW_LEVEL =
-        "/theme/field[@name='showwidth']/@default";
+            "/theme/field[@name='showlevel']/@default";
 
     public final static String XPATH_TRANSPARENCY =
-        "/theme/field[@name='transparent']/@default";
-
-    public final static String XPATH_TRANSPARENCY_ALPHA =
-        "/theme/field[@name='alpha']/@default";
+            "/theme/field[@name='transparency']/@default";
 
     public final static String XPATH_SHOW_AREA =
-        "/theme/field[@name='showarea']/@default";
+            "/theme/field[@name='showarea']/@default";
 
     public final static String XPATH_SHOW_MIDDLE_HEIGHT =
-        "/theme/field[@name='showmiddleheight']/@default";
-
-    public final static String XPATH_TEXT_COLOR =
-        "/theme/field[@name='textcolor']/@default";
+            "/theme/field[@name='showmiddleheight']/@default";
 
-    public final static String XPATH_TEXT_SIZE =
-        "/theme/field[@name='textsize']/@default";
+    public final static String XPATH_LABEL_FONT_COLOR =
+            "/theme/field[@name='labelfontcolor']/@default";
 
-    public final static String XPATH_TEXT_FONT =
-        "/theme/field[@name='font']/@default";
+    public final static String XPATH_LABEL_FONT_SIZE =
+            "/theme/field[@name='labelfontsize']/@default";
 
-    public final static String XPATH_TEXT_STYLE =
-        "/theme/field[@name='textstyle']/@default";
+    public final static String XPATH_LABEL_FONT_FACE =
+            "/theme/field[@name='labelfontface']/@default";
+
+    public final static String XPATH_LABEL_FONT_STYLE =
+            "/theme/field[@name='labelfontstyle']/@default";
 
     public final static String XPATH_TEXT_ORIENTATION =
-        "/theme/field[@name='textorientation']/@default";
+            "/theme/field[@name='textorientation']/@default";
 
-    public final static String XPATH_TEXT_BACKGROUND =
-        "/theme/field[@name='backgroundcolor']/@default";
+    public final static String XPATH_LABEL_BGCOLOR =
+            "/theme/field[@name='labelbgcolor']/@default";
 
-    public final static String XPATH_SHOW_BACKGROUND =
-        "/theme/field[@name='showbackground']/@default";
+    public final static String XPATH_LABEL_SHOW_BACKGROUND =
+            "/theme/field[@name='labelshowbg']/@default";
+
+    public final static String XPATH_BACKGROUND_COLOR =
+            "/theme/field[@name='backgroundcolor']/@default";
 
     public final static String XPATH_SYMBOL =
-        "/theme/field[@name='symbol']/@default";
+            "/theme/field[@name='symbol']/@default";
 
     public final static String XPATH_SHOW_MINIMUM =
-        "/theme/field[@name='showminimum']/@default";
+            "/theme/field[@name='showminimum']/@default";
 
     public final static String XPATH_SHOW_MAXIMUM =
-        "/theme/field[@name='showmaximum']/@default";
+            "/theme/field[@name='showmaximum']/@default";
 
     public final static String XPATH_WSPLGEN_FIELDS =
-        "/theme[@name='WSPLGEN']/field";
+            "/theme[@name='WSPLGEN']/field";
+
+    /** XPATH to bandwidth field. */
+    public final static String XPATH_BANDWIDTH =
+            "/theme/field[@name='bandwidth']/@default";
 
 
     /** Parse string to be boolean with default if empty or unrecognized. */
@@ -152,13 +139,43 @@
     }
 
 
+    /**
+     * Attempt converting \param value to an integer, in failing cases,
+     * return \param defaultsTo.
+     * @param value String to be converted to integer.
+     * @param defaultsTo Default to return if conversion failed.
+     * @return \param value as integer or defaultsto if conversion failed.
+     */
     public static int parseInteger(String value, int defaultsTo) {
         if (value == null || value.length() == 0) {
             return defaultsTo;
         }
 
         try {
-            return Integer.valueOf(value);
+            return Integer.parseInt(value);
+        }
+        catch (NumberFormatException nfe) {
+            // do nothing
+        }
+
+        return defaultsTo;
+    }
+
+
+    /**
+     * Attempt converting \param value to a double, in failing cases,
+     * return \param defaultsTo.
+     * @param value String to be converted to double.
+     * @param defaultsTo Default to return if conversion failed.
+     * @return \param value as integer or defaultsto if conversion failed.
+     */
+    public static double parseDouble(String value, double defaultsTo) {
+        if (value == null || value.length() == 0) {
+            return defaultsTo;
+        }
+
+        try {
+            return Double.parseDouble(value);
         }
         catch (NumberFormatException nfe) {
             // do nothing
@@ -179,7 +196,7 @@
         }
 
         try {
-            return Integer.valueOf(size);
+            return Integer.parseInt(size);
         }
         catch (NumberFormatException nfe) {
             logger.warn("Unable to set line size from string: '" + size + "'");
@@ -188,6 +205,17 @@
     }
 
 
+    /**
+     * Parse band width, defaulting to 0.
+     * @param theme the theme.
+     */
+    public static double parseBandWidth(Document theme) {
+        String bandWidth = XMLUtils.xpathString(theme, XPATH_BANDWIDTH, null);
+
+        return parseDouble(bandWidth, 0);
+    }
+
+
     public static int parsePointWidth(Document theme) {
         String width = XMLUtils.xpathString(theme, XPATH_POINT_SIZE, null);
 
@@ -244,7 +272,7 @@
         }
 
         try {
-            return Integer.valueOf(size);
+            return Integer.parseInt(size);
         }
         catch (NumberFormatException nfe) {
         }
@@ -253,12 +281,7 @@
 
 
     public static int parseTextSize(Document theme) {
-        return parseTextSize(theme, XPATH_TEXT_SIZE);
-    }
-
-
-    public static int parseLineLabelSize(Document theme) {
-        return parseTextSize(theme, XPATH_LINE_LABEL_SIZE);
+        return parseTextSize(theme, XPATH_LABEL_FONT_SIZE);
     }
 
 
@@ -339,25 +362,12 @@
     }
 
 
-    /** Parse color for line label(s text). */
-    public static Color parseLineLabelTextColor(Document theme) {
-        return parseRGB(getLineLabelTextColorString(theme));
-    }
-
-    /** Parse bg color for line label(s text). */
-    public static Color parseLineLabelBGColor(Document theme) {
-        return parseRGB(getLineLabelBGColorString(theme));
-    }
-
-    // TODO showbg and bg color for linelabels
-
-
     /**
      * Parses the font.
      * @param theme The theme.
      */
     public static Font parseTextFont(Document theme) {
-        String font = XMLUtils.xpathString(theme, XPATH_TEXT_FONT, null);
+        String font = XMLUtils.xpathString(theme, XPATH_LABEL_FONT_FACE, null);
         if (font == null || font.length() == 0) {
             return null;
         }
@@ -368,20 +378,6 @@
         return f;
     }
 
-    /** Parse font (name, size and style) for linelabels. */
-    public static Font parseLineLabelFont(Document theme) {
-        String font = XMLUtils.xpathString(theme, XPATH_LINE_LABEL_FONT, null);
-        if (font == null || font.length() == 0) {
-            return null;
-        }
-
-        int size = parseLineLabelSize(theme);
-        int style = parseLineLabelStyle(theme);
-
-        Font f = new Font (font, style, size);
-        return f;
-    }
-
 
     /**
      * Parses the text style, defaults to 'Font.PLAIN'.
@@ -406,12 +402,7 @@
 
 
     public static int parseTextStyle(Document theme) {
-        return parseTextStyle(theme, XPATH_TEXT_STYLE);
-    }
-
-
-    public static int parseLineLabelStyle(Document theme) {
-        return parseTextStyle(theme, XPATH_LINE_LABEL_STYLE);
+        return parseTextStyle(theme, XPATH_LABEL_FONT_STYLE);
     }
 
 
@@ -420,6 +411,7 @@
         return parseBoolean(show, false);
     }
 
+
     public static boolean parseShowLevel(Document theme) {
         String show = XMLUtils.xpathString(theme, XPATH_SHOW_LEVEL, null);
         return parseBoolean(show, false);
@@ -445,7 +437,7 @@
      * @param theme The theme.
      */
     public static Color parseTextBackground(Document theme) {
-        String color = getBackgroundColorString(theme);
+        String color = getLabelBackgroundColorString(theme);
         if (color == null || color.length() == 0) {
             return Color.WHITE;
         }
@@ -458,19 +450,8 @@
      * false.
      * @param theme The theme.
      */
-    public static boolean parseShowTextBackground(Document theme) {
-        String show = XMLUtils.xpathString(theme, XPATH_SHOW_BACKGROUND, null);
-        return parseBoolean(show, false);
-    }
-
-
-    /**
-     * Parses the attribute whether to show line labels background or not,
-     * defaults to false.
-     * @param theme The theme.
-     */
-    public static boolean parseShowLineLabelBG(Document theme) {
-        String show = XMLUtils.xpathString(theme, XPATH_LINE_LABEL_SHOWBG, null);
+    public static boolean parseLabelShowBackground(Document theme) {
+        String show = XMLUtils.xpathString(theme, XPATH_LABEL_SHOW_BACKGROUND, null);
         return parseBoolean(show, false);
     }
 
@@ -518,9 +499,9 @@
         Color c = null;
         try {
             c = new Color(
-                    Integer.valueOf(rgb[0].trim()),
-                    Integer.valueOf(rgb[1].trim()),
-                    Integer.valueOf(rgb[2].trim()));
+                    Integer.parseInt(rgb[0].trim()),
+                    Integer.parseInt(rgb[1].trim()),
+                    Integer.parseInt(rgb[2].trim()));
         }
         catch (NumberFormatException nfe) {
             c = null;
@@ -533,47 +514,45 @@
         return XMLUtils.xpathString(theme, XPATH_LINE_COLOR, null);
     }
 
+
     /** Get show border as string. */
     public static String getShowBorderString(Document theme) {
         return XMLUtils.xpathString(theme, XPATH_SHOW_BORDER, null);
     }
 
+
     /** Get fill color as string. */
     public static String getFillColorString(Document theme) {
         return XMLUtils.xpathString(theme, XPATH_FILL_COLOR, null);
     }
 
+
+    public static String getLabelBackgroundColorString(Document theme) {
+        return XMLUtils.xpathString(theme, XPATH_LABEL_BGCOLOR, null);
+    }
+
+
     public static String getBackgroundColorString(Document theme) {
-        return XMLUtils.xpathString(theme, XPATH_TEXT_BACKGROUND, null);
+        return XMLUtils.xpathString(theme, XPATH_BACKGROUND_COLOR, null);
     }
 
 
     public static String getTextColorString(Document theme) {
-        return XMLUtils.xpathString(theme, XPATH_TEXT_COLOR, null);
+        String textColor = XMLUtils.xpathString(theme, XPATH_LABEL_FONT_COLOR, null);
+        return textColor;
     }
 
-    public static String getLineLabelTextColorString(Document theme) {
-        return XMLUtils.xpathString(theme, XPATH_LINE_LABEL_COLOR, null);
-    }
-
-    public static String getLineLabelBGColorString(Document theme) {
-        return XMLUtils.xpathString(theme, XPATH_LINE_LABEL_BGCOLOR, null);
-    }
 
     public static String getSymbol(Document theme) {
         return XMLUtils.xpathString(theme, XPATH_SYMBOL, null);
     }
 
+
     public static String getTransparencyString(Document theme) {
         return XMLUtils.xpathString(theme, XPATH_TRANSPARENCY, null);
     }
 
 
-    public static String getTransparencyAlpha(Document theme) {
-        return XMLUtils.xpathString(theme, XPATH_TRANSPARENCY_ALPHA, null);
-    }
-
-
     public static String getShowMinimum(Document theme) {
         return XMLUtils.xpathString(theme, XPATH_SHOW_MINIMUM, null);
     }
@@ -593,14 +572,17 @@
         return parseRGB(getFillColorString(theme));
     }
 
+
     public static boolean parseShowBorder(Document theme) {
         return parseBoolean(getShowBorderString(theme), false);
     }
 
-    public static boolean parseTransparency(Document theme) {
-        return parseBoolean(getTransparencyString(theme), false);
+
+    public static int parseTransparency(Document theme) {
+        return parseInteger(getTransparencyString(theme), 50);
     }
 
+
     /**
      * Gets color from color field.
      * @param theme    the theme document.
@@ -618,6 +600,7 @@
         return parseBoolean(getShowMinimum(theme), false);
     }
 
+
     public static boolean parseShowMaximum(Document theme) {
         return parseBoolean(getShowMaximum(theme), false);
     }
@@ -625,9 +608,9 @@
 
     public static String createWSPLGENStyle(Document theme) {
         NodeList categories = (NodeList) XMLUtils.xpath(
-            theme,
-            XPATH_WSPLGEN_FIELDS,
-            XPathConstants.NODESET);
+                theme,
+                XPATH_WSPLGEN_FIELDS,
+                XPathConstants.NODESET);
 
         return createWSPLGENStyle(categories).toString();
     }
@@ -644,7 +627,7 @@
 
             try {
                 int length = name.length();
-                int idx    = Integer.valueOf(name.substring(length-1, length));
+                int idx    = Integer.parseInt(name.substring(length-1, length));
 
                 expr = createWSPLGENExpression(idx);
             }
@@ -681,7 +664,7 @@
 
     public static String createMapserverStyle(Document theme) {
         String symbol    = getSymbol(theme);
-        String backcolor = getBackgroundColorString(theme);
+        String backcolor = getLabelBackgroundColorString(theme);
         String linecolor = getLineColorString(theme);
 
         int linewidth = parseLineWidth(theme);
--- a/flys-artifacts/src/main/java/de/intevation/flys/wsplgen/FacetCreator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/java/de/intevation/flys/wsplgen/FacetCreator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -94,6 +94,7 @@
         Envelope envB = b.getGeom().getEnvelopeInternal();
 
         envA.expandToInclude(envB);
+        envA = GeometryUtils.transform(envA, getSrid());
 
         logger.debug("###    => " + envA);
 
@@ -130,6 +131,7 @@
         wsplgen.addLayer(
             MapfileGenerator.MS_WSPLGEN_PREFIX + artifact.identifier());
         wsplgen.setSrid(getSrid());
+        wsplgen.setOriginalExtent(bounds);
         wsplgen.setExtent(bounds);
 
         tmpFacets.add(wsplgen);
Binary file flys-artifacts/src/main/resources/images/bfg_logo.gif has changed
Binary file flys-artifacts/src/main/resources/images/intevation.png has changed
--- a/flys-artifacts/src/main/resources/messages.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/resources/messages.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,6 @@
+false=Nein
+true=Ja
+
 state.winfo.river = River
 state.winfo.calculation_mode = Calculation Mode
 state.winfo.location_distance = Location or distance selection
@@ -27,16 +30,31 @@
 state.fix.analysis.referenceperiod = Reference period
 state.fix.analysis.analysisperiods = Analysis period
 state.fix.analysis.function = Function
-state.fix.analysis.preprocessing = Preprocessing
+state.fix.analysis.preprocessing = Outliers
 state.fix.preprocess=preprocess
+state.fix.vollmer.function=Function
+state.fix.vollmer.preprocessing = Outliers
+state.fix.vollmer.qa = Input for W/Q data
 
 state.minfo.river = River
 state.minfo.calculation_mode = Calculation Mode
 state.minfo.distance_only = Range selection
 state.minfo.dischargestate = Selection of discharge state and channel
 state.minfo.sq.location=Location
-state.minfo.sq.periods=Periods
+state.minfo.sq.period=Periods
 state.minfo.sq.outliers=Outliers
+state.minfo.bed.year_epoch=Year/Epoch
+state.minfo.bed.difference_select=Differences
+state.minfo.year=Year
+state.minfo.epoch=Epoch
+state.minfo.bed.location = Location/Distance
+state.minfo.bed.periods = Periods
+state.minfo.bed.char_diameter = Characteristic Diameter
+state.minfo.soundings = Choose Soundings
+
+year=Year
+epoch=Epoch
+soundings = Soundings / Epochs
 
 historical.mode.w = Waterlevel Analyse
 historical.mode.q = Discharge Analyse
@@ -50,16 +68,32 @@
 calc.historical.discharge.curve = Historical Discharge Curve
 calc.reference.curve = Reference Curve
 calc.fixation.default = Fixingg
-calc.fixation.volmer = Generative Waterlevel
+calc.fixation.vollmer = Generative Waterlevel
 calc.bed.middle = Middle Bed Height
 calc.bed.diff = Bed Height Difference
 calc.bed.quality = Bed Quality
 calc.sediment.load = Sediment Load
 calc.flow.velocity = Flow Velocity
 calc.sq.relation = Load Discharge Relation
+calc.bed.d90 = D90
+calc.bed.d84 = D84
+calc.bed.d80 = D80
+calc.bed.d75 = D75
+calc.bed.d70 = D70
+calc.bed.d60 = D60
+calc.bed.d50 = D50
+calc.bed.d40 = D40
+calc.bed.d30 = D30
+calc.bed.d25 = D25
+calc.bed.d20 = D20
+calc.bed.d16 = D16
+calc.bed.d10 = D10
+calc.bed.dmin = Dmin
+calc.bed.dmax = Dmax
+calc.bed.dmid = Dmid
 
 calculation.analysis = Fixinganalysis
-calculation.volmer = relocated Waterlevel Calculation
+calculation.vollmer = relocated Waterlevel Calculation
 
 state.chart.river = River
 state.chart.type = Charttype
@@ -86,8 +120,8 @@
 river = River
 calculation_mode = Calculation Mode
 ld_locations = Location(s)
-main.channel = Main channel
-total.channel = Total channel
+main_channel = Main channel
+total_channel = Total channel
 
 chart.longitudinal.section.title = W-Longitudinal Section
 chart.longitudinal.section.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
@@ -128,7 +162,7 @@
 chart.reference.curve.subtitle = {0}
 
 chart.reference.curve.x.axis.in.cm = Reference Gauge(s) [cm]
-chart.reference.curve.x.axis.in.m = Reference Station(s) [NN + m]
+chart.reference.curve.x.axis.in.m = Reference Station [NN + m]
 chart.reference.curve.y.axis.in.cm = Target Gauge(s) [cm]
 chart.reference.curve.y.axis.in.m = Target Station(s) [NN + m] 
 
@@ -139,6 +173,24 @@
 
 chart.normalized.reference.curve.title = Reduced Reference Curve
 
+chart.fixings.wq.title = Fixings Analysis at km {0}
+chart.fixings.wq.subtitle=River: {0}; Range: {1,date,short} to {2,date,short}; Reference period: {3,date,short} to {4,date,short}
+chart.fixings.wq.subtitle1={0,date,short} to {1,date,short}
+chart.fixings.analysis.title = Longitudinal section at km {0}
+
+chart.bedquality.title=Bed Longitudinal Section
+chart.bedquality.xaxis.label=River-Km
+chart.bedquality.yaxis.label=Diameter [m]
+chart.bedquality.yaxis.label.porosity=Porosity [%]
+chart.bedquality.yaxis.label.density=Density [t/m\u00b3]
+
+chart.bedheight_middle.section.title=Middle Bed Height
+chart.bedheight_middle.section.yaxis.label=middle Bed Height [mm a NN]
+
+chart.flow_velocity.section.title=Geschwindigkeit- und Schubspannung
+chart.flow_velocity.section.yaxis.label=Speed v [m/s]
+chart.flow_velocity.section.yaxis.second.label=Schubspannung Tau [N]
+
 chart.sq_relation.xaxis.label = Discharge [m\u00b3/s]
 chart.sq_relation.yaxis.label = Transport [kg/s]
 chart.sq_relation_a.title = Feinkornanteil
@@ -150,6 +202,8 @@
 facet.sq_relation.curve = Potenziell (Geschiebedaten)
 facet.sq_relation.measurements = Geschiebedaten
 facet.sq_relation.outliers = Ausrei\u00dfer Durchgang {0}
+facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
+facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
 facet.longitudinal_section.annotations = POIs
 facet.discharge_curves.mainvalues.q = Q (main values)
@@ -159,6 +213,35 @@
 facet.flow_velocity.tauchannel = TAU Mainchannel at {0}
 facet.bedheight_middle.single = Bed Height {0,number,####}
 facet.bedheight_middle.epoch = Bed Height Epoch {0,number,####} - {1,number,####}
+facet.bedquality.bed.porosity.toplayer = Porosity ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.porosity.sublayer = Porosity ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.toplayer = Density ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.sublayer = Density ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.diameter.toplayer = {0}_Bed ({1,date} - {2,date}) ({3})
+facet.bedquality.bed.diameter.sublayer = {0}_Bed ({1,date} - {2,date}) ({3})
+facet.bedquality.bedload.diameter = {0}_Bedload
+bedquality.toplayer = 0.0m - 0.3m
+bedquality.sublayer = 0.1m - 0.5m
+facet.bedheight.diff.year = Bedheight Difference {0}
+facet.bedheight.diff.morph = Morphologic Width {0}
+facet.bedheight.diff.height1 = Original Height Minuend {0}
+facet.bedheight.diff.height2 = Original Height Subtrahend {0}
+facet.bedheight.diff.absolute = Bedheight Difference/Year {0}
+facet.bedheight.diff.epoch = Bedheight Difference {0}
+
+chart.beddifference.height.title = Bedheight Difference
+chart.beddifference.height.xaxis.label = River-Km [km]
+chart.beddifference.height.yaxis.label = Difference [cm/year]
+chart.beddifference.epoch.title = Bedheight Difference
+chart.beddifference.xaxis.label = River-Km [km]
+chart.beddifference.yaxis.label.diff = Difference [m]
+chart.beddifference.yaxis.label.height = Absolute Height [m]
+chart.beddifference.year.title = Bedheight Difference
+chart.beddifference.xaxis.label = River-Km [km]
+chart.beddifference.yaxis.label.diff = Difference [m]
+chart.beddifference.yaxis.label.morph = Morphologic Width [m]
+chart.beddifference.yaxis.label.heights = Absolute Height [m]
+
 
 export.waterlevel.csv.header.km = River-Km
 export.waterlevel.csv.header.w = W [NN + m]
@@ -238,6 +321,14 @@
 export.sqrelation.csv.header.c.duan = C (DUAN)
 export.sqrelation.csv.header.c.ferguson = C (FERGUSON)
 export.sqrelation.csv.header.variance = Standard variance
+export.minfo.bedquality.km = km
+export.minfo.bedquality.density_cap = Density Toplayer
+export.minfo.bedquality.density_sub = Density Sublayer
+export.minfo.bedquality.porosity_cap = Porosity Toplayer
+export.minfo.bedquality.porosity_sub = Porosity Sublayer
+export.minfo.bedquality.bedload = Bedload Diameter
+export.minfo.bedquality.bed_cap = Bed Diameter Toplayer
+export.minfo.bedquality.bed_sub = Bed Diameter Sublayer
 
 floodmap.wmsbackground = Background Map
 floodmap.riveraxis = River Axis
@@ -329,19 +420,41 @@
 help.winfo.historical.discharge.mode=https://flys-intern.intevation.de/Flys-3.0/OnlineHilfe/WINFO#Auswahl_der_Analyseart
 
 fix.reference.period=Reference period
-fix.reference.period.events=Reference period events
+fix.reference.period.event=Reference event
+fix.reference.period.event.short=R
+fix.analysis.short=A
 fix.analysis.periods=Analysis periods
 fix.derivative=Derivative
 fix.outlier=Outlier
-fix.analysis=Analysis
+fix.analysis=Analysis event
 fix.deviation=Standard deviation
 fix.reference.deviation=Reference deviation
+fix.vollmer.wq.curve=W/Q
+fix.vollmer.wq.outliers=Outliers
+fix.vollmer.wq.events=Events
+qsectors=Discharge Sectors
 
-chart.fix.deltawt.title=Difference from compensating curve
-chart.fix.deltawt.subtitle=Water: {0}; Period:  {1,date,short} to {2,date,short}
+chart.fix.deltawt.title=Difference from compensating curve at kilometer {0}
+chart.fix.deltawt.subtitle=Water: {0}; Period:  {1,date,short} to {2,date,short}; Reference period: {3,date,short} bis {4,date,short}
 chart.fix.deltawt.xaxis.label=Date
 chart.fix.deltawt.yaxis.label=\u0394 W(t) [cm]
 
+chart.fix.wq.subtitle=Water: {0}; Period: {1,date,short} to {2,date,short}
+chart.fixings.derivedcurve.title = Derived curve at km {0}
+chart.fixings.deltawt.title = Differences from fitted curve at km {0}
+
+chart.fixings.longitudinalsection.title=Longitudinal section
+
+export.fixings.deltawt.csv.header.km=km
+export.fixings.deltawt.csv.header.deltaw=\u0394 W [cm]
+export.fixings.deltawt.csv.header.q=Discharge [m\u00b3/s]
+export.fixings.deltawt.csv.header.w=Waterlevel [m]
+export.fixings.deltawt.csv.header.t=Date
+export.fixings.deltawt.csv.t.format=yyyy/MM/dd
+export.fixings.deltawt.csv.header.time.range=State
+export.fixings.deltawt.csv.reference=R
+export.fixings.deltawt.csv.analysis=A{0,number,integer}
+
 fix.missing.river=Missing river
 fix.missing.from=Missing start km
 fix.missing.to=Missing end km
@@ -375,3 +488,15 @@
 sq.km.chart.title = Measuring Points
 sq.km.chart.km.axis = km
 sq.km.chart.date.axis = Date
+
+module.winfo = WINFO
+module.minfo = MINFO
+module.fixanalysis = Fix Analysis
+module.new_map = New Map
+module.new_chart = New Chart
+
+load_diameter = Bedload Diameter
+bed_diameter = Bed Diameter
+
+area.label.template = Area = %s m\u00b3
+
--- a/flys-artifacts/src/main/resources/messages_de.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/resources/messages_de.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,6 @@
+false=Nein
+true=Ja
+
 state.winfo.river = Gew\u00e4sser
 state.winfo.calculation_mode = Berechnungsart
 state.winfo.location_distance = Wahl des Berechnungsortes/strecke
@@ -27,16 +30,31 @@
 state.fix.analysis.referenceperiod = Bezugszeitraum
 state.fix.analysis.analysisperiods = Analysezeitr\u00e4ume
 state.fix.analysis.function = Funktion
-state.fix.analysis.preprocessing = Aufbereiten
+state.fix.analysis.preprocessing = Ausrei\u00DFer
 state.fix.preprocess=aufbereiten
+state.fix.vollmer.function=Funktion
+state.fix.vollmer.preprocessing = Ausrei\u00DFer
+state.fix.vollmer.qa = Eingabe f\u00e4r W/Q Daten
 
 state.minfo.river = Gew\u00e4sser
 state.minfo.calculation_mode = Berechnungsart
 state.minfo.distance_only = Wahl der Berechnungsstrecke
 state.minfo.dischargestate = Abflusszustand und Gerinne
 state.minfo.sq.location=Ort
-state.minfo.sq.periods=Zeitraum
+state.minfo.sq.period=Zeitraum
 state.minfo.sq.outliers=Ausrei\u00dfer
+state.minfo.bed.year_epoch=Jahr/Epoche
+state.minfo.bed.difference_select=Differenzen
+state.minfo.year=Jahr
+state.minfo.epoch=Epoche
+state.minfo.bed.location = Ort(e)/Strecke
+state.minfo.bed.periods = Zeitraum/Zeitr\u00e4ume
+state.minfo.bed.char_diameter = Charakteristischer Durchmesser
+state.minfo.soundings = Wahl der Peilungen
+
+year=Jahr
+epoch=Epoche
+soundings = Peilungen / Epochen
 
 historical.mode.w = Wasserstandsanalyse
 historical.mode.q = Abflussanalyse
@@ -50,16 +68,32 @@
 calc.historical.discharge.curve = Hist. Abflusskurven
 calc.reference.curve = Bezugslinie
 calc.fixation.default = Fixierungsanalyse
-calc.fixation.volmer = Ausgelagerte Wasserspiegellage
+calc.fixation.vollmer = Ausgelagerte Wasserspiegellage
 calc.bed.middle = Mittlere Sohlh\u00f6he
 calc.bed.diff = Sohlh\u00f6hendifferenz
 calc.bed.quality = Sohlbeschaffenheit
 calc.sediment.load = Sedimentfracht
 calc.flow.velocity = Flie\u00dfgeschwindigkeit
 calc.sq.relation = Transport-Abfluss Beziehung
+calc.bed.d90 = D90
+calc.bed.d84 = D84
+calc.bed.d80 = D80
+calc.bed.d75 = D75
+calc.bed.d70 = D70
+calc.bed.d60 = D60
+calc.bed.d50 = D50
+calc.bed.d40 = D40
+calc.bed.d30 = D30
+calc.bed.d25 = D25
+calc.bed.d20 = D20
+calc.bed.d16 = D16
+calc.bed.d10 = D10
+calc.bed.dmin = Dmin
+calc.bed.dmax = Dmax
+calc.bed.dmid = Dmid
 
 calculation.analysis = Fixierungsanalyse
-calculation.volmer = ausgelagerte Wasserspiegellage
+calculation.vollmer = ausgelagerte Wasserspiegellage
 
 state.chart.river = Gew\u00e4sser
 state.chart.type = Diagrammtyp
@@ -86,10 +120,10 @@
 river = Fluss
 calculation_mode = Berechnungsart
 ld_locations = Ort(e)
-main.channel = Hauptgerinne
-total.channel = Gesamtgerinne
+main_channel = Hauptgerinne
+total_channel = Gesamtgerinne
 
-chart.cross_section.title = Querprofildiagram f\u00fcr Gew\u00e4sser {0}
+chart.cross_section.title = Querprofildiagramm f\u00fcr Gew\u00e4sser {0}
 chart.cross_section.subtitle = {0}-km: {1,number,#.###}
 chart.cross_section.xaxis.label = Abstand [m]
 chart.cross_section.yaxis.label = W [NN + m]
@@ -126,8 +160,14 @@
 chart.reference.curve.title = Bezugslinie
 chart.reference.curve.subtitle = {0}
 
+chart.fixings.derivedcurve.title = Ableitungskurve an Kilometer {0}
+chart.fixings.deltawt.title = Abweichungen von der Ausgleichskurve an Kilometer {0}
+chart.fixings.analysis.title = L\u00e4ngsschnitt an Kilometer {0}
+chart.fixings.wq.title = Fixierungsanalyse an Kilometer {0}
+
+
 chart.reference.curve.x.axis.in.cm = Bezugspegel [cm]
-chart.reference.curve.x.axis.in.m = Bezugsort(e) [NN + m]
+chart.reference.curve.x.axis.in.m = Bezugsort [NN + m]
 chart.reference.curve.y.axis.in.cm = Zielpegel [cm]
 chart.reference.curve.y.axis.in.m = Zielort(e) [NN + m] 
 
@@ -138,6 +178,19 @@
 chart.w_differences.yaxis.label = m
 chart.w_differences.yaxis.second.label = W [NN + m]
 
+chart.bedquality.title=Sohlen L\u00e4ngsschnitt
+chart.bedquality.xaxis.label=Fluss-Km
+chart.bedquality.yaxis.label=Durchmesser [m]
+chart.bedquality.yaxis.label.porosity=Porosit\u00e4t [%]
+chart.bedquality.yaxis.label.density=Dichte [t/m\u00b3]
+
+chart.bedheight_middle.section.title=Mittlere Sohlh\u00f6he
+chart.bedheight_middle.section.yaxis.label=mittlere Sohlh\u00f6hen [mm\u00fcNN]
+
+chart.flow_velocity.section.title=Geschwindigkeit- und Schubspannung
+chart.flow_velocity.section.yaxis.label=Geschwindigkeit v [m/s]
+chart.flow_velocity.section.yaxis.second.label=Schubspannung Tau [N]
+
 chart.sq_relation.xaxis.label = Abfluss [m\u00b3/s]
 chart.sq_relation.yaxis.label = Transport [kg/s]
 chart.sq_relation_a.title = Feinkornanteil
@@ -149,6 +202,8 @@
 facet.sq_relation.curve = Potenziell (Geschiebedaten)
 facet.sq_relation.measurements = Geschiebedaten
 facet.sq_relation.outliers = Ausrei\u00dfer Durchgang {0}
+facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
+facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
 facet.longitudinal_section.annotations = Streckenfavoriten
 facet.discharge_curves.mainvalues.q = Q (Haupt- und Extremwerte)
@@ -158,6 +213,34 @@
 facet.flow_velocity.tauchannel = TAU Hauptgerinne bei {0}
 facet.bedheight_middle.single = Sohlh\u00f6he {0,number,####}
 facet.bedheight_middle.epoch = Sohlh\u00f6he Epoche {0,number,####} - {1,number,####}
+facet.bedquality.bed.porosity.toplayer = Porosit\u00e4t ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.porosity.sublayer = Porosit\u00e4t ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.toplayer = Dichte ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.sublayer = Dichte ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.diameter.toplayer = {0}_Sohle ({1,date} - {2,date}) ({3})
+facet.bedquality.bed.diameter.sublayer = {0}_Sohle ({1,date} - {2,date}) ({3})
+facet.bedquality.bedload.diameter = {0}_Geschiebe
+bedquality.toplayer = 0,0m - 0,3m
+bedquality.sublayer = 0,1m - 0,5m
+facet.bedheight.diff.year = Sohlh\u00f6hendiffernez {0}
+facet.bedheight.diff.morph = Morphologische Breite {0}
+facet.bedheight.diff.height1 = H\u00f6he Minuend {0}
+facet.bedheight.diff.height2 = H\u00f6he Subtrahend {0}
+facet.bedheight.diff.absolute = Sohlh\u00f6hendifferenz/Jahr {0}
+facet.bedheight.diff.epoch = Sohlh\u00f6hendifferenz {0}
+
+chart.beddifference.height.title = Sohlh\u00f6hendifferenz
+chart.beddifference.height.xaxis.label = Fluss-Km [km]
+chart.beddifference.height.yaxis.label = Differenz [cm/Jahr]
+chart.beddifference.epoch.title = Sohlh\u00f6hendifferenz
+chart.beddifference.xaxis.label = Fluss-Km [km]
+chart.beddifference.yaxis.label.diff = Differenz [m]
+chart.beddifference.yaxis.label.height = Absolute H\u00f6he [m]
+chart.beddifference.year.title = Sohlh\u00f6hendifferenz
+chart.beddifference.xaxis.label = Fluss-Km [km]
+chart.beddifference.yaxis.label.diff = Differenz [m]
+chart.beddifference.yaxis.label.morph = Morphologische Breite [m]
+chart.beddifference.yaxis.label.heights = Absolute H\u00f6he [m]
 
 export.waterlevel.csv.header.km = Fluss-Km
 export.waterlevel.csv.header.w = W [NN + m]
@@ -238,6 +321,14 @@
 export.sqrelation.csv.header.c.duan = C (DUAN)
 export.sqrelation.csv.header.c.ferguson = C (FERGUSON)
 export.sqrelation.csv.header.variance = Standardabweichung
+export.minfo.bedquality.km = km
+export.minfo.bedquality.density_cap = Sedimentdichte Deckschicht
+export.minfo.bedquality.density_sub = Sedimentdichte Unterschicht
+export.minfo.bedquality.porosity_cap = Porosit\u00e4t Deckschicht
+export.minfo.bedquality.porosity_sub = Porosit\u00e4t Unterschicht
+export.minfo.bedquality.bedload = Geschiebedurchmesser
+export.minfo.bedquality.bed_cap = Sohldurchmesser Deckschicht
+export.minfo.bedquality.bed_sub = Sohldurchmesser Unterschicht
 
 floodmap.wmsbackground = Hintergrundkarte
 floodmap.riveraxis = Flussachse
@@ -330,19 +421,42 @@
 help.winfo.historical.discharge.mode=https://flys-intern.intevation.de/Flys-3.0/OnlineHilfe/WINFO#Auswahl_der_Analyseart
 
 fix.reference.period=Bezugszeitraum
-fix.reference.period.events=Ereignisse im Bezugszeitraum
+fix.reference.period.event=Bezugsereignis
+fix.reference.period.event.short=B
+fix.analysis.short=A
 fix.analysis.periods=Analysezeitr\u00e4ume
 fix.derivative=Ableitung
 fix.outlier=Ausrei\u00dfer
-fix.analysis=Analyse
+fix.analysis=Analyseereignis
 fix.deviation=Standardabweichung
 fix.reference.deviation=Abweichung im Bezugszeitraum
+fix.vollmer.wq.curve=W/Q
+fix.vollmer.wq.outliers=Ausrei\u00dfer
+fix.vollmer.wq.events=Ereignisse
+qsectors=Abfluss-Sektoren
 
-chart.fix.deltawt.title=Abweichungen von der Ausgleichskurve
-chart.fix.deltawt.subtitle=Gewässer: {0}; Darstellungszeitraum: {1,date,short} bis {2,date,short}
+chart.fix.deltawt.title=Abweichungen von der Ausgleichskurve an Kilometer {0}
+chart.fix.deltawt.subtitle=Gew\u00e4sser: {0}; Darstellungszeitraum: {1,date,short} bis {2,date,short}; Bezugszeitraum: {3,date,short} bis {4,date,short}
 chart.fix.deltawt.xaxis.label=Datum
 chart.fix.deltawt.yaxis.label=\u0394 W(t) [cm]
 
+chart.fixings.wq.subtitle=Gew\u00e4sser: {0}; Darstellungszeitraum: {1,date,short} bis {2,date,short}; Bezugszeitraum: {3,date,short} bis {4,date,short}
+chart.fixings.wq.subtitle1={0,date,short} bis {1,date,short}
+
+chart.fixings.longitudinalsection.title=L\u00e4ngsschnitt
+
+export.fixings.deltawt.csv.header.km=km
+export.fixings.deltawt.csv.header.deltaw=\u0394 W [cm]
+export.fixings.deltawt.csv.header.q=Abfluss [m\u00b3/s]
+export.fixings.deltawt.csv.header.w=Wasserstand [m]
+export.fixings.deltawt.csv.header.t=Datum
+export.fixings.deltawt.csv.t.format=dd.MM.yyyy
+export.fixings.deltawt.csv.header.time.range=Status
+export.fixings.deltawt.csv.reference=B
+export.fixings.deltawt.csv.analysis=A{0,number,integer}
+
+chart.fix.wq.subtitle=Gew\u00e4sser: {0}; Zeitraum: {1,date,short} bis {2,date,short}
+
 fix.missing.river=Kein Gew\u00e4sser gew\u00e4hlt
 fix.missing.from=Kein Startkilometer gew\u00e4hlt
 fix.missing.to=Kein Endkilometer gew\u00e4hlt
@@ -376,3 +490,15 @@
 sq.km.chart.title = Messstellen
 sq.km.chart.km.axis = km
 sq.km.chart.date.axis = Datum
+
+module.winfo = WINFO
+module.minfo = MINFO
+module.fixanalysis = Fixierungsanalyse
+module.new_map = Neue Karte
+module.new_chart = Neues Diagramm
+
+load_diameter = Geschiebedurchmesser
+bed_diameter = Sohldurchmesser
+
+area.label.template = Fl\u00e4che = %s m\u00b3
+
--- a/flys-artifacts/src/main/resources/messages_de_DE.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/resources/messages_de_DE.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,6 @@
+false=Nein
+true=Ja
+
 state.winfo.river = Gew\u00e4sser
 state.winfo.calculation_mode = Berechnungsart
 state.winfo.location_distance = Wahl des Berechnungsortes/strecke
@@ -27,16 +30,31 @@
 state.fix.analysis.referenceperiod = Bezugszeitraum
 state.fix.analysis.analysisperiods = Analysezeitr\u00e4ume
 state.fix.analysis.function = Funktion
-state.fix.analysis.preprocessing = Aufbereitung
+state.fix.analysis.preprocessing = Ausrei\u00DFer
 state.fix.preprocess=aufbereiten
+state.fix.vollmer.function=Funktion
+state.fix.vollmer.preprocessing = Ausrei\u00DFer
+state.fix.vollmer.qa = Eingabe f\u00e4r W/Q Daten
 
 state.minfo.river = Gew\u00e4sser
 state.minfo.calculation_mode = Berechnungsart
 state.minfo.distance_only = Wahl der Berechnungsstrecke
 state.minfo.dischargestate = Abflusszustand und Gerinne
 state.minfo.sq.location=Ort
-state.minfo.sq.periods=Zeitraum
+state.minfo.sq.period=Zeitraum
 state.minfo.sq.outliers=Ausrei\u00dfer
+state.minfo.bed.year_epoch=Jahr/Epoche
+state.minfo.bed.difference_select=Differenzen
+state.minfo.year=Jahr
+state.minfo.epoch=Epoche
+state.minfo.bed.location = Ort(e)/Strecke
+state.minfo.bed.periods = Zeitraum/Zeitr\u00e4ume
+state.minfo.bed.char_diameter = Charakteristischer Durchmesser
+state.minfo.soundings = Wahl der Peilungen
+
+year=Jahr
+epoch=Epoche
+soundings = Peilungen / Epochen
 
 historical.mode.w = Wasserstandsanalyse
 historical.mode.q = Abflussanalyse
@@ -50,16 +68,32 @@
 calc.historical.discharge.curve = Hist. Abflusskurven
 calc.reference.curve = Bezugslinie
 calc.fixation.default = Fixierung
-calc.fixation.volmer = Ausgelagerte Wasserspiegellage
+calc.fixation.vollmer = Ausgelagerte Wasserspiegellage
 calc.bed.middle = Mittlere Sohlh\u00f6he
 calc.bed.diff = Sohlh\u00f6hendifferenz
 calc.bed.quality = Sohlbeschaffenheit
 calc.sediment.load = Sedimentfracht
 calc.flow.velocity = Flie\u00dfgeschwindigkeit
 calc.sq.relation = Transport-Abfluss Beziehung
+calc.bed.d90 = D90
+calc.bed.d84 = D84
+calc.bed.d80 = D80
+calc.bed.d75 = D75
+calc.bed.d70 = D70
+calc.bed.d60 = D60
+calc.bed.d50 = D50
+calc.bed.d40 = D40
+calc.bed.d30 = D30
+calc.bed.d25 = D25
+calc.bed.d20 = D20
+calc.bed.d16 = D16
+calc.bed.d10 = D10
+calc.bed.dmin = Dmin
+calc.bed.dmax = Dmax
+calc.bed.dmid = Dmid
 
 calculation.analysis = Fixierungsanalyse
-calculation.volmer = ausgelagerte Wasserspiegellage
+calculation.vollmer = ausgelagerte Wasserspiegellage
 
 state.chart.river = Gew\u00e4sser
 state.chart.type = Diagrammtyp
@@ -86,10 +120,10 @@
 river = Fluss
 calculation_mode = Berechnungsart
 ld_locations = Ort(e)
-main.channel = Hauptgerinne
-total.channel = Gesamtgerinne
+main_channel = Hauptgerinne
+total_channel = Gesamtgerinne
 
-chart.cross_section.title = Querprofildiagram f\u00fcr Gew\u00e4sser {0}
+chart.cross_section.title = Querprofildiagramm f\u00fcr Gew\u00e4sser {0}
 chart.cross_section.subtitle = {0}-km: {1,number,#.###}
 chart.cross_section.xaxis.label = Abstand [m]
 chart.cross_section.yaxis.label = W [NN + m]
@@ -127,17 +161,34 @@
 chart.reference.curve.subtitle = {0}
 
 chart.reference.curve.x.axis.in.cm = Bezugspegel [cm]
-chart.reference.curve.x.axis.in.m = Bezugsort(e) [NN + m]
+chart.reference.curve.x.axis.in.m = Bezugsort [NN + m]
 chart.reference.curve.y.axis.in.cm = Zielpegel [cm]
 chart.reference.curve.y.axis.in.m = Zielort(e) [NN + m] 
 
+chart.fixings.derivedcurve.title = Ableitungskurve an Kilometer {0}
+chart.fixings.analysis.title = L\u00e4ngsschnitt an Kilometer {0}
+chart.fixings.wq.title = Fixierungsanalyse an Kilometer {0}
+
 chart.normalized.reference.curve.title = Reduzierte Bezugslinie
 
 chart.w_differences.title = Differenzen
-chart.w_differences.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
+chart.w_differences.subtitle = Strecke: {0}-km {1,number,#.###} - {2,number,#.###}
 chart.w_differences.yaxis.label = m
 chart.w_differences.yaxis.second.label = W [NN + m]
 
+chart.bedquality.title=Sohlen L\u00e4ngsschnitt
+chart.bedquality.xaxis.label=Fluss-Km
+chart.bedquality.yaxis.label=Durchmesser [m]
+chart.bedquality.yaxis.label.porosity=Porosit\u00e4t [%]
+chart.bedquality.yaxis.label.density=Dichte [t/m\u00b3]
+
+chart.bedheight_middle.section.title=Mittlere Sohlh\u00f6he
+chart.bedheight_middle.section.yaxis.label=mittlere Sohlh\u00f6hen [mm\u00fcNN]
+
+chart.flow_velocity.section.title=Geschwindigkeit- und Schubspannung
+chart.flow_velocity.section.yaxis.label=Geschwindigkeit v [m/s]
+chart.flow_velocity.section.yaxis.second.label=Schubspannung Tau [N]
+
 chart.sq_relation.xaxis.label = Abfluss [m\u00b3/s]
 chart.sq_relation.yaxis.label = Transport [kg/s]
 chart.sq_relation_a.title = Feinkornanteil
@@ -149,6 +200,8 @@
 facet.sq_relation.curve = Potenziell (Geschiebedaten)
 facet.sq_relation.measurements = Geschiebedaten
 facet.sq_relation.outliers = Ausrei\u00dfer Durchgang {0}
+facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
+facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
 facet.longitudinal_section.annotations = Streckenfavoriten
 facet.discharge_curves.mainvalues.q = Q (Haupt- und Extremwerte)
@@ -158,6 +211,34 @@
 facet.flow_velocity.tauchannel = TAU Hauptgerinne bei {0}
 facet.bedheight_middle.single = Sohlh\u00f6he {0,number,####}
 facet.bedheight_middle.epoch = Sohlh\u00f6he Epoche {0,number,####} - {1,number,####}
+facet.bedquality.bed.porosity.toplayer = Porosit\u00e4t ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.porosity.sublayer = Porosit\u00e4t ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.toplayer = Dichte ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.sublayer = Dichte ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.diameter.toplayer = {0}_Sohle ({1,date} - {2,date}) ({3})
+facet.bedquality.bed.diameter.sublayer = {0}_Sohle ({1,date} - {2,date}) ({3})
+facet.bedquality.bedload.diameter = {0}_Geschiebe
+bedquality.toplayer = 0,0m - 0,3m
+bedquality.sublayer = 0,1m - 0,5m
+facet.bedheight.diff.year = Sohlh\u00f6hendiffernez {0}
+facet.bedheight.diff.morph = Morphologische Breite {0}
+facet.bedheight.diff.height1 = H\u00f6he Minuend {0}
+facet.bedheight.diff.height2 = H\u00f6he Subtrahend {0}
+facet.bedheight.diff.absolute = Sohlh\u00f6hendifferenz/Jahr {0}
+facet.bedheight.diff.epoch = Sohlh\u00f6hendifferenz {0}
+
+chart.beddifference.height.title = Sohlh\u00f6hendifferenz
+chart.beddifference.height.xaxis.label = Fluss-Km [km]
+chart.beddifference.height.yaxis.label = Differenz [cm/Jahr]
+chart.beddifference.epoch.title = Sohlh\u00f6hendifferenz
+chart.beddifference.xaxis.label = Fluss-Km [km]
+chart.beddifference.yaxis.label.diff = Differenz [m]
+chart.beddifference.yaxis.label.height = Absolute H\u00f6he [m]
+chart.beddifference.year.title = Sohlh\u00f6hendifferenz
+chart.beddifference.xaxis.label = Fluss-Km [km]
+chart.beddifference.yaxis.label.diff = Differenz [m]
+chart.beddifference.yaxis.label.morph = Morphologische Breite [m]
+chart.beddifference.yaxis.label.heights = Absolute H\u00f6he [m]
 
 export.waterlevel.csv.header.km = Fluss-Km
 export.waterlevel.csv.header.w = W [NN + m]
@@ -237,6 +318,14 @@
 export.sqrelation.csv.header.c.duan = C (DUAN)
 export.sqrelation.csv.header.c.ferguson = C (FERGUSON)
 export.sqrelation.csv.header.variance = Standardabweichung
+export.minfo.bedquality.km = km
+export.minfo.bedquality.density_cap = Sedimentdichte Deckschicht
+export.minfo.bedquality.density_sub = Sedimentdichte Unterschicht
+export.minfo.bedquality.porosity_cap = Porosit\u00e4t Deckschicht
+export.minfo.bedquality.porosity_sub = Porosit\u00e4t Unterschicht
+export.minfo.bedquality.bedload = Geschiebedurchmesser
+export.minfo.bedquality.bed_cap = Sohldurchmesser Deckschicht
+export.minfo.bedquality.bed_sub = Sohldurchmesser Unterschicht
 
 floodmap.wmsbackground = Hintergrundkarte
 floodmap.riveraxis = Flussachse
@@ -329,19 +418,44 @@
 help.winfo.historical.discharge.mode=https://flys-intern.intevation.de/Flys-3.0/OnlineHilfe/WINFO#Auswahl_der_Analyseart
 
 fix.reference.period=Bezugszeitraum
-fix.reference.period.events=Ereignisse im Bezugszeitraum
+fix.reference.period.event=Bezugsereignis
+fix.reference.period.event.short=B
+fix.analysis.short=A
 fix.analysis.periods=Analysezeitr\u00e4ume
 fix.derivative=Ableitung
 fix.outlier=Ausrei\u00dfer
-fix.analysis=Analyse
+fix.analysis=Analyseereignis
 fix.deviation=Standardabweichung
 fix.reference.deviation=Abweichung im Bezugszeitraum
+fix.vollmer.wq.curve=W/Q
+fix.vollmer.wq.outliers=Ausrei\u00dfer
+fix.vollmer.wq.events=Ereignisse
+qsectors=Abfluss-Sektoren
 
-chart.fix.deltawt.title=Abweichungen von der Ausgleichskurve
-chart.fix.deltawt.subtitle=Gewässer: {0}; Darstellungszeitraum: {1,date,short} bis {2,date,short}
+chart.fix.deltawt.title=Abweichungen von der Ausgleichskurve an Kilometer {0}
+chart.fix.deltawt.subtitle=Gew\u00e4sser: {0}; Darstellungszeitraum: {1,date,short} bis {2,date,short}; Bezugszeitraum: {3,date,short} bis {4,date,short}
 chart.fix.deltawt.xaxis.label=Datum
 chart.fix.deltawt.yaxis.label=\u0394 W(t) [cm]
 
+chart.fixings.wq.subtitle=Gew\u00e4sser: {0}; Darstellungszeitraum: {1,date,short} bis {2,date,short}; Bezugszeitraum: {3,date,short} bis {4,date,short}
+chart.fixings.wq.subtitle1={0,date,short} bis {1,date,short}
+
+chart.fix.wq.subtitle=Gew\u00e4sser: {0}; Zeitraum: {1,date,short} bis {2,date,short}
+
+chart.fixings.longitudinalsection.title=L\u00e4ngsschnitt
+
+chart.fixings.deltawt.title = Abweichungen von der Ausgleichskurve am Kilometer {0}
+
+export.fixings.deltawt.csv.header.km=km
+export.fixings.deltawt.csv.header.deltaw=\u0394 W [cm]
+export.fixings.deltawt.csv.header.q=Abfluss [m\u00b3/s]
+export.fixings.deltawt.csv.header.w=Wasserstand [m]
+export.fixings.deltawt.csv.header.t=Datum
+export.fixings.deltawt.csv.t.format=dd.MM.yyyy
+export.fixings.deltawt.csv.header.time.range=Status
+export.fixings.deltawt.csv.reference=B
+export.fixings.deltawt.csv.analysis=A{0,number,integer}
+
 fix.missing.river=Kein Gew\u00e4sser gew\u00e4hlt
 fix.missing.from=Kein Startkilometer gew\u00e4hlt
 fix.missing.to=Kein Endkilometer gew\u00e4hlt
@@ -375,3 +489,15 @@
 sq.km.chart.title = Messstellen
 sq.km.chart.km.axis = km
 sq.km.chart.date.axis = Datum
+
+module.winfo = WINFO
+module.minfo = MINFO
+module.fixanalysis = Fixierungsanalyse
+module.new_map = Neue Karte
+module.new_chart = Neues Diagramm
+
+load_diameter = Geschiebedurchmesser
+bed_diameter = Sohldurchmesser
+
+area.label.template = Fl\u00e4che = %s m\u00b3
+
--- a/flys-artifacts/src/main/resources/messages_en.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-artifacts/src/main/resources/messages_en.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,6 @@
+false=Nein
+true=Ja
+
 state.winfo.river = River
 state.winfo.calculation_mode = Calculation Mode
 state.winfo.location_distance = Location or distance selection
@@ -27,16 +30,31 @@
 state.fix.analysis.referenceperiod = Reference period
 state.fix.analysis.analysisperiods = Analysis period
 state.fix.analysis.function = Function
-state.fix.analysis.preprocessing = Preprocessing
+state.fix.analysis.preprocessing = Outliers
 state.fix.preprocess=preprocess
+state.fix.vollmer.function=Function
+state.fix.vollmer.preprocessing = Outliers
+state.fix.vollmer.qa = Input for W/Q data
 
 state.minfo.river = River
 state.minfo.calculation_mode = Calculation Mode
 state.minfo.distance_only = Range selection
 state.minfo.dischargestate = Selection of discharge state and channel
 state.minfo.sq.location=Location
-state.minfo.sq.periods=Periods
+state.minfo.sq.period=Periods
 state.minfo.sq.outliers=Outliers
+state.minfo.bed.year_epoch=Year/Epoch
+state.minfo.bed.difference_select=Differences
+state.minfo.year=Year
+state.minfo.epoch=Epoch
+state.minfo.bed.location = Location/Distance
+state.minfo.bed.periods = Periods
+state.minfo.bed.char_diameter = Characteristic Diameter
+state.minfo.soundings = Choose Soundings
+
+year=Year
+epoch=Epoch
+soundings = Soundings / Epochs
 
 historical.mode.w = Waterlevel Analyse
 historical.mode.q = Discharge Analyse
@@ -50,16 +68,32 @@
 calc.historical.discharge.curve = Historical Discharge Curve
 calc.reference.curve = Reference Curve
 calc.fixation.default = Fixation
-calc.fixation.volmer = Balanced Waterlevel
+calc.fixation.vollmer = Balanced Waterlevel
 calc.bed.middle = Middle Bed Height
 calc.bed.diff = Bed Height Difference
 calc.bed.quality = Bed Quality
 calc.sediment.load = Sediment Load
 calc.flow.velocity = Flow Velocity
 calc.sq.relation = Load Discharge Relation
+calc.bed.d90 = D90
+calc.bed.d84 = D84
+calc.bed.d80 = D80
+calc.bed.d75 = D75
+calc.bed.d70 = D70
+calc.bed.d60 = D60
+calc.bed.d50 = D50
+calc.bed.d40 = D40
+calc.bed.d30 = D30
+calc.bed.d25 = D25
+calc.bed.d20 = D20
+calc.bed.d16 = D16
+calc.bed.d10 = D10
+calc.bed.dmin = Dmin
+calc.bed.dmax = Dmax
+calc.bed.dmid = Dmid
 
 calculation.analysis = Fixinganalysis
-calculation.volmer = relocated Waterlevel Calculation
+calculation.vollmer = relocated Waterlevel Calculation
 
 state.chart.river = River
 state.chart.type = Charttype
@@ -86,8 +120,8 @@
 river = River
 calculation_mode = Calculation Mode
 ld_locations = Location(s)
-main.channel = Main channel
-total.channel = Total channel
+main_channel = Main channel
+total_channel = Total channel
 
 chart.cross_section.title = Cross Section for river {0}
 chart.cross_section.subtitle = {0}-km: {1,number,#.###}
@@ -126,8 +160,16 @@
 chart.reference.curve.title = Reference Curve
 chart.reference.curve.subtitle = {0}
 
+chart.fixings.analysis.title = Longitudinal section at km {0}
+chart.fixings.wq.subtitle=River: {0}; Range: {1,date,short} to {2,date,short}; Reference period: {3,date,short} to {4,date,short}
+chart.fixings.wq.subtitle1={0,date,short} to {1,date,short}
+
+chart.fixings.derivedcurve.title = Derived curve at km {0}
+chart.fixings.deltawt.title = Differences from fitted curve at km {0}
+chart.fixings.wq.title = Fixings Analysis at km {0}
+
 chart.reference.curve.x.axis.in.cm = Reference Gauge(s) [cm]
-chart.reference.curve.x.axis.in.m = Reference Station(s) [NN + m]
+chart.reference.curve.x.axis.in.m = Reference Station [NN + m]
 chart.reference.curve.y.axis.in.cm = Target Gauge(s) [cm]
 chart.reference.curve.y.axis.in.m = Target Station(s) [NN + m] 
 
@@ -138,6 +180,19 @@
 chart.w_differences.yaxis.label = m
 chart.w_differences.yaxis.second.label = W [NN + m]
 
+chart.bedquality.title=Bed Longitudinal Section
+chart.bedquality.xaxis.label=River-Km
+chart.bedquality.yaxis.label=Diameter [m]
+chart.bedquality.yaxis.label.porosity=Porosity [%]
+chart.bedquality.yaxis.label.density=Density [t/m\u00b3]
+
+chart.bedheight_middle.section.title=Middle Bed Height
+chart.bedheight_middle.section.yaxis.label=middle Bed Height [mm a NN]
+
+chart.flow_velocity.section.title=Geschwindigkeit- und Schubspannung
+chart.flow_velocity.section.yaxis.label=Speed v [m/s]
+chart.flow_velocity.section.yaxis.second.label=Schubspannung Tau [N]
+
 chart.sq_relation.xaxis.label = Discharge [m\u00b3/s]
 chart.sq_relation.yaxis.label = Transport [kg/s]
 chart.sq_relation_a.title = Feinkornanteil
@@ -149,6 +204,8 @@
 facet.sq_relation.curve = Potenziell (Geschiebedaten)
 facet.sq_relation.measurements = Geschiebedaten
 facet.sq_relation.outliers = Ausrei\u00dfer Durchgang {0}
+facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
+facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
 facet.longitudinal_section.annotations = POIs
 facet.discharge_curves.mainvalues.q = Q (main values)
@@ -158,6 +215,34 @@
 facet.flow_velocity.tauchannel = TAU Mainchannel at {0}
 facet.bedheight_middle.single = Bed Height {0,number,####}
 facet.bedheight_middle.epoch = Bed Height Epoch {0,number,####} - {1,number,####}
+facet.bedquality.bed.porosity.toplayer = Porosity ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.porosity.sublayer = Porosity ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.toplayer = Density ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.density.sublayer = Density ({0,date} - {1,date}) ({2})
+facet.bedquality.bed.diameter.toplayer = {0}_Bed ({1,date} - {2,date}) ({3})
+facet.bedquality.bed.diameter.sublayer = {0}_Bed ({1,date} - {2,date}) ({3})
+facet.bedquality.bedload.diameter = {0}_Bedload
+bedquality.toplayer = 0.0m - 0.3m
+bedquality.sublayer = 0.1m - 0.5m
+facet.bedheight.diff.year = Bedheight Difference {0}
+facet.bedheight.diff.morph = Morphologic Width {0}
+facet.bedheight.diff.height1 = Original Height Minuend {0}
+facet.bedheight.diff.height2 = Original Height Subtrahend {0}
+facet.bedheight.diff.absolute = Bedheight Difference/Year {0}
+facet.bedheight.diff.epoch = Bedheight Difference {0}
+
+chart.beddifference.height.title = Bedheight Difference
+chart.beddifference.height.xaxis.label = River-Km [km]
+chart.beddifference.height.yaxis.label = Difference [cm/year]
+chart.beddifference.epoch.title = Bedheight Difference
+chart.beddifference.xaxis.label = River-Km [km]
+chart.beddifference.yaxis.label.diff = Difference [m]
+chart.beddifference.yaxis.label.height = Absolute Height [m]
+chart.beddifference.year.title = Bedheight Difference
+chart.beddifference.xaxis.label = River-Km [km]
+chart.beddifference.yaxis.label.diff = Difference [m]
+chart.beddifference.yaxis.label.morph = Morphologic Width [m]
+chart.beddifference.yaxis.label.heights = Absolute Height [m]
 
 export.waterlevel.csv.header.km = River-Km
 export.waterlevel.csv.header.w = W [NN + m]
@@ -237,6 +322,14 @@
 export.sqrelation.csv.header.c.duan = C (DUAN)
 export.sqrelation.csv.header.c.ferguson = C (FERGUSON)
 export.sqrelation.csv.header.variance = Standard variance
+export.minfo.bedquality.km = km
+export.minfo.bedquality.density_cap = Density Toplayer
+export.minfo.bedquality.density_sub = Density Sublayer
+export.minfo.bedquality.porosity_cap = Porosity Toplayer
+export.minfo.bedquality.porosity_sub = Porosity Sublayer
+export.minfo.bedquality.bedload = Bedload Diameter
+export.minfo.bedquality.bed_cap = Bed Diameter Toplayer
+export.minfo.bedquality.bed_sub = Bed Diameter Sublayer
 
 floodmap.wmsbackground = Background Map
 floodmap.riveraxis = River Axis
@@ -329,19 +422,39 @@
 help.winfo.historical.discharge.mode=https://flys-intern.intevation.de/Flys-3.0/OnlineHilfe/WINFO#Auswahl_der_Analyseart
 
 fix.reference.period=Reference period
-fix.reference.period.events=Reference period events
+fix.reference.period.event=Reference event
+fix.reference.period.event.short=R
+fix.analysis.short=A
 fix.analysis.periods=Analysis periods
 fix.derivative=Derivative
 fix.outlier=Outlier
-fix.analysis=Analysis
+fix.analysis=Analysis event
 fix.deviation=Standard deviation
 fix.reference.deviation=Reference deviation
+fix.vollmer.wq.curve=W/Q
+fix.vollmer.wq.outliers=Outliers
+fix.vollmer.wq.events=Events
+qsectors=Discharge Sectors
 
-chart.fix.deltawt.title=Difference from compensating curve
-chart.fix.deltawt.subtitle=Water: {0}; Period:  {1,date,short} to {2,date,short}
+chart.fix.deltawt.title=Difference from compensating curve at kilometer {0}
+chart.fix.deltawt.subtitle=Water: {0}; Period:  {1,date,short} to {2,date,short}; Reference period: {3,date,short} bis {4,date,short}
 chart.fix.deltawt.xaxis.label=Date
 chart.fix.deltawt.yaxis.label=\u0394 W(t) [cm]
 
+chart.fix.wq.subtitle=Water: {0}; Period: {1,date,short} to {2,date,short}
+
+chart.fixings.longitudinalsection.title=Longitudinal section
+
+export.fixings.deltawt.csv.header.km=km
+export.fixings.deltawt.csv.header.deltaw=\u0394 W [cm]
+export.fixings.deltawt.csv.header.q=Discharge [m\u00b3/s]
+export.fixings.deltawt.csv.header.w=Waterlevel [m]
+export.fixings.deltawt.csv.header.t=Date
+export.fixings.deltawt.csv.t.format=yyyy/MM/dd
+export.fixings.deltawt.csv.header.time.range=State
+export.fixings.deltawt.csv.reference=R
+export.fixings.deltawt.csv.analysis=A{0,number,integer}
+
 fix.missing.river=Missing river
 fix.missing.from=Missing start km
 fix.missing.to=Missing end km
@@ -376,3 +489,13 @@
 sq.km.chart.km.axis = km
 sq.km.chart.date.axis = Date
 
+module.winfo = WINFO
+module.minfo = MINFO
+module.fixanalysis = Fix Analysis
+module.new_map = New Map
+module.new_chart = New Chart
+
+load_diameter = Bedload Diameter
+bed_diameter = Bed Diameter
+
+area.label.template = Area = %s m\u00b3
--- a/flys-backend/ChangeLog	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/ChangeLog	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,513 @@
+2012-09-28  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/schema/postgresql-spatial.sql,
+	  doc/schema/oracle-spatial.sql: Changed the type of date columns to
+	  VARCHAR. This is a quick fix to solve the concatination problem in
+	  Oracle and PostgreSQL. Both aren't able to concatinate null values.
+	  So, null values are not valid for those columns. Users can now decide
+	  to fill these columns with correct values or an empty string.
+
+	* src/main/java/de/intevation/flys/utils/DgmSqlConverter.java: Set
+	  year_from and year_to values to an empty string if no correct value is
+	  specified.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	For issue862/1, fix parsing of year field of bed height csvs,
+	which sometimes contain non-year character.
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java:
+	  Extend RE to parse year field of Bed Height data csv.
+
+2012-09-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/RiverAxis.java:
+	  Added new method to query a special kind of river axes.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	Backend-part for fix of issue863.
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightEpochParser.java:
+	  Handle missing data points.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/ImportBedHeightEpoch.java:
+	  Doc.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightSingleParser.java:
+	  Removed debug output.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightSingleParser.java:
+	  Handle csv lines with just the km set ("gaps").
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightEpochParser.java:
+	  Added TODO, as more changes towards fix for issue863 are necessary.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java,
+	  src/main/java/de/intevation/flys/importer/ImportBedHeightSingleValue.java:
+	  Cosmetics, docs.
+
+2012-09-27  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	Towards fix for issue863 (data gaps in bed height single values).
+
+	* doc/schema/postgresql-minfo.sql,
+	  doc/schema/oracle-minfo.sql:
+	  Drop "NOT NULL" constraints on some single bed height value columns.
+
+2012-09-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/BedHeightSingle.java:
+	  Replaced labeled continue by a simple break.
+
+	* src/main/java/de/intevation/flys/utils/DgmSqlConverter.java,
+	  src/main/java/de/intevation/flys/importer/ImportElevationModel.java:
+	  Removed trailing whitespace.
+
+2012-09-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/schema/postgresql-spatial.sql:
+
+	* doc/schema/import-dems.sql: Added more information to fullfil the schema
+	  for dems.
+
+	* src/main/java/de/intevation/flys/utils/DgmSqlConverter.java: New converter
+	  for CSV files with DGM information; results in a SQL file with INSERT
+	  statements.
+
+	* pom.xml: Added dependency to OpenCSV for reading CSV files.
+
+2012-09-24  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/importer.py: Fixed method name for ERROR log
+	  messages.
+
+	* doc/schema/postgresql-spatial.sql: Set geometry dim to '3' instead of
+	  '4'.
+
+2012-09-24  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/ImportBedHeightEpoch.java,
+	  src/main/java/de/intevation/flys/importer/ImportElevationModel.java:
+	  Some minor bugfixes for MINFO import.
+
+2012-09-24  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/schema/postgresql-spatial.sql: Adapted schema; added missing
+	  relations.
+
+	* doc/schema/postgresql-drop-spatial.sql: SQL statements to drop an
+	  existing FLYS postgresql schema.
+
+2012-09-21	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/River.java,
+	  src/main/java/de/intevation/flys/model/Gauge.java:
+	  Remove fetchInfoURL methods. The info url will be generated in the
+	  client.
+
+2012-09-22	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/schema/postgresql.sql, doc/schema/oracle.sql:
+	  Addes column 'official_number' to rivers table.
+	  This should contain the 'Bundeswasserstrassen Identnummer'.
+
+	* src/main/java/de/intevation/flys/model/River.java:
+	  Added new column to Hibernate model.
+
+2012-09-21	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/River.java,
+	  src/main/java/de/intevation/flys/model/Gauge.java:
+	  Rename getInfoURL methods to fetchInfoURL until the values are fetched
+	  from the db to statisfy hibernate.
+
+2012-09-21	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/River.java,
+	  src/main/java/de/intevation/flys/model/Gauge.java:
+	  Add new methods to return a HTTP URL for additional information about the
+	  river or gauge.
+
+2012-09-19  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/ImportSedimentDensity.java,
+	  src/main/java/de/intevation/flys/importer/ImportWaterlevelDifference.java,
+	  src/main/java/de/intevation/flys/importer/ImportBedHeightSingle.java,
+	  src/main/java/de/intevation/flys/importer/ImportSedimentYield.java,
+	  src/main/java/de/intevation/flys/importer/ImportBedHeightEpoch.java,
+	  src/main/java/de/intevation/flys/importer/ImportWaterlevel.java,
+	  src/main/java/de/intevation/flys/importer/ImportFlowVelocityMeasurement.java,
+	  src/main/java/de/intevation/flys/importer/ImportMorphWidth.java,
+	  src/main/java/de/intevation/flys/importer/ImportFlowVelocityModel.java,
+	  src/main/java/de/intevation/flys/importer/ImportSQRelation.java: Store
+	  values into database only if its peer has been successfully stored,
+	  otherwise skip values.
+
+2012-09-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	 * src/main/java/de/intevation/flys/importer/ImportSedimentDensity.java,
+	   src/main/java/de/intevation/flys/importer/parsers/SedimentDensityParser.java:
+	   Removed trailing whitespace.
+
+2012-09-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/BedHeightType.java: Accept
+	  "Querprofil" as valid BedHeightType.
+
+	* src/main/java/de/intevation/flys/importer/parsers/SedimentYieldParser.java:
+	  Added missing GrainFraction.TOTAL type to parser.
+
+2012-09-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/ImportSedimentDensity.java,
+	  src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/SedimentDensityParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/WaterlevelDifferencesParser.java:
+	  Some litte logging improvements and be more tolerant with exceptions.
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	Taggd RELEASE 2.9.1
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/BedHeightEpoch.java:
+	  Corrected broken loop to find epochs for river and km range.
+
+	* src/main/java/de/intevation/flys/model/BedHeightSingle.java:
+	  Corrected broken loop to find singles for river and km range.
+
+2012-09-12	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java:
+	  Made code more robust.
+
+2012-09-12	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/Config.java:
+	  Add system property 'flys.backend.importer.skip.default'
+	  which enables the switching of the skipping default.
+	  Very useful if you want only some sub systems by
+	  setting this to 'true' and the sub systems to 'false'.
+
+2012-09-12	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/schema/postgresql.sql: Indices on cross sections
+	  were created too early (before the referenced tables
+	  were created).
+
+2012-09-12	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/River.java:
+	  Add new method determineMinMaxQ to fetch the mimimum and maximum q values
+	  from the database.
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* postgresql-minfo.sql: Added missing tables.
+	* oracle-minfo.sql: Fixed small typos.
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* pom.xml: Java 1.6 -> 1.6
+
+	* src/main/java/de/intevation/flys/utils/StringUtil.java:
+	  Replaced german comment (with an ill encoded Umlaut).
+
+2012-09-10	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/Gauge.java:
+	  Remove obsolet method (#851).
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/Gauge.java:
+	  We need min/max Q, too.
+
+2012-09-10	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/MinMaxWQ.java,
+	  src/main/java/de/intevation/flys/model/Gauge.java:
+	  Add method fetchMinMaxWQ to Gauge. This mehtod returns a new MinMaxWQ
+	  instance that contains the fetched values for the gauge overview info.
+
+2012-09-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/Gauge.java:
+	  Moved some code over from flys-artifacts.
+
+2012-09-07  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged module as '2.9'.
+
+2012-09-07	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/Gauge.java:
+	  Rename getDurationCurveData to fetchDurationCurveData to satisfy
+	  hibernate.
+
+2012-09-06	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/Gauge.java:
+	  Move static getDurationCurveData method from flys-artifacts
+	  MainValuesFactory class to a instance method in Gauge class.
+
+2012-08-30  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	Attempt fix for issue821 (cross sections just till +/-500m).
+
+	* src/main/java/de/intevation/flys/model/CrossSectionLine.java:
+	  Set max value for cross sections to 2500 instead of 500.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/run_geo.sh: New run script for the python based geo importer.
+
+	* contrib/run_hydr_morph.sh: New run script for the java based importer
+	  for hydrological and morphological data.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/overview.tex: Fixed typo.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-geodaesie.tex,
+	  doc/documentation/de/importer-hydr-morph.tex: Corrected name of run
+	  scripts.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-geodaesie.tex,
+	  doc/documentation/de/importer-hydr-morph.tex,
+	  doc/documentation/de/importer-manual.tex: Bugfixes and new geo error
+	  description.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/importer.py: Fixed broken method call.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/overview.tex: Hint to root permissions.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/importer.py: Set 'path' attribute for each feature.
+
+	* contrib/shpimporter/axis.py: Also accept shapes with 'achse' in its name.
+
+	* doc/schema/oracle-spatial.sql: Added 'path' attribute to each db
+	  relation.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-geodaesie.tex: Bugfixes and added hint.
+
+	* doc/documentation/de/importer-manual.tex: Set document revision and
+	  date.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-hydr-morph.tex: Added manual line breaks.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-hydr-morph.tex: Fixed bug during PDF
+	  creation.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-hydr-morph.tex: Bugfixes.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/overview.tex: Improved description of database
+	  schema creation. Describe command to unpack importer tarball.
+
+2012-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-geodaesie.tex: Added further error message
+	  if no connection to Oracle database could be established.
+
+2012-08-29  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-geodaesie.tex: Documented install steps
+	  for Oracle Instantclient and python and gdal.
+
+2012-08-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-hydr-morph.tex: Describe Log4J
+	  configuration; some smaller bugfixes.
+
+2012-08-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/overview.tex: Added comment to directory structure
+	  of a river.
+
+	* doc/documentation/de/importer-hydr-morph.tex: Describe import of
+	  morphological files.
+
+2012-08-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/title.tex,
+	  doc/documentation/de/overview.tex,
+	  doc/documentation/de/importer-hydr-morph.tex,
+	  doc/documentation/de/importer-manual.tex: Smaller fixed and structural
+	  changes.
+
+2012-08-27  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/documentation/de/importer-hydr-morph.tex: Added documentation from
+	  README.
+
+2012-08-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Documented which hydrological files are taken into account.
+
+2012-08-26	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Documented the classification of the annotations.
+
+2012-08-26	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Documented the db credentials.
+
+2012-08-24	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Completed the error messages (Puh!)
+
+	* src/main/java/de/intevation/flys/importer/ImportBedHeightSingle.java,
+	  src/main/java/de/intevation/flys/importer/ImportWaterlevelDifference.java,
+	  src/main/java/de/intevation/flys/importer/ImportBedHeightEpoch.java,
+	  src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/BedHeightSingleParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/AnnotationsParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/MorphologicalWidthParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/SedimentYieldParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/AnnotationClassifier.java,
+	  src/main/java/de/intevation/flys/importer/parsers/WstParser.java,
+	  src/main/java/de/intevation/flys/importer/ImportSQRelation.java:
+	  Made error messages identifiable.
+
+2012-08-24  Ingo Weinzierl <ingo@intevation.de>
+
+	* doc/shapeimporter,
+	  doc/shapeimporter/documentation.txt: Removed. The documentation is now
+	  written in latex.
+
+	* doc/documentation,
+	  doc/documentation/de: New. The place where the german documentation is
+	  located.
+
+	* doc/documentation/de/title.tex,
+	  doc/documentation/de/importer-geodaesie.tex,
+	  doc/documentation/de/figures/bfg_logo.png,
+	  doc/documentation/de/figures/intevation-logo.pdf,
+	  doc/documentation/de/overview.tex,
+	  doc/documentation/de/importer-hydr-morph.tex,
+	  doc/documentation/de/importer-manual.tex: German documentation of the
+	  importer and shape importer.
+
+	* doc/documentation/de/Makefile: Makefile to generate the documentation.
+
+	* doc/documentation/de/README: Instructions to generate the documentation.
+
+2012-08-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Added warning messages. TODO: More warnings.
+
+	* src/main/java/de/intevation/flys/importer/parsers/PRFParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/StaFileParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/PegelGltParser.java,
+	  src/main/java/de/intevation/flys/importer/parsers/AtFileParser.java,
+	  src/main/java/de/intevation/flys/importer/ImportRiver.java:
+	  Made warnings identifiable.
+
+2012-08-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Added error messages.
+
+	* src/main/java/de/intevation/flys/importer/Importer.java,
+	  src/main/java/de/intevation/flys/importer/parsers/PRFParser.java
+	  src/main/java/de/intevation/flys/importer/parsers/HYKParser.java
+	  src/main/java/de/intevation/flys/importer/ImportRiver.java:
+	  Made errors identifiable.
+
+2012-08-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/README.txt: Documentation for the importer (german).
+	  TODO: db crendentials, warning & errors, annotation types.
+
+2012-08-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/run.sh: Moved 'SKIP_XXX' variables to the top of
+	  the script.
+
+2012-08-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/axis.py: Use log methods of shpimporter and
+	  removed print() calls.
+
+	* contrib/shpimporter/importer.py: Evaluate command line option 'dry_run'.
+	  Do not commit database transaction if it is activated.
+
+	* contrib/shpimporter/shpimporter.py: Added new command line option
+	  'dry_run' to supress database transactions.
+
+2012-08-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/shpimporter.py: Use OptionParse to read command line
+	  options. Now, it is no longer necessary to adjust user specific settings
+	  in python files. Users should adapt run.sh script for specific settings.
+
+	* contrib/shpimporter/catchments.py,
+	  contrib/shpimporter/boundaries.py,
+	  contrib/shpimporter/hws.py,
+	  contrib/shpimporter/importer.py,
+	  contrib/shpimporter/uesg.py,
+	  contrib/shpimporter/axis.py,
+	  contrib/shpimporter/km.py,
+	  contrib/shpimporter/floodplains.py,
+	  contrib/shpimporter/lines.py,
+	  contrib/shpimporter/gauges.py,
+	  contrib/shpimporter/buildings.py,
+	  contrib/shpimporter/fixpoints.py,
+	  contrib/shpimporter/crosssectiontracks.py: Added new method getName().
+
+	* contrib/shpimporter/utils.py: Use shpimporter functions to print debug
+	  messages.
+
+	* contrib/shpimporter/run.sh: New shell script to run the shape importer
+	  with a default configuration.
+
+2012-08-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/model/FastAnnotations.java:
+	  Added toString() to Annotation.
+
+2012-07-27  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged module as '2.8.1'.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfstellre@intevation.de>
+
+	* doc/schema/postgresql.sql, doc/schema/oracle.sql:
+	  Adjusted the official_lines views to include wst column pos.
+
+2012-07-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* Tagged module as '2.8'.
+
 2012-07-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/model/Gauge.java,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/contrib/run_geo.sh	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# Required
+RIVER_PATH="/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar"
+RIVER_ID=1
+TARGET_SRS=31467
+HOST=localhost
+USER=flys28
+PASS=flys28
+
+# Optional
+VERBOSE=1
+SKIP_AXIS=0
+SKIP_KMS=0
+SKIP_CROSSSECTIONS=0
+SKIP_LINES=0
+SKIP_FIXPOINTS=0
+SKIP_BUILDINGS=0
+SKIP_FLOODPLAINS=0
+SKIP_HYDR_BOUNDARIES=0
+SKIP_HWS=0
+SKIP_GAUGE_LOCATION=0
+SKIP_CATCHMENTS=0
+SKIP_UESG=0
+
+
+DIR=`dirname $0`
+DIR=`readlink -f "$DIR"`
+
+exec python $DIR/shpimporter/shpimporter.py \
+    --directory $RIVER_PATH \
+    --river_id $RIVER_ID \
+    --target_srs $TARGET_SRS \
+    --host $HOST \
+    --user $USER \
+    --password $PASS \
+    --verbose $VERBOSE \
+    --skip_axis $SKIP_AXIS \
+    --skip_kms $SKIP_KMS \
+    --skip_crosssections $SKIP_CROSSSECTIONS \
+    --skip_lines $SKIP_LINES \
+    --skip_fixpoints $SKIP_FIXPOINTS \
+    --skip_buildings $SKIP_BUILDINGS \
+    --skip_floodplains $SKIP_FLOODPLAINS \
+    --skip_hydr_boundaries $SKIP_HYDR_BOUNDARIES \
+    --skip_hws $SKIP_HWS \
+    --skip_gauge_locations $SKIP_GAUGE_LOCATION \
+    --skip_catchments $SKIP_CATCHMENTS \
+    --skip_uesgs $SKIP_UESG
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/contrib/run_hydr_morph.sh	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,103 @@
+#!/bin/bash
+
+######################### CONFIG OPTIONS ############################
+INFO_GEW="/vol1/projects/Geospatial/flys-3.0/testdaten/saar.gew"
+BACKEND_USER="flys28"
+BACKEND_PASS="flys28"
+BACKEND_HOST="czech-republic.atlas.intevation.de"
+BACKEND_PORT="1521"
+BACKEND_NAME="XE"
+LOG4J_CONFIG="conf/log4j.properties"
+#####################################################################
+
+
+########################## Oracle Settings ##########################
+BACKEND_DB_PREFIX="jdbc:oracle:thin:@"
+BACKEND_DB_DRIVER="oracle.jdbc.OracleDriver"
+BACKEND_DB_DIALECT="org.hibernate.dialect.OracleDialect"
+BACKEND_URL=$BACKEND_DB_PREFIX//$BACKEND_HOST:$BACKEND_PORT/$BACKEND_NAME
+#####################################################################
+
+
+######################## Custom Importer Settings ###################
+IMPORTER_DRY_RUN=false
+IMPORTER_MAINVALUE_TYPES=QWTD
+IMPORTER_ANNOTATION_TYPES="conf/annotation-types.xml"
+
+IMPORTER_SKIP_GAUGES=false
+IMPORTER_SKIP_ANNOTATIONS=false
+IMPORTER_SKIP_WST=false
+IMPORTER_SKIP_PRFS=false
+IMPORTER_SKIP_HYKS=false
+IMPORTER_SKIP_EXTRA_WST=false
+IMPORTER_SKIP_FIXATIONS=false
+IMPORTER_SKIP_OFFICIAL_LINES=false
+IMPORTER_SKIP_FLOOD_WATER=false
+IMPORTER_SKIP_FLOOD_PROTECTION=false
+
+IMPORTER_SKIP_BED_HEIGHT_SINGLE=false
+IMPORTER_SKIP_BED_HEIGHT_EPOCH=false
+IMPORTER_SKIP_SEDIMENT_DENSITY=false
+IMPORTER_SKIP_MORPHOLOGICAL_WIDTH=false
+IMPORTER_SKIP_FLOW_VELOCITY=false
+IMPORTER_SKIP_SEDIMENT_YIELD=false
+IMPORTER_SKIP_WATERLEVELS=false
+IMPORTER_SKIP_WATERLEVEL_DIFFERENCES=false
+IMPORTER_SKIP_SQ_RELATION=false
+#####################################################################
+
+#MIN_MEMORY="8192m"
+MIN_MEMORY="1024m"
+
+
+########################## Importer Settings ########################
+APP="de.intevation.flys.importer.Importer"
+DIR=`dirname $0`
+DIR=`readlink -f "$DIR/.."`
+#####################################################################
+
+
+########################## Collect required libraries ###############
+CLASSPATH=
+for l in `find "$DIR/lib" -name \*.jar -print`; do
+   CLASSPATH=$CLASSPATH:$l
+done
+
+export CLASSPATH
+#####################################################################
+
+
+######################### Run Importer ##############################
+exec java \
+    -Xmx$MIN_MEMORY \
+    -server \
+    -Dlog4j.configuration=file://`readlink -f $LOG4J_CONFIG` \
+    -Dflys.backend.importer.infogew.file=$INFO_GEW \
+    -Dflys.backend.main.value.types=$IMPORTER_MAINVALUE_TYPES \
+    -Dflys.backend.importer.annotation.types=$IMPORTER_ANNOTATION_TYPES \
+    -Dflys.backend.importer.dry.run=$IMPORTER_DRY_RUN \
+    -Dflys.backend.importer.skip.gauges=$IMPORTER_SKIP_GAUGES \
+    -Dflys.backend.importer.skip.annotations=$IMPORTER_SKIP_ANNOTATIONS \
+    -Dflys.backend.importer.skip.prfs=$IMPORTER_SKIP_PRFS \
+    -Dflys.backend.importer.skip.hyks=$IMPORTER_SKIP_HYKS \
+    -Dflys.backend.importer.skip.wst=$IMPORTER_SKIP_WST \
+    -Dflys.backend.importer.skip.extra.wsts=$IMPORTER_SKIP_EXTRA_WST \
+    -Dflys.backend.importer.skip.fixations=$IMPORTER_SKIP_FIXATIONS \
+    -Dflys.backend.importer.skip.official.lines=$IMPORTER_SKIP_OFFICIAL_LINES \
+    -Dflys.backend.importer.skip.flood.water=$IMPORTER_SKIP_FLOOD_WATER \
+    -Dflys.backend.importer.skip.flood.protection=$IMPORTER_SKIP_FLOOD_PROTECTION \
+    -Dflys.backend.importer.skip.bed.height.single=$IMPORTER_SKIP_BED_HEIGHT_SINGLE \
+    -Dflys.backend.importer.skip.bed.height.epoch=$IMPORTER_SKIP_BED_HEIGHT_EPOCH \
+    -Dflys.backend.importer.skip.sediment.density=$IMPORTER_SKIP_SEDIMENT_DENSITY \
+    -Dflys.backend.importer.skip.morphological.width=$IMPORTER_SKIP_MORPHOLOGICAL_WIDTH \
+    -Dflys.backend.importer.skip.flow.velocity=$IMPORTER_SKIP_FLOW_VELOCITY \
+    -Dflys.backend.importer.skip.sediment.yield=$IMPORTER_SKIP_SEDIMENT_YIELD \
+    -Dflys.backend.importer.skip.waterlevels=$IMPORTER_SKIP_WATERLEVELS \
+    -Dflys.backend.importer.skip.waterlevel.differences=$IMPORTER_SKIP_WATERLEVEL_DIFFERENCES \
+    -Dflys.backend.importer.skip.sq.relation=$IMPORTER_SKIP_SQ_RELATION \
+    -Dflys.backend.user=$BACKEND_USER \
+    -Dflys.backend.password=$BACKEND_PASS \
+    -Dflys.backend.url=$BACKEND_URL \
+    -Dflys.backend.driver=$BACKEND_DB_DRIVER \
+    -Dflys.backend.dialect=$BACKEND_DB_DIALECT \
+     $APP
--- a/flys-backend/contrib/shpimporter/axis.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/axis.py	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,9 @@
 import ogr
 
 from importer import Importer
+import shpimporter
 
+NAME="Axis"
 TABLE_NAME="river_axes"
 PATH="Geodaesie/Flussachse+km"
 
@@ -16,12 +18,16 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 2
 
 
     def isShapeRelevant(self, name, path):
-        return name == "achse"
+        return name == "achse" or name.find("achse") >= 0
 
 
     def createNewFeature(self, featureDef, feat, **args):
--- a/flys-backend/contrib/shpimporter/boundaries.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/boundaries.py	Fri Sep 28 12:15:40 2012 +0200
@@ -5,6 +5,7 @@
 TABLE_NAME="hydr_boundaries"
 TABLE_NAME_POLY="hydr_boundaries_poly"
 PATH="Hydrologie/Hydr.Grenzen/Linien"
+NAME="Hydr. Boundaries"
 
 
 class HydrBoundary(Importer):
@@ -17,6 +18,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 2
 
@@ -58,6 +63,10 @@
         return TABLE_NAME_POLY
 
 
+    def getName(self):
+        return "%s (Polygons)" % NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 3 or geomType == 6
 
--- a/flys-backend/contrib/shpimporter/buildings.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/buildings.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="buildings"
 PATH="Geodaesie/Bauwerke"
+NAME="Buildings"
 
 
 class Building(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 2
 
--- a/flys-backend/contrib/shpimporter/catchments.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/catchments.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="catchment"
 PATH="Hydrologie/Einzugsgebiet"
+NAME="Catchments"
 
 
 class Catchment(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 3 or geomType == 6
 
--- a/flys-backend/contrib/shpimporter/crosssectiontracks.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/crosssectiontracks.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="cross_section_tracks"
 PATH="Geodaesie/Querprofile"
+NAME="Crosssections"
 
 
 class CrosssectionTrack(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 2
 
--- a/flys-backend/contrib/shpimporter/fixpoints.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/fixpoints.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="fixpoints"
 PATH="Geodaesie/Festpunkte"
+NAME="Fixpoints"
 
 
 class Fixpoint(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 1
 
--- a/flys-backend/contrib/shpimporter/floodplains.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/floodplains.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="floodplain"
 PATH="Hydrologie/Hydr.Grenzen"
+NAME="Floodplains"
 
 
 class Floodplain(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 3 or geomType == 6
 
--- a/flys-backend/contrib/shpimporter/gauges.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/gauges.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="gauge_location"
 PATH="Hydrologie/Streckendaten"
+NAME="Gauge locations"
 
 
 class GaugeLocation(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 1
 
--- a/flys-backend/contrib/shpimporter/hws.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/hws.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="hws"
 PATH="Hydrologie/HW-Schutzanlagen"
+NAME="HWS"
 
 
 class HWS(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 2
 
--- a/flys-backend/contrib/shpimporter/importer.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/importer.py	Fri Sep 28 12:15:40 2012 +0200
@@ -1,12 +1,14 @@
 import ogr, osr
+import shpimporter
 
 class Importer:
 
-    def __init__(self, dbconn, river_id, dest_srs):
-        self.dbconn   = dbconn
-        self.river_id = river_id
+    def __init__(self, config):
+        self.config = config
+        self.dbconn   = 'OCI:%s/%s@%s' % (config.user, config.password, config.host)
+        self.river_id = config.river_id
         self.dest_srs = osr.SpatialReference()
-        self.dest_srs.ImportFromEPSG(dest_srs)
+        self.dest_srs.ImportFromEPSG(config.target_srs)
 
 
     def getKind(self, path):
@@ -21,6 +23,10 @@
         raise NotImplementedError("Importer.getTablename is abstract!")
 
 
+    def getName(self):
+        raise NotImplementedError("Importer.getTablename is abstract!")
+
+
     def IsFieldSet(self, feat, name):
         try:
             isset = feat.GetField(name)
@@ -42,22 +48,21 @@
 
 
     def walkOverShapes(self, shape):
-        print "---"
         (name, path) = shape
         if not self.isShapeRelevant(name, path):
-            print "Skip shapefile '%s'" % name
+            shpimporter.INFO("Skip shapefile '%s'" % path)
             return
 
         shp = ogr.Open(shape[1])
         if shp is None:
-            print "Shapefile '%s' could not be opened!" % path
+            shpimporter.ERROR("Shapefile '%s' could not be opened!" % path)
             return
 
-        print "Opened shapefile '%s'" % path
+        shpimporter.INFO("Processing shapefile '%s'" % path)
         srcLayer = shp.GetLayerByName(name)
 
         if srcLayer is None:
-            print "Layer '%s' was not found!" % name
+            shpimporter.ERROR("Layer '%s' was not found!" % name)
             return
 
         return self.shape2Database(srcLayer, name, path)
@@ -68,7 +73,7 @@
         src_srs  = geometry.GetSpatialReference()
 
         if src_srs is None:
-            print "Error: No source SRS given! No transformation possible!"
+            shpimporter.ERROR("No source SRS given! No transformation possible!")
             return feat
 
         transformer = osr.CoordinateTransformation(src_srs, self.dest_srs)
@@ -82,15 +87,15 @@
         destLayer = table.GetLayerByName(self.getTablename())
 
         if srcLayer is None:
-            print "Shapefile is None!"
+            shpimporter.ERROR("Shapefile is None!")
             return -1
 
         if destLayer is None:
-            print "No destination layer given!"
+            shpimporter.ERROR("No destination layer given!")
             return -1
 
         count = srcLayer.GetFeatureCount()
-        print "Try to add %i features to database." % count
+        shpimporter.DEBUG("Try to add %i features to database." % count)
 
         srcLayer.ResetReading()
 
@@ -115,10 +120,11 @@
                                                 path=path)
 
                 if newFeat is not None:
+		    newFeat.SetField("path", path)
                     newFeat = self.transform(newFeat)
                     res = destLayer.CreateFeature(newFeat)
                     if res is None or res > 0:
-                        print "Error while inserting feature: %r" % res
+                        shpimporter.ERROR("Unable to insert feature: %r" % res)
                     else:
                         success = success + 1
                 else:
@@ -126,14 +132,16 @@
             else:
                 unsupported = unsupported + 1
 
-        print "Inserted %i features" % success
-        print "Failed to create %i features" % creationFailed
-        print "Found %i unsupported features" % unsupported
+        shpimporter.INFO("Inserted %i features" % success)
+        shpimporter.INFO("Failed to create %i features" % creationFailed)
+        shpimporter.INFO("Found %i unsupported features" % unsupported)
 
         try:
+            if self.config.dry_run > 0:
+                return geomType
             destLayer.CommitTransaction()
         except e:
-            print "Exception while committing transaction."
+            shpimporter.ERROR("Exception while committing transaction.")
 
         return geomType
 
--- a/flys-backend/contrib/shpimporter/km.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/km.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="river_axes_km"
 PATH="Geodaesie/Flussachse+km"
+NAME="KMS"
 
 
 class KM(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 1
 
--- a/flys-backend/contrib/shpimporter/lines.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/lines.py	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 TABLE_NAME="lines"
 PATH="Geodaesie/Linien"
+NAME="Lines"
 
 
 class Line(Importer):
@@ -16,6 +17,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         return geomType == 2 or geomType == -2147483646
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/contrib/shpimporter/run.sh	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# Required
+RIVER_PATH="/path/to/rivers/river"
+RIVER_ID=1
+TARGET_SRS=31466
+HOST=localhost
+USER=the_user
+PASS=the_pass
+
+# Optional
+VERBOSE=1
+SKIP_AXIS=0
+SKIP_KMS=0
+SKIP_CROSSSECTIONS=0
+SKIP_LINES=0
+SKIP_FIXPOINTS=0
+SKIP_BUILDINGS=0
+SKIP_FLOODPLAINS=0
+SKIP_HYDR_BOUNDARIES=0
+SKIP_HWS=0
+SKIP_GAUGE_LOCATION=0
+SKIP_CATCHMENTS=0
+SKIP_UESG=0
+
+exec python shpimporter.py \
+    --directory $RIVER_PATH \
+    --river_id $RIVER_ID \
+    --target_srs $TARGET_SRS \
+    --host $HOST \
+    --user $USER \
+    --password $PASS \
+    --verbose $VERBOSE \
+    --skip_axis $SKIP_AXIS \
+    --skip_kms $SKIP_KMS \
+    --skip_crosssections $SKIP_CROSSSECTIONS \
+    --skip_lines $SKIP_LINES \
+    --skip_fixpoints $SKIP_FIXPOINTS \
+    --skip_buildings $SKIP_BUILDINGS \
+    --skip_floodplains $SKIP_FLOODPLAINS \
+    --skip_hydr_boundaries $SKIP_HYDR_BOUNDARIES \
+    --skip_hws $SKIP_HWS \
+    --skip_gauge_locations $SKIP_GAUGE_LOCATION \
+    --skip_catchments $SKIP_CATCHMENTS \
+    --skip_uesgs $SKIP_UESG
+
--- a/flys-backend/contrib/shpimporter/shpimporter.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/shpimporter.py	Fri Sep 28 12:15:40 2012 +0200
@@ -1,6 +1,7 @@
 import ogr
 
-import utils
+import utils, optparse
+
 from uesg  import UESG
 from axis  import Axis
 from km    import KM
@@ -14,47 +15,157 @@
 from gauges import GaugeLocation
 from catchments import Catchment
 
-DBCONN='OCI:user/pass@host'
-PATH='/path/to/Gewaesser/Elbe'
-RIVER_ID=the_river_id
-DEST_SRS=31467
+
+VERBOSE_DEBUG=2
+VERBOSE_INFO=1
 
 
-def getImporters():
+def DEBUG(msg):
+    config = getConfig()
+    if config.verbose >= VERBOSE_DEBUG:
+        print "DEBUG: %s" % msg
+
+def INFO(msg):
+    config = getConfig()
+    if config.verbose >= VERBOSE_INFO:
+        print "INFO: %s" % msg
+
+def ERROR(msg):
+    config = getConfig()
+    print "ERROR: %s" % msg
+
+
+def getImporters(config):
     return [
-        Axis(DBCONN, RIVER_ID, DEST_SRS),
-        KM(DBCONN, RIVER_ID, DEST_SRS),
-        CrosssectionTrack(DBCONN, RIVER_ID, DEST_SRS),
-        Line(DBCONN, RIVER_ID, DEST_SRS),
-        Fixpoint(DBCONN, RIVER_ID, DEST_SRS),
-        Building(DBCONN, RIVER_ID, DEST_SRS),
-        Floodplain(DBCONN, RIVER_ID, DEST_SRS),
-        HydrBoundary(DBCONN, RIVER_ID, DEST_SRS),
-        HydrBoundaryPoly(DBCONN, RIVER_ID, DEST_SRS),
-        HWS(DBCONN, RIVER_ID, DEST_SRS),
-        GaugeLocation(DBCONN, RIVER_ID, DEST_SRS),
-        Catchment(DBCONN, RIVER_ID, DEST_SRS),
-        UESG(DBCONN, RIVER_ID, DEST_SRS)
+        Axis(config),
+        KM(config),
+        CrosssectionTrack(config),
+        Line(config),
+        Fixpoint(config),
+        Building(config),
+        Floodplain(config),
+        HydrBoundary(config),
+        HydrBoundaryPoly(config),
+        HWS(config),
+        GaugeLocation(config),
+        Catchment(config),
+        UESG(config)
         ]
 
 
-if __name__ == '__main__':
-    importers = getImporters()
+def getConfig():
+    parser = optparse.OptionParser()
+    parser.add_option("--directory", type="string")
+    parser.add_option("--target_srs", type="int")
+    parser.add_option("--host", type="string")
+    parser.add_option("--user", type="string")
+    parser.add_option("--password", type="string")
+    parser.add_option("--river_id", type="int")
+    parser.add_option("--verbose", type="int", default=1)
+    parser.add_option("--dry_run", type="int", default=0)
+    parser.add_option("--skip_axis", type="int")
+    parser.add_option("--skip_hydr_boundaries", type="int")
+    parser.add_option("--skip_buildings", type="int")
+    parser.add_option("--skip_crosssections", type="int")
+    parser.add_option("--skip_lines", type="int")
+    parser.add_option("--skip_fixpoints", type="int")
+    parser.add_option("--skip_floodplains", type="int")
+    parser.add_option("--skip_hws", type="int")
+    parser.add_option("--skip_gauge_locations", type="int")
+    parser.add_option("--skip_catchments", type="int")
+    parser.add_option("--skip_kms", type="int")
+    parser.add_option("--skip_uesgs", type="int")
+    (config, args) = parser.parse_args()
 
+    if config.directory == None:
+        ERROR("No river directory specified!")
+        raise Exception("Invalid config")
+    elif config.host == None:
+        ERROR("No database host specified!")
+        raise Exception("Invalid config")
+    elif config.user == None:
+        ERROR("No databaser user specified!")
+        raise Exception("Invalid config")
+    elif config.password == None:
+        ERROR("No password specified!")
+        raise Exception("Invalid config")
+    elif config.river_id == None:
+        ERROR("No river id specified!")
+        raise Exception("Invalid config")
+
+    return config
+
+
+def skip_importer(config, importer):
+    if config.skip_axis == 1 and isinstance(importer, Axis):
+        return True
+    elif config.skip_hydr_boundaries == 1 and isinstance(importer, HydrBoundary):
+        return True
+    elif config.skip_hydr_boundaries == 1 and isinstance(importer, HydrBoundaryPoly):
+        return True
+    elif config.skip_buildings == 1 and isinstance(importer, Building):
+        return True
+    elif config.skip_crosssections == 1 and isinstance(importer, CrosssectionTrack):
+        return True
+    elif config.skip_lines == 1 and isinstance(importer, Line):
+        return True
+    elif config.skip_fixpoints == 1 and isinstance(importer, Fixpoint):
+        return True
+    elif config.skip_floodplains == 1 and isinstance(importer, Floodplain):
+        return True
+    elif config.skip_hws == 1 and isinstance(importer, HWS):
+        return True
+    elif config.skip_gauge_locations == 1 and isinstance(importer, GaugeLocation):
+        return True
+    elif config.skip_catchments == 1 and isinstance(importer, Catchment):
+        return True
+    elif config.skip_kms == 1 and isinstance(importer, KM):
+        return True
+    elif config.skip_uesgs == 1 and isinstance(importer, UESG):
+        return True
+
+    return False
+
+
+def parse():
+    config=None
+    try:
+        config = getConfig()
+    except:
+        return
+
+    if config == None:
+        ERROR("Unable to read config from command line!")
+        return
+
+    if config.dry_run > 0:
+        INFO("You enable 'dry_run'. No database transaction will take place!")
+
+    importers = getImporters(config)
     types = {}
 
     for importer in importers:
-        shapes = utils.findShapefiles(importer.getPath(PATH))
-        print "Found %i Shapefiles" % len(shapes)
+        if skip_importer(config, importer):
+            INFO("Skip import of '%s'" % importer.getName())
+            continue
+
+        INFO("Start import of '%s'" % importer.getName())
+
+        shapes = utils.findShapefiles(importer.getPath(config.directory))
+        DEBUG("Found %i Shapefiles" % len(shapes))
 
         for shpTuple in shapes:
             geomType = importer.walkOverShapes(shpTuple)
             try:
-                num = types[geomType]
-                types[geomType] = num+1
+                if geomType is not None:
+                    num = types[geomType]
+                    types[geomType] = num+1
             except:
                 types[geomType] = 1
 
     for key in types:
-        print "%i x geometry type %s" % (types[key], key)
+        DEBUG("%i x geometry type %s" % (types[key], key))
 
+
+if __name__ == '__main__':
+    parse()
--- a/flys-backend/contrib/shpimporter/uesg.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/uesg.py	Fri Sep 28 12:15:40 2012 +0200
@@ -5,6 +5,7 @@
 
 TABLE_NAME="floodmaps"
 PATH="Hydrologie/UeSG/Berechnung"
+NAME="UESG"
 
 
 class UESG(Importer):
@@ -17,6 +18,10 @@
         return TABLE_NAME
 
 
+    def getName(self):
+        return NAME
+
+
     def isGeometryValid(self, geomType):
         if geomType == 3 or geomType == 6:
             return True
--- a/flys-backend/contrib/shpimporter/utils.py	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/contrib/shpimporter/utils.py	Fri Sep 28 12:15:40 2012 +0200
@@ -1,4 +1,5 @@
 import os
+from shpimporter import DEBUG, INFO, ERROR
 
 SHP='.shp'
 
@@ -9,7 +10,7 @@
         if len(files) == 0:
             continue
 
-        print "Processing directory '%s' with %i files " % (root, len(files))
+        DEBUG("Processing directory '%s' with %i files " % (root, len(files)))
 
         for f in files:
             idx = f.find(SHP)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/README.txt	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,527 @@
+FLYS3-Importer
+
+Der FLYS3-Importer dient dazu, hydrologische und morphologische
+Gewässerdaten aus dem Dateisystem in die FLYS3-Datenbank zu importieren.
+Das Werkzeug orientiert sich hierbei an der Dateihierachie,
+so wie sie auch von Desktop-FLYS ausgelesen wird.
+
+Als Startargument bekommt der Importer den Pfad zu einer
+GEW-Datei übergeben. 
+
+Wichtig für den Importer sind in dieser Datei
+die Zeilen, die mit "WSTDatei:" beginnen. In ihnen wird der 
+Pfad zu der zentralen WST-Datei des jeweiligen Gewässers angegeben.
+Alle anderen importierten Dateien werden in ihrer Lage relativ zur 
+Lage dieser Datei betrachtet.
+
+Das Verhalten des Importes kann mit sogenannten
+System-Properties gesteuert werden. Diese werden im
+Allgemeinen in der Form -Dkey=value angegeben.
+
+Will man z.B. mit dem Importer nur in simulierierten Import
+durchführen, dann kann dies über die Angabe von
+'-Dflys.backend.importer.dry.run=true' erfolgen.
+
+!!! Der Import geht wie Desktop-FLYS davon aus, dass die Dateien
+!!! Latin-1 encodiert vorliegen.
+
+Für den Importer stellt jeweils der Import eines Gewässers eine
+transaktionale Einheit dar. Wird der Import während eines Gewässers
+abgebrochen, werden alle Änderungen bzgl. dieses Gewässers zurück gerollt.
+
+Importierte Daten:
+
+Der Importer importiert folgende Datentypen:
+
+- Streckenfavoriten (*.km-Dateien)
+  Der Import kann mit '-Dflys.backend.importer.skip.annotations=true'
+  unterdrückt werden.
+
+  Zur Klassifikation von Streckenfavoriten kann mit
+  -Dflys.backend.importer.annotation.types=DATEI
+  der Pfad zu einer XML-Datei angegeben werden, in der über
+  Regeln festgelegt wird, wie diese geschehen soll.
+  Details hierzu im Anhang 'Klassifikation von Streckenfavoriten'.
+
+- Pegel, Stammdaten (*.glt, *.sta-Dateien):
+  Der Import kann mit '-Dflys.backend.importer.skip.gauges=true'
+  unterdrückt werden.
+  Die .glt-Datei, die neben der .wst-Datei liegt, wird zuerst
+  ausgelesen. Es werden nur *.sta-Datei von Pegeln geladen, die
+  in der .glt-Datei vermerkt sind.
+
+  Wenn "-Dflys.backend.sta.parse.gauge.numbers=true' wird versucht,
+  die offiziellen Pegelnummern aus den Stammdaten zu extrahieren.
+  !!! Dies ist mit Vorsicht zu behandeln, denn die meisten STA-Dateien
+  !!! Enthalten invalide Pegelnummern.
+
+  Die System-Property "flys.backend.main.value.types" kann einen
+  String mit gültigen Typen von Stammdaten enthalten. Vorbelegt
+  ist "QWTD". In der Praxis ist "QWD" eine sinnvolle Belegung.
+
+- Basis-Wasserstände (gewaesser.wst-Dateien):
+  Der Import kann mit '-Dflys.backend.importer.skip.wst=true'
+  unterdrückt werden.
+
+- Zusätzliche Längsschnitte (*.zus, *.wst-Dateien)
+  Der Import kann mit '-Dflys.backend.importer.skip.extra.wsts=true'
+  unterdrückt werden.
+  Es werden die *.zus- und *.wst-Dateien aus dem Verzeichnis
+  "../Zus.Längsschnitte" relativ zur gewaesser.wst-Datei betrachtet.
+
+- Fixierungen (*.wst-Dateien)
+  Der Import kann mit '-Dflys.backend.importer.skip.fixations=true'
+  unterdrückt werden.
+  Es werden die *.wst-Dateien aus dem Verzeichnis
+  "../Fixierungen" relativ zur gewaesser.wst-Datei betrachtet.
+
+- Amtliche Linien (*.wst-Dateien)
+  Der Import kann mit '-Dflys.backend.importer.skip.official.lines=true'
+  unterdrückt werden.
+  Es werden die "Amtl_Linien.wst"-Dateien aus dem Verzeichnis
+  "../Basisdaten" und "../Fixierungen" relativ zur gewaesser.wst-Datei betrachtet.
+
+- Profilspuren (*.prf-Dateien)
+  Der Import kann mit '-Dflys.backend.importer.skip.prfs=true'
+  unterdrückt werden.
+  Es werden rekursiv alle *.prf-Dateien aus "../../.." relativ
+  zur gewaesser.wst-Datei betrachtet. Vor dem Import werden
+  mithilfe eines Längen- und eines MD5-Summen-Vergleichs
+  inhaltliche Duplikate ausgeschlossen.
+
+- Hydraulische Kennzahlen (*.hyk)
+  Der Import kann mit '-Dflys.backend.importer.skip.hyks=true'
+  unterdrückt werden.
+  Es werden rekursiv alle *.hyk-Dateien aus "../../.." relativ
+  zur gewaesser.wst-Datei betrachtet. Vor dem Import werden
+  mithilfe eines Längen- und eines MD5-Summen-Vergleichs
+  inhaltliche Duplikate ausgeschlossen.
+
+- Hochwassermarken (*.zus, *.wst)
+  Der Import kann mit '-Dflys.backend.importer.skip.flood.water=true'
+  unterdrückt werden.
+  Es werden die *.zus- und *.wst-Dateien aus dem Verzeichnis
+  "../HW-Marken" relativ zur gewaesser.wst-Datei betrachtet.
+
+- Hochwasserschutzanlagen (*.zus)
+  Der Import kann mit '-Dflys.backend.importer.skip.flood.protection=true'
+  unterdrückt werden.
+  Es werden die *.zus- und *.wst-Dateien aus dem Verzeichnis
+  "../HW-Schutzanlagen" relativ zur gewaesser.wst-Datei betrachtet.
+
+  TODO INGO:
+
+  flys.backend.importer.skip.bed.height.single
+  flys.backend.importer.skip.bed.height.epoch
+  flys.backend.importer.skip.sediment.density
+  flys.backend.importer.skip.morphological.width
+  flys.backend.importer.skip.flow.velocity
+  flys.backend.importer.skip.sediment.yield
+  flys.backend.importer.skip.waterlevels
+  flys.backend.importer.skip.waterlevel.differences
+  flys.backend.importer.skip.sq.relation
+
+Für die Verbindung zur Datenbank ist es nötig, dem Import
+die Verbindungsdaten zu übergeben. Dies geschieht ebenfalls
+über System-Properties:
+
+  -Dflys.backend.user=NUTZER
+   Datenbanknutzer
+
+  -Dflys.backend.password=PASSWORT
+   Datenbankpasswort
+
+  -Dflys.backend.url=URL
+   URL zur Datenbank. Typische wäre im Fall einer Oracle-XE-Edition z.B.:
+   jdbc:oracle:thin:@//RECHNER:PORT/XE
+   mit RECHNER Name des Servers, auf dem die Datenbank läuft
+   und PORT der Port auf dem die Datenbank konkret zu erreichen ist.
+   Weitere Details unter http://www.orafaq.com/wiki/JDBC
+
+ -Dflys.backend.driver=TREIBER
+  mit TREIBER dem Namen des JDBC-Treibers, der es erlaubt
+  das Protokoll der Datenbank zu sprechen. Im Falle
+  einer Oracle XE wäre dies z.B.:
+  oracle.jdbc.OracleDriver
+
+ -Dflys.backend.dialect=DIALECT
+  mit DIALECT dem Hibernate-Dialekt, den die Datenbank versteht.
+  Im Falle eine Oracle-XE wäre dies z.B.:
+  org.hibernate.dialect.OracleDialect
+
+
+Hinweise zum Betrieb:
+---------------------
+
+    Der Speicherverbrauch des Importers ist sehr hoch. Es ist empfehlenswert,
+    der JVM mindestens 8GiB Hauptspeicher zuzuordnen: '-Xmx8192m'
+    Besonders speicherintensiv ist der Import der HYKs und der PRFs.
+    Hier ist es unter Umständen empfehlenswert, diese in zwei oder drei
+    Schritten zu importieren. Zuerst die sonstigen hydrologischen Daten
+    (hierbei mit flys.backend.importer.skip.hyks=true und flys.backend.importer.skip.prfs
+    den Import der HYKs und PRFs verhindern). Dann die HYKs (mit flys.backend.importer.skip.*
+    der anderen Daten) und im finalen Schritt dann die PRFs.
+
+Anhang 'Klassifikation von Streckenfavoriten'
+---------------------------------------------
+Streckenfavoriten werden aus KM-Dateien importiert. Um die einzelnen Einträge
+eine Kategorie (Brücken, Pegel, etc.) zuzuordnen, kann eine XML angegeben werden,
+in der Regeln für diese Klassifikation definiert werden. Schematisch gliedert
+sich diese Datei in die zwei Bereiche 'types' und 'patterns':
+
+<annotation>
+    <types> ...  </types>
+    <patterns> ...  </patterns>
+</annotation>
+
+In der Sektion 'types' werden die Kategorien vereinbart, in die
+klassifiziert werden sollen. Die geschieht mit einzelnen
+
+  <type name="Pegel"/>
+  <type name="Brücke"/>
+  ...
+  <type name="Sonstige" default="true"/>
+
+Das Attribut 'default' kann einmal vergeben werden und
+besagt, dass diese Kategorie gewählt werden soll, wenn
+keine andere Kategorie zugeordnet werden kann.
+
+In der Sektion 'patterns' werden dann die Regel
+definiert, die einzelne Einträge den definierten Kategorien
+zuordnet. Hierfür können zwei Arten von Definitionen
+angegeben werden:
+
+  <file pattern="^Brücken$" type="Brücke"/>
+
+oder
+
+  <line pattern="^Brücke[:\s].*$" type="Brücke"/>
+
+Die erste Variante bestimmt die Kategorie, die pro KM-Datei
+gelten soll. 'pattern' ist hierbei ein regulärer Ausdruck,
+der auf den Dateinamen angewandt wird. Passt der Name
+der Datei auf den regulären Ausdruck, wird 'type' als
+Vorgabe angenommen. Treffen mehrere <file>-Regeln zu,
+wird der erste Treffer angewandt. Findet keine der <file>-Regeln
+Anwendung, wird die Kategorie ausgewählt, die in der <types>-Section
+das Attribut 'default' gesetzt hat.
+
+Die zweite Regel-Variante <line> wird auf jeden Eintrag
+innerhalb einer KM-Datei auf den Bezeichner der Streckenfavoriten
+angewandt. Als Muster dient auch hier ein regulärer Ausdruck,
+der über das Attribut 'pattern' definiert wird. Die Kategorie
+wird in Trefferfall über das Attribut 'type' bestimmt. Treffen
+mehrere Regeln zu, wird die Kategorie gewählt, die zum ersten
+Treffer gehört. Trifft keine Regel zu wird der Eintrag der
+Kategorie zugeteilt, die für die beinhaltende Datei als Vorgabe
+gilt.
+
+Anhang 'Fehler und Warnungen':
+=============================
+
+Fehler:
+-------
+
+- 'error while parsing gew'
+  Die GEW-Datei ist fehlerhaft oder konnte nicht geöffnet werden.
+
+- 'File 'XYZ' is broken!'
+  Die Datei XYZ ist inkonsistent und führt zu Fehlern.
+
+- 'Error while parsing file for morph. width.'
+  Beim Lesen der morphologischen Breite trat ein Fehler auf.
+
+- 'Error while storing flow velocity model.'
+  Beim Schreiben eines Fliessgeschwindigkeitsmodells trat ein Fehler auf.
+
+- 'Error while storing flow velocity measurement.'
+  Beim Schreiben einer Fliessgeschwindigkeitsmessung trat ein Fehler auf. 
+
+- 'Error while storing sediment yield.'
+  Beim Schreiben einer Sedimentablagerung trat ein Fehler auf.
+
+- 'Error while storing waterlevel diff.'
+  Beim Schreiben einer Wassspiegeldifferenz trat ein Fehler auf.
+
+- 'Error while storing sq relation.'
+  Beim Schreiben einer S(Q) Beziehung trat ein Fehler auf.
+
+- 'Error reading PRF file.'
+  Beim Lesen einer PRF-Datei trat ein Fehler auf.
+
+- 'Error closing PRF file.'
+  Beim Schliessen einer PRF-Datei trat ein Fehler auf.
+
+- 'HYK 1: not enough elements in line #'
+- 'HYK 2: not enough elements in line #'
+- 'HYK 5: not enough elements in line #'
+- 'HYK 6: not enough elements in line #'
+  Eine Zeile in einer HYK-Datei hat nicht genügend Elemente.
+
+- 'HYK: parsing num zones, bottom or top height failed in line #'
+- 'HYK: HYK: number of flow zones mismatches in line #'
+  Die Anzahl der Zonen oder Daten über die Zonen sind nicht korrekt.
+
+- 'HYK: cannot parse number in line #'
+  Eine Zahl wurde erwartet.
+
+- 'HYK: Error reading file.'
+  Beim Lesen einer HYK-Datei trat ein Fehler auf.
+
+- 'HYK: Error closing file.'
+  Beim Schliessen einer HYK-Datei trat ein Fehler auf.
+
+Warnungen:
+----------
+
+- 'annotation type file 'XYZ' is not readable.'
+  Die Datein XYZ kann nicht gelesen werden.
+
+- 'cannot parse annotation types file.'
+  Während der Verarbeitung der Annotationsdatei ist Fehler aufgetreten.
+
+- 'Cannot read directory.'
+  verzeichnis konnte nicht gelesen werden.
+
+- 'no official lines wst file found'
+  Keine Datei mit amtlichen Linien gefunden.
+
+- 'cannot read fixations wst file directory'
+  Das Verzeichnis mit den Fixierungen kann nicht gelesen werden.
+
+- 'cannot read extra longitudinal wst file directory'
+  Das Verzeichnis mit den zusätzlichen Längsschnitten kann nicht gelesen werden.
+
+- 'cannot read gauges from 'XYZ''
+  Die Pegelgültigkeiten können nicht gelesen werden.
+
+- 'HYK file 'XYZ' seems to be a duplicate.'
+  Die HYK-Datei wurde unter anderem Namen aber gleichen Inhalts
+  bereits gefunden.
+
+- 'PRF file 'XYZ' seems to be a duplicate.'
+  Die PRF-Datei wurde unter anderem Namen aber gleichen Inhalts
+  bereits gefunden.
+
+- 'Skip invalid SedimentYield: time interval or unit null!'
+  Eine Sedimentablagerung ist ungültig und wurde ausgelassen.
+
+- 'skip flow velocity model: No discharge zone specified.'
+  Da kein Abflussbereich angegeben wurde, wurde das Fliessgeschwindigkeitsmodell ausgelassen.
+
+- 'skip invalid waterlevel - no unit set!'
+  Ein einheitenloser Wasserstand wurde ausgelassen.
+
+- 'Cannot parse time range.'
+  Das Zeitformat wurde nicht erkannt.
+
+- 'skip invalid data line #'
+  Ungültige Datenzeile wurde ausgelassen.
+
+- 'Error while parsing sq relation row #'
+  Eine Zeile in der S(Q)-Beziehung ist ungültig.
+
+- 'GLT: no gauge found in line #'
+  In der GLT-Datei wurde ein Pegel erwartet, aber nicht gefunden.
+
+- 'GLT: line # has not enough columns.'
+  Eine Zeile in der Pegelgültigkeitsdatei hat nicht genug spalten.
+
+- 'Error while parsing flow velocity values.'
+- 'skip invalid data line: #'
+  Invalide Datenzeile in einer Datei mit einer Fliessgeschwindigkeitsmessung.
+
+- 'skip invalid waterlevel line: #'
+- 'Error while parsing value: #'
+- 'Error while parsing station: #'
+  Invalide Datenzeile in einer Datei mit Wasserstandsdifferenzen.
+
+- 'skip invalid MainValue part: #'
+- 'skip invalid gauge part: #'
+- 'Error while parsing Q value: <Q>'
+- 'skip invalid data line: #'
+- 'Error while parsing flow velocity values.'
+  Invalide Datenzeile in einer Datei Fliessgeschwindigkeitsmodellen.
+
+- 'Error while parsing number from data row: #'
+  TODO INGO
+
+- 'Unknown meta line: #'
+- 'Error while parsing numbers in: #'
+- 'skip invalid data line: #'
+- 'Error while parsing numbers in #'
+  Invalide Datenzeile in einer Datei mit Sedimentdichten.
+
+- 'STA file is empty'
+- 'STA file has not enough lines'
+- 'STA file is too short'
+  Stammdatendatei ist leer oder hat zu wenige Zeilen.
+
+- 'First line in STA file is too short.'
+  Die erste Zeile der Stammdaten ist zu kurz.
+
+- 'STA: second line is too short'
+  Die zweite Zeile ist zu kurz.
+
+- 'STA: parsing of the datum of the gauge failed'
+
+- 'STA: 'XYZ' is not a valid long number.'
+  Die Pegelnummer ist invalide.
+
+- 'STA: Not enough columns for aeo and datum.
+  AEO und Pegelnullpunkt können nicht ermittelt werden.
+
+- 'STA: cannot parse aeo or datum.'
+  AEO oder Pegelnullpunkt sind invalide.
+
+- 'STA: value not parseable in line #'
+  Wert ist nicht als Zahl zu interpretieren.
+  
+- 'PRF: cannot open file <FILE>'
+  Die PRF kann nicht geöffnet werden.
+
+- PRF: file is empty
+- PRF: First line does not look like a PRF data pattern.
+- PRF: premature EOF. Expected integer in line 2
+- PRF: Expected <num> in line 2
+- PRF: invalid integer in line 2
+- PRF: premature EOF. Expected pattern for km extraction
+- PRF: line 4 does not look like a PRF km extraction pattern.
+- PRF: premature EOF. Expected skip row count.
+- PRF: line 5 is not an positive integer.
+- PRF: cannot extract km in line #
+  Das PRF-Format ist komplex. Hier sollten weitere Information
+  zur genaueren Analyse herangezogen werden.
+
+- 'cannot access WST file <FILE>'
+  Die WST-Datei konnte nicht gefunden werden.
+
+- 'Found an invalid row in the AT file.'
+  Eine Zeile in einer AT-Datei ist nicht korrekt.
+
+- 'AT: invalid number <XYZ>'
+  Eine Zahl wurde erwartet aber nicht gefunden.
+
+- 'Try to add Q range without waterlevel!'
+  Q-Bereich ohne Wasserstand gefunden.
+
+- 'Error while parsing Q range: #'
+  Invalider Q-Bereich
+
+- 'skip invalid waterlevel line: #'
+  Ungültige Wasserstandslinie
+
+- 'Error while parsing number values: #'
+  Ungültige Zahlenwerte.
+
+- 'ANN: not enough columns in line #'
+  Nicht genug Zeichenspalten in KM-Datei
+
+- 'ANN: invalid number in line #'
+  Ungültige Zahl.
+
+- 'ANN: cannot parse 'Unterkante' in line #'
+  Die Unterkante in einer KM-Datei konnte nicht gelesen werden.
+
+- 'ANN: cannot parse 'Unterkante' or 'Oberkante' in line #'
+  Unter- oder Oberkannte liegen in einem falschen Format vor.
+
+- 'ANN: duplicated annotation 'XYZ' in line #'
+  Ein Duplikat eines Streckenfavoriten wurde gefunden.
+
+- 'ANN: 'XYZ' is not a directory.'
+  Unterverzeichnis konnte nicht geöffnet werden.
+
+- 'ANN: cannot list directory 'XYZ''
+  Unterverzeichnis konnte nicht durchsucht werden.
+
+- 'BHP: Meta line did not match any known type: #'
+  Unbekannter Typ.
+
+- 'BHP: Error while parsing timeinterval!'
+  Ungültiges Zeitinterval.
+
+- 'BHP: Error while parsing year!'
+  Ungültige Jahresangabe.
+
+- 'BHP: Error while parsing sounding width!'
+  Unbekannte Peilungsbreite.
+
+- 'BHP: Error while parsing range!'
+  Bereichsangabe fehlerhaft.
+
+- 'MWP: Unknown meta line: #'
+  Meta-Informationen ungültig.
+
+- 'MWP: skip invalid data line: #'
+  Ungültige Datenzeile wurde übersprungen.
+
+- 'MWP: Error while parsing numbers in #'
+  Falsche Zahlenformat.
+
+- 'ANNCLASS: rule has no name'
+  Klassifizierungsregel für Streckenfavoriten hat keinen Namen.
+
+- 'ANNCLASS: pattern has no 'pattern' attribute.'
+  Klassifizierungsmuster für Streckenfavoriten hat kein Muster.
+
+- 'ANNCLASS: pattern has unknown type 'XYZ''
+  Klassifizierungsmuster für Streckenfavoriten konnte keinem Typ zugeordnet werden.
+
+- 'ANNCLASS: pattern 'XYZ' is invalid.'
+  Klassifizierungsmuster für Streckenfavoriten ist ungültig.
+
+- 'BSP: Error while parsing data row.'
+  Ungültige Datenzeile.
+
+- 'SYP: Unknown meta line: #'
+  Ungültige Metadatenzeile.
+
+- 'SYP: skip invalid data line #'
+  Ungültige Datenzeile wurde übersprungen.
+
+- 'SYP: Error while parsing numbers in #'
+  Ungültige Zahlenformatierung.
+
+- 'SYP: Unknown time interval string <XYZ>'
+  Falsches Datumformat.
+
+- 'SYP: Error while parsing years <XYZ>'
+  Falsches Jahreszahlformat.
+ 
+- 'SYP: Error while parsing ranges of <XYZ>'
+  Bereichsangaben fehlerhaft.
+
+- 'SYP: Unknown grain fraction <XYZ>'
+  Unbekannte Kornfraktion.
+
+- 'WST: invalid number.'
+  Ungültige Zahl.
+
+- 'WST: km <km> (<Zeile>) found more than once. -> ignored.'
+  Ein Kilometer ist doppelt in einer WST-Datei enthalten.
+
+- 'HYK: zone coordinates swapped in line #'
+  Fliesszonenkordinaten wurden in umgekehrter Reihenfolge angeben.
+
+- 'BHS: Skip invalid file 'XYZ''
+  Die Inhalte der Datei sind ungültig.
+
+- 'ISQ: Unable to store sq relation value.'
+  S(Q) Beziehung konnte nicht gespeichert werden.
+
+- 'ISQ: Cannot determine sq relation without time interval.'
+  Einer S(Q)-Beziehung ist keine zeitliche Gültigkeit zugeordnet.
+
+- 'IWD: skip invalid waterlevel difference - no unit set!'
+  Wasserstandsdifferenz hat keine Einheit.
+
+- 'BHE: Skip file - invalid current elevation model.'
+  Höhenmodell ungültig.
+
+- 'BHE: Skip file - invalid time range.'
+  Zeitbereich ungültig.
+
+- 'BHE: Skip file - invalid km range.'
+  Kilometerbereich ungültig.
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/Makefile	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,3492 @@
+# Copyright 2004 Chris Monson (shiblon@gmail.com)
+# Latest version available at http://www.bouncingchairs.net/oss
+#
+#    This file is part of ``Chris Monson's Free Software''.
+#
+#    ``Chris Monson's Free Software'' is free software; you can redistribute it
+#    and/or modify it under the terms of the GNU General Public License as
+#    published by the Free Software Foundation, Version 2.
+#
+#    ``Chris Monson's Free Software'' is distributed in the hope that it will
+#    be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+#    Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License along
+#    with ``Chris Monson's Free Software''; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#    It is also available on the web at http://www.gnu.org/copyleft/gpl.html
+#
+#    Note that using this makefile to build your documents does NOT place them
+#    under the GPL unless you, the author, specifically do so.  In other words,
+#    I, Chris Monson, the copyright holder and author of this makefile,
+#    consider it impossible to ``link'' to this makefile in any way covered by
+#    the GPL.
+#
+# TO OBTAIN INSTRUCTIONS FOR USING THIS FILE, RUN:
+#    make help
+#
+fileinfo	:= LaTeX Makefile
+author		:= Chris Monson
+version		:= 2.2.0-rc1
+#
+# Note that the user-global version is imported *after* the source directory,
+# so that you can use stuff like ?= to get proper override behavior.
+.PHONY: Makefile GNUmakefile Makefile.ini $(HOME)/.latex-makefile/Makefile.ini
+-include Makefile.ini
+-include $(HOME)/.latex-makefile/Makefile.ini
+#
+# This can be pdflatex or latex - you can change this by adding the following line to your Makefile.ini:
+# BUILD_STRATEGY := latex
+BUILD_STRATEGY		?= pdflatex
+#
+# Sets LC_ALL=C, by default, so that the locale-aware tools, like sort, be
+# # immune to changes to the locale in the user environment.
+export LC_ALL		?= C
+#
+#
+# If you specify sources here, all other files with the same suffix
+# will be treated as if they were _include_ files.
+#onlysources.tex	?= main.tex
+#onlysources.tex.sh	?=
+#onlysources.tex.pl	?=
+#onlysources.tex.py	?=
+#onlysources.rst	?=
+#onlysources.fig	?=
+#onlysources.gpi	?=
+#onlysources.dot	?=
+#onlysources.xvg	?=
+#onlysources.svg	?=
+#onlysources.eps.gz	?=
+#onlysources.eps	?=
+#
+# If you list files here, they will be treated as _include_ files
+#includes.tex		?= file1.tex file2.tex
+#includes.tex.sh	?=
+#includes.tex.pl	?=
+#includes.tex.py	?=
+#includes.rst		?=
+#includes.fig		?=
+#includes.gpi		?=
+#includes.dot		?=
+#includes.xvg		?=
+#includes.svg		?=
+#includes.eps.gz	?=
+#includes.eps		?=
+#
+# If you list files or wildcards here, they will *not* be cleaned - default is
+# to allow everything to be cleaned.
+#neverclean		?= *.pdf
+#
+# Alternatively (recommended), you can add those lines to a Makefile.ini file
+# and it will get picked up automatically without your having to edit this
+# Makefile.
+#
+# KNOWN ISSUES:
+#	* The following occurs:
+#		file with: \usepackage{named}\bibliographystyle{named}
+#		Compile
+#		change to: \usepackage{apalike}\bibliographystyle{apalike}
+#		Compile again -- BARF!
+#
+#		The workaround: make clean-nographics; make
+#
+#		Note that we may not be able to fix this.  LaTeX itself barfs
+#		on this, not the makefile.  The very first invocation of LaTeX
+#		(when something like this has happened) reads the existing .aux
+#		file and discovers invalid commands like \citeauthoryear that
+#		are only valid in the package that was just removed.  It then
+#		tries to parse them and explodes.  It's not at all clear to me
+#		how to fix this.  I tried removing the .aux files on the first
+#		run of LaTeX, but that necessarily requires more subsequent
+#		rebuilds on common edits.  There does not appear to be a
+#		graceful solution to this issue.
+#
+# CHANGES:
+# Chris Monson (2010-04-08):
+# 	* Bumped version to 2.2.0-rc1
+# 	* Added back in the rst_style_file stuff that got broken when switching
+# 		rst -> tex to use the script mechanism
+# Chris Monson (2010-03-23):
+#	* Bumped version to 2.2.0-beta8
+#	* Work on issue 76: bad backtick escape for some sed versions, failure
+#		to clear out the hold buffer when outputting MISSING comment.
+#		- Backed out 2>&1 to &> (doesn't work in sh)
+#		- Backed out using . to source variables
+# Chris Monson (2010-03-22):
+# 	* Bumped version to 2.2.0-beta7
+# 	* Issue 72: Fix latex/bibtex invocation order for annotated bib styles
+# 	* Fixed informational output to reflect which LaTeX run we're on
+# 	* Fixed graphic detection to include graphics that are already there in
+# 		.d files
+# 	* Tightened up the .d file output to only make .d depend on graphic
+# 		*source* files.  This means that building foo.d no longer
+# 		builds all of the graphics files on which foo.tex depends.
+# 		Had to use .SECONDEXPANSION trickery to make it work.
+# 	* Changed get-graphics to only accept a stem.
+# 	* Fixed build-once logic for scripted .tex to work better
+# 	* Made get-inputs sed script more maintainable.
+# 	* Moved Makefile.ini import up higher.
+# 	* Changed bare stems to not recursively invoke make
+# 	* Updated diff output to be more silent everywhere
+# 	* Added a MISSING comment to the .d file if stuff isn't found - forces
+# 		removal of .1st.make file, which often forces it to try again.
+# 	* Fixed broken graphics-target function
+# 	* Added sleep to .d file generation when stuff is missing - if it
+# 		builds too fast, make doesn't realize it needs to be reloaded,
+# 		and thus never discovers some deeper dependencies (especially
+# 		evident when graphics are included from scripted include
+# 		files).
+# Chris Monson (2010-03-17):
+# 	* Bumped version to 2.2.0-beta6
+# 	* Fixed bareword builds to actually work (requires static patterns)
+# 	* Fixed colorization to work with new paragraph stuff
+# Chris Monson (2010-03-17):
+# 	* Bumped version to 2.2.0-beta5
+# 	* Fixed graphic detection to be much more focused - splits log file
+# 		into paragraphs before doing pattern matching.
+# 	* Fixed make foo to work properly (recursively calls make foo.pdf)
+# 	* Fixed gpi -> pdf generation to not waste time building .eps *after*
+# 		the pdf already exists.
+# 	* Changed log copies to include MAKE_RESTARTS as part of the name.
+# 	* Fixed missing include file detection (also makes use of the paragraph
+# 		stuff) to detect missing scripted include files.
+# Chris Monson (2010-03-16):
+# 	* Bumped version to 2.2.0-beta4
+# 	* issue 70: .pdf not moved out of the way properly on first
+# 		compilation, resulting in early error detection failure.
+# 	* issue 74: fixed broken error on missing .aux files: the
+# 		implementation was masking real errors.
+# Chris Monson (2010-03-15):
+# 	* Bumped version to 2.2.0-beta3
+# 	* issue 71: Made the tput dependency optional
+# 	* issue 73: Made .tex targets not pull in .d files (building them from
+# 		scripts should not require a .d)
+# 	* issue 74: Output a much saner error when a .aux file is not produced
+# 		(e.g., when you are typing "make" without arguments in a
+# 		directory with included .tex files that are not named with
+# 		._include_.)
+# Chris Monson (2010-03-11):
+# 	* Bumped version to 2.2.0-beta2
+# 	* Fixed clean-graphics to get rid of intermediate .eps files that may
+# 		be hanging around
+# 	* Added an automatic setting to use eps terminals in pdflatex mode for
+# 		gnuplot if it doesn't understand pdf.
+# 	* issue 66: Removed grayscale generation via magic suffix.  Grayscale
+# 		generation is now only available via GRAY=1
+# 	* issue 68: Added explicit handling of LC_ALL for locale-aware tools
+# 		like "sort"
+# Chris Monson (2010-03-10):
+# 	* Bumped version to 2.2.0-beta1
+# 	* Fixed success message to handle output message in different places
+# 	* Added name of produced file to success message
+# Chris Monson (2010-03-10):
+# 	* Bumped version to 2.2.0-alpha3
+# 	* Added meaningful error message for wrong hyperref options
+# 	* Added meaningful error message for incorrect graphics extensions
+# Chris Monson (2010-03-09):
+# 	* Bumped version to 2.2.0-alpha2
+# 	* Updated graphics handling (gnuplot and fig generate pdf natively)
+# 	* Changed xmgrace to output monochrome natively
+# Chris Monson (2010-03-09):
+# 	* Bumped version to 2.2.0-alpha1 - major change!
+# 	* Support pdflatex natively and by default (issue 6 - a long time coming)
+# 	* Add ability to have a single $HOME/.latex-makefile/Makefile.ini for
+# 		all invocations
+# 	* Reworked graphic inclusion detection so that extensions need not be
+# 		specified for either build strategy (e.g.,
+# 		\includegraphics{test1.eps} -> \includegrahpics{test1})
+# 	* Changed log format to include filenames and line numbers
+# Chris Monson (2010-02-04):
+# 	* Bumped version to 2.1.43
+# 	* All of the following are for issue 63 (thanks to mojoh81):
+# 	* Added documentation about fixing Makefile.ini default target
+# 	* Added perl and python script targets
+# 	* Fixed run logic to allow included .tex files to be scripted (the
+# 		run-again logic now detects missing .tex files, and the MV
+# 		command has been switched out for a command that only invokes
+# 		MV if the files exist)
+# 	* Changed scripted generation to only run once per make invocation
+# 	* Added dependency on expr
+# Chris Monson (2010-01-19):
+# 	* Bumped version to 2.1.42
+# 	* issue 62: Added .brf extension to cleanable files (backrefs)
+# Chris Monson (2010-01-07):
+# 	* Bumped version to 2.1.41
+# 	* issue 60: bad makeindex runs now error out on subsequent tries
+# Chris Monson (2009-12-01):
+# 	* Bumped version to 2.1.40
+# 	* issue 36: build all indices (for e.g., splitidx usage)
+# 	* issue 59: clean up all generated files (including indices)
+# Chris Monson (2009-11-23):
+# 	* Bumped version to 2.1.39
+# 	* issue 57: change ps2pdf invocations to just use gs directly
+# Chris Monson (2009-11-19):
+# 	* Bumped version to 2.1.38
+# 	* issue 57: Added some limited support for Cygwin (spaces in filenames)
+# Chris Monson (2009-11-15):
+# 	* Bumped version to 2.1.37
+# 	* Removed svninfo, since this is now managed by mercurial
+# 	* Fixed typo in changelist
+# 	* Issue 52: added jpg->eps conversion (thanks to brubakee)
+# 	* Issue 54: fix missing Overfull colorization due to lack of a blank
+# 		line preceding the first error.
+#	* Issue 51: remove head.tmp and body.tmp in make clean invocation
+#	* Issue 56: maintain multiple versions of log files (for debugging)
+# Chris Monson (2009-11-14):
+# 	* Bumped version to 2.1.36
+# 	* Issues 53 and 49: added .brf, .mtc, and .maf to the cleanables
+# Chris Monson (2009-11-05):
+# 	* Bumped version to 2.1.35
+# 	* Added nomenclature support (see issue 48)
+# Chris Monson (2009-10-29):
+# 	* Bumped version to 2.1.34
+# 	* Fixed _out_ creation bug introduced in 2.1.33 (it was always created)
+# 	* Fixed erroneous help output for $HOME in BINARY_TARGET_DIR
+# 	* Changed contact email address - bring on the spam!
+# Chris Monson (2009-10-21):
+# 	* Bumped version to 2.1.33
+# 	* Fixed issue 46, adding support for dot2tex (thanks to fdemesmay)
+# 	* Made all_files.* settable in Makefile.ini (using ?= instead of :=)
+# 	* Fixed issue 47, thanks to fdemesmay: add binary copy directory, copy
+# 		dvi, pdf, and ps if it exists
+# Chris Monson (2009-09-25):
+# 	* Bumped version to 2.1.32
+# 	* Fixed so that a changed lol file will cause a rebuild
+# 	* Added .lol files to the cleanable list
+# Chris Monson (2009-09-08):
+# 	* Bumped version to 2.1.31
+# 	* Closed issue 43: evince doesn't notice pdf change w/out touch
+# Chris Monson (2009-08-28):
+# 	* Bumped version to 2.1.30
+# 	* Closed issue 39: Capture multi-line log warnings/errors to output
+# Chris Monson (2009-08-26):
+# 	* Bumped version to 2.1.29
+# 	* Closed issue 42: add svg support using inkscape
+# Chris Monson (2009-08-17):
+# 	* Bumped version to 2.1.28
+# 	* Patch from paul.biggar for issue 38: package warnings are overlooked
+# Chris Monson (2009-08-07):
+# 	* Bumped version to 2.1.27
+# 	* Included patch for issue 37 - removes pdf/ps files before copying,
+# 		allowing some broken viewers to see changes properly.
+# Chris Monson (2009-05-15):
+# 	* Bumped version to 2.1.26
+# 	* Included patch for issue 9 from favonia - detects .fig changes for
+# 		pstex files during regular compilation, so long as the pstex
+# 		has been built at least once with make all-pstex.
+# Chris Monson (2009-03-27):
+# 	* Bumped version to 2.1.25
+# 	* Cleaned up a bunch of variable setting stuff - more stuff is now
+# 		settable from Makefile.ini
+# 	* Cleaned up documentation for various features, especially settable
+# 		variables.
+# 	* issue 28: support for png -> eps conversion (it even looks good!)
+# 	* issue 29: support for "neverclean" files in Makefile.ini
+# 	* issue 30: make ps2pdf14 the default - fall back when not there
+# Chris Monson (2009-03-09):
+# 	* Bumped version to 2.1.24
+# 	* issue 27: xmgrace support (thanks to rolandschulzhd)
+# Chris Monson (2008-10-23):
+# 	* Bumped version to 2.1.23
+# 	* issue 23: fixed _check_programs to not use bash string subs
+# Chris Monson (2008-09-02):
+# 	* Bumped version to 2.1.22
+# 	* Appled patch from Holger <yllohy@googlemail.com> to add include
+# 		sources and some documentation updates.
+# 	* Updated backup_patterns to be a bit more aggressive (also thanks to
+# 		Holger)
+# Chris Monson (2008-08-30):
+# 	* Bumped version to 2.1.21
+# 	* Added ability to specify onlysources.* variables to indicate the only
+# 		files that should *not* be considered includes.  Thanks to Holger
+# 		<yllohy@googlemail.com> for this patch.
+# 	* Added an automatic include of Makefile.ini if it exists.  Allows
+# 		settings to be made outside of this makefile.
+# Chris Monson (2008-05-21):
+# 	* Bumped version to 2.1.20
+# 	* Added manual pstex compilation support (run make all-pstex first)
+# 	* Removed all automatic pstex support.  It was totally breaking
+# 		everything and is very hard to incorporate into the makefile
+# 		concept because it requires LaTeX to *fail* before it can
+# 		determine that it needs the files.
+# Chris Monson (2008-04-17):
+# 	* Bumped version to 2.1.19
+# 	* Changed the pstex build hack to be on by default
+# Chris Monson (2008-04-09):
+# 	* Bumped version to 2.1.18
+# 	* issue 16: fixed pstex build problems, seems nondeterministic.  Added
+# 		gratuitious hack for testing: set PSTEX_BUILD_ALL_HACK=1.
+# Chris Monson (2008-04-09):
+# 	* Bumped version to 2.1.17
+# 	* issue 20: fixed accumulation of <pid>*.make files - wildcard was
+#		refusing to work on files that are very recently created.
+# Chris Monson (2008-04-02):
+# 	* Bumped version to 2.1.16
+# 	* issue 19: Removed the use of "type" to fix broken "echo" settings
+# Chris Monson (2008-03-27):
+# 	* Bumped version to 2.1.15
+# 	* issue 18: Favors binary echo over builtin, as binary understands -n
+# 	* issue 16: Fixed handling of missing pstex_t files in the log
+# 	* issue 9: Added .SECONDARY target for .pstex files
+# Chris Monson (2008-03-21):
+# 	* Bumped version to 2.1.14
+# 	* Fixed broken aux file flattening, which caused included bibs to be
+# 		missed.
+# Chris Monson (2008-03-20):
+# 	* Bumped version to 2.1.13
+# 	* Changed error output colorization to show errors for missing files
+# 		that are not graphics files.
+# Chris Monson (2008-03-20):
+# 	* Bumped version to 2.1.12
+# 	* Fixed a regression introduced in r28 that makes bibtex fail when
+# 		there is no index file present
+# Chris Monson (2008-03-03):
+# 	* Bumped version to 2.1.11
+# 	* Fixed issue 11 (handle index files, reported by abachn)
+# 	* Cleaned up some comments and help text
+# Chris Monson (2008-01-24):
+# 	* Bumped version to 2.1.10
+#	* Fixed to work when 'sh' is a POSIX shell like 'dash'
+# Chris Monson (2007-12-12):
+# 	* Bumped version to 2.1.9
+# 	* Fixed documentation and dependency graph for pstex files
+# Chris Monson (2007-12-12):
+# 	* Bumped version to 2.1.8
+# 	* Added basic pstex_t support for fig files (Issue 9 by favonia)
+# 		I still suggest that psfrag be used instead.
+# Chris Monson (2007-10-16):
+# 	* Bumped version to 2.1.7
+# 	* Removed todo item: allow other comment directives for rst conversion
+# 	* Added ability to use global rst style file _rststyle_._include_.tex
+# 	* Added help text to that effect
+# Chris Monson (2007-05-20):
+# 	* Bumped version to 2.1.6
+# 	* Changed default paper size for rst files
+# 	* Added todo item: fix paper size for rst files
+# 	* Added todo item: allow other comment directives for rst conversion
+# Chris Monson (2007-04-02):
+# 	* Bumped version to 2.1.5
+# 	* Addressed Issue 7, incorrect .gpi.d generation in subdirectories
+# Chris Monson (2007-03-28):
+# 	* Bumped version to 2.1.4
+# 	* Fixed syntax error in dot output
+# Chris Monson (2007-03-01):
+# 	* Bumped version to 2.1.3
+# 	* Added reST to the included documentation
+# 	* Fixed graphics and script generation to be settable in the
+# 		environment.
+# Chris Monson (2007-02-23):
+# 	* Bumped version to 2.1.2
+# 	* Added the ability to generate .tex files from .rst files
+# Chris Monson (2006-10-17):
+# 	* Bumped version to 2.1.1
+# 	* Fixed includes from subdirectories (sed-to-sed slash escape problem)
+# Chris Monson (2006-10-05):
+# 	* Bumped version to 2.1.0 (pretty serious new feature added)
+# 	* New feature: bib files can now be anywhere on the BIBINPUTS path
+# 	* New programs: kpsewhich (with tetex) and xargs (BSD)
+# Chris Monson (2006-09-28):
+# 	* Bumped version to 2.0.9
+# 	* Added ability to parse more than one bibliography
+# Chris Monson (2006-06-01):
+# 	* Bumped version to 2.0.8
+# 	* Added .vrb to the list of cleaned files
+# Chris Monson (2006-04-26):
+# 	* Bumped version to 2.0.7
+# 	* Fixed so that clean-nographics does not remove .gpi.d files
+# 	* Removed jpg -> eps hack (not working properly -- just pre-convert)
+# 	* Fixed so that postscript grayscale can be done with BSD sed
+# Chris Monson (2006-04-25):
+# 	* Bumped version to 2.0.6
+# 	* Fixed so that changed toc, lot, lof, or out causes a rebuild
+# Chris Monson (2006-04-17):
+# 	* Bumped version to 2.0.5
+# 	* Added jpg -> eps conversion target
+# Chris Monson (2006-04-12):
+# 	* Bumped version to 2.0.4
+# 	* Fixed BSD sed invocation to not use \| as a branch delimiter
+# 	* Added a comment section on what is and is not allowed in BSD sed
+# 	* Made paper size handling more robust while I was at it
+# 	* Fixed postscript RGB grayscale to use a weighted average
+# 	* Fixed postscript HSB grayscale to convert to RGB first
+# 	* Fixed a problem with rebuilding .bbl files
+# Chris Monson (2006-04-11):
+# 	* Bumped version to 2.0.3
+# 	* Fixed some BSD sed problems: can't use \n in substitutions
+# Chris Monson (2006-04-10):
+# 	* Bumped version to 2.0.2
+# 	* Once again removed ability to create .tex files from scripts
+# 	* \includeonly works again
+# Chris Monson (2006-04-09):
+# 	* Bumped version to 2.0.1
+# 	* Fixed grayscale postscript handling to be more robust
+# 	* Added ability to generate ._gray_. files from eps and eps.gz
+# 	* Added ability to clean ._gray_.eps files created from .eps files
+# Chris Monson (2006-04-07):
+# 	* Bumped version to 2.0.0
+# 	* Removed clunky ability to create included .tex files from scripts
+# 	* Added note in the help about included tex scripting not working
+# 	* Fixed the .eps generation to delete %.gpihead.make when finished
+# 	* Abandoned designs to use shell variables to create sed scripts
+# 	* Abandoned __default__.tex.sh idea: it causes recursion with %: .
+# 	* Removed web page to-do.  All items are now complete.
+# 	* Added better grayscale conversion for dot figures (direct ps fixup).
+# 	* Include files can now be scripted (at the expense of \includeonly).
+# 	* Updated dependency graph to contain better node names.
+# Chris Monson (2006-04-06):
+# 	* Bumped version to 2.0b3
+# 	* Top level includes now fail if there is no rule to build them
+# 	* A helpful message is printed when they do fail
+# 	* Grayscale has been changed to be ._gray_, other phonies use _ now, too
+# 	* Grayscale handling has been completed
+# 	* Changed _include_stems target to _includes target.
+# 	* Fixed _includes target to be useful by itself.
+# 	* Removed the ability to specify clean and build targets at once
+# 	* Verified that epsfig works fine with current code
+# 	* Fixed included scripts so that they are added to the dep files
+# 	* Fixed so that graphics includes don't happen if they aren't for gpi
+# 	* Fixed dot output to allow grayscale.
+# Chris Monson (2006-04-05):
+#	* Bumped version to 2.0b2
+#	* Removed automatic -gray output.  It needs fixing in a bad way.
+#	* Revamped dependency creation completely.
+#	* Fixed conditional inclusion to actually work (test.nobuild.d, test.d).
+#	* Fixed clean target to remove log targets
+#	* Added the 'monochrome' word for gray gpi output
+#	* Added a _check_gpi_files target that checks for common problems
+#	* Changed the _version target into the version target (no _)
+#	* Added better handling of grayscale files.  Use the .gray.pdf target.
+#	* Fixed testing for rebuilds
+# Chris Monson (2006-04-04):
+#	* Bumped version to 2.0b1
+#	* Changed colorization of output
+#	* Made .auxbbl and .auxtex .make files secondary targets
+#	* Shortened and simplified the final latex invocation loop
+#	* Added version-specific output ($$i vs. $$$$i) in latex loop
+#	* Added a build message for the first .dvi run (Building .dvi (0))
+#	* Removed some build messages that most people don't care about.
+#	* Simplified procedure for user-set colors -- simple text specification
+#	* Fixed diff output to...not output.
+#	* Fixed rerun bug -- detect not only when preceded with LaTeX Warning
+#	* Sped up gpi plotting
+#	* Added error handling and colorized output for gpi failure
+#	* Documented color changing stuff.
+#	* Now sort the flattened aux file to avoid false recompilation needs
+#	* Added clean-nographics target
+#	* Don't remove self.dvi file if self.aux is missing in the log
+#	* Clarified some code.  Did some very minor adjusting.
+# Chris Monson (2006-04-03):
+#	* Bumped version to 2.0a7
+#	* Added .dvi and .ps files as secondary files.
+#	* Fixed handling of multiple run detection when includeonly is in use.
+#	* Added code to flatten .aux files.
+#	* Added more files as .SECONDARY prerequisites to avoid recompilation.
+#	* Fixed the inputs generation to be much simpler and to use pipes.
+#	* Added the dependency graph directly into the makefile.
+#	* Changed flatten-aux to remove \@writefile \relax \newlabel, etc.
+#	* Undid pipe changes with sed usage (BSD sed doesn't know -f-).
+#	* Added a _check_programs target that tells you what your system has.
+#	* Fixed an error in colorization that made unnecessary errors appear
+#	* Added view targets.
+#	* Updated help text.
+#	* Augmented cookies so that .aux can trigger .bbl and .dvi rebuilds
+#	* Added more informative error handling for dvips and ps2pdf
+# Chris Monson (2006-04-02):
+#	* Bumped version to 2.0a6
+#	* Added indirection to .bbl dependencies to avoid rebuilding .bbl files
+#	* Streamlined the diff invocation to eliminate an existence test
+#	* Removed special shell quote escape variables
+#	* Moved includes to a more prominent location
+#	* Fixed .inputs.make to not contain .aux files
+#	* Fixed embedding to use a file instead of always grepping.
+#	* Added *.make.temp to the list of cleanable files
+#	* Fixed Ruby.  It should now be supported properly.
+#	* Now differentiate between all, default, and buildable files.
+#	* Fixed to bail out on serious errors.
+#	* Revised the handling of includable files.  Still working on it.
+# Chris Monson (2006-03-31):
+#	* Bumped version to 2.0a5
+#	* Fixed a bug with LaTeX error detection (there can be spaces)
+#	* Added .bbl support, simplifying everything and making it more correct
+#	* Refactored some tests that muddy the code
+#	* Did a little cleanup of some shell loops that can safely be make loops
+#	* Added support for graphviz .dot files
+#	* Made _all_programs output easier to read
+#	* Added the ruby support that has long been advertised
+#	* Font embedding was screwed up for PostScript -- now implicit
+#	* Changed the generation of -gray.gpi files to a single command
+#	* Changed any make-generated file that is not included from .d to .make
+# Chris Monson (2006-03-30):
+#	* Bumped version to 2.0a4
+#	* Fixed a bug with very long graphics file names
+#	* Added a todo entry for epsfig support
+#	* Fixed a bug paper size bug: sometimes more than one entry appears
+#	* Fixed DVI build echoing to display the number instead of process ID
+#	* DVI files are now removed on first invocation if ANY file is missing
+#	* Added a simple grayscale approach: if a file ends with -gray.gpi, it
+#		is created from the corresponding .gpi file with a special
+#		comment ##GRAY in its header, which causes coloring to be
+#		turned off.
+#	* Fixed a bug in the handling of .tex.sh files.  For some reason I had
+#		neglected to define file stems for scripted output.
+#	* Removed a trailing ; from the %.graphics dependencies
+#	* Added dvips embedding (I think it works, anyway)
+# Chris Monson (2006-03-29):
+#	* Bumped version to 2.0a3
+#	* Fixed error in make 3.79 with MAKEFILE_LIST usage
+#	* Added the presumed filename to the _version output
+#	* Added a vim macro for converting sed scripts to make commands
+#	* Added gpi dependency support (plotting external files and loading gpi)
+#	* Allow .gpi files to be ignored if called .include.gpi or .nobuild.gpi
+#	* Fixed sed invocations where \+ was used.  BSD sed uses \{1,\}.
+# Chris Monson (2006-03-28):
+#	* Bumped version to 2.0a2
+#	* Added SHELL_DEBUG and VERBOSE options
+#	* Changed the default shell back to /bin/sh (unset, in other words)
+#	* Moved .PHONY declarations closer to their targets
+#	* Moved help text into its own define block to obtain better formatting
+#	* Removed need for double-entry when adding a new program invocation
+#	* Moved .SECONDARY declaration closer to its relevant occurrence
+#	* Commented things more heavily
+#	* Added help text about setting terminal and output in gnuplot
+#	* Created more fine-grained clean targets
+#	* Added a %.graphics target that generates all of %'s graphics
+#	* Killed backward-compatible graphics generation (e.g., eps.gpi=gpi.eps)
+#	* For now, we're just GPL 2, not 3.  Maybe it will change later
+#	* Made the version and svninfo into variables
+# Chris Monson (2006-03-27):
+#	* Bumped version to 2.0a1
+#	* Huge, sweeping changes -- automatic dependencies
+
+# IMPORTANT!
+#
+# When adding to the following list, do not introduce any blank lines.  The
+# list is extracted for documentation using sed and is terminated by a blank
+# line.
+#
+# EXTERNAL PROGRAMS:
+# = ESSENTIAL PROGRAMS =
+# == Basic Shell Utilities ==
+CAT		?= cat
+CP		?= cp -f
+DIFF		?= diff
+ECHO		?= echo
+EGREP		?= egrep
+ENV		?= env
+EXPR		?= expr
+MV		?= mv -f
+SED		?= sed
+SORT		?= sort
+TOUCH		?= touch
+UNIQ		?= uniq
+WHICH		?= which
+XARGS		?= xargs
+SLEEP		?= sleep
+# == LaTeX (tetex-provided) ==
+BIBTEX		?= bibtex
+DVIPS		?= dvips
+LATEX		?= latex
+PDFLATEX	?= pdflatex
+EPSTOPDF	?= epstopdf
+MAKEINDEX	?= makeindex
+KPSEWHICH	?= kpsewhich
+GS		?= gs
+# = OPTIONAL PROGRAMS =
+# == Makefile Color Output ==
+TPUT		?= tput
+# == TeX Generation ==
+PERL		?= perl
+PYTHON		?= python
+RST2LATEX	?= rst2latex.py
+# == EPS Generation ==
+CONVERT		?= convert	# ImageMagick
+DOT		?= dot		# GraphViz
+DOT2TEX		?= dot2tex	# dot2tex - add options (not -o) as needed
+FIG2DEV		?= fig2dev	# XFig
+GNUPLOT		?= gnuplot	# GNUplot
+INKSCAPE	?= inkscape	# Inkscape (svg support)
+XMGRACE		?= xmgrace	# XMgrace
+PNGTOPNM	?= pngtopnm	# From NetPBM - step 1 for png -> eps
+PPMTOPGM	?= ppmtopgm	# From NetPBM - (gray) step 2 for png -> eps
+PNMTOPS		?= pnmtops	# From NetPBM - step 3 for png -> eps
+GUNZIP		?= gunzip	# GZipped EPS
+# == Beamer Enlarged Output ==
+PSNUP		?= psnup
+# == Viewing Stuff ==
+VIEW_POSTSCRIPT	?= gv
+VIEW_PDF	?= xpdf
+VIEW_GRAPHICS	?= display
+
+# Command options for embedding fonts and postscript->pdf conversion
+PS_EMBED_OPTIONS	?= -dPDFSETTINGS=/printer -dEmbedAllFonts=true -dSubsetFonts=true -dMaxSubsetPct=100
+PS_COMPATIBILITY	?= 1.4
+
+# Defaults for GPI
+DEFAULT_GPI_EPS_FONTSIZE	?= 22
+DEFAULT_GPI_PDF_FONTSIZE	?= 12
+
+# Style file for ReST
+RST_STYLE_FILE			?= $(wildcard _rststyle_._include_.tex)
+
+# This ensures that even when echo is a shell builtin, we still use the binary
+# (the builtin doesn't always understand -n)
+FIXED_ECHO	:= $(if $(findstring -n,$(shell $(ECHO) -n)),$(shell which echo),$(ECHO))
+ECHO		:= $(if $(FIXED_ECHO),$(FIXED_ECHO),$(ECHO))
+
+define determine-gnuplot-output-extension
+$(if $(shell $(WHICH) $(GNUPLOT)),
+     $(if $(findstring unknown or ambiguous, $(shell $(GNUPLOT) -e "set terminal pdf" 2>&1)),
+	  eps, pdf),
+     none)
+endef
+
+GNUPLOT_OUTPUT_EXTENSION	?= $(strip $(call determine-gnuplot-output-extension))
+
+# Directory into which we place "binaries" if it exists.
+# Note that this can be changed on the commandline or in Makefile.ini:
+#
+# Command line:
+#   make BINARY_TARGET_DIR=$HOME/pdfs myfile.pdf
+#
+# Also, you can specify a relative directory (relative to the Makefile):
+#   make BINARY_TARGET_DIR=pdfs myfile.pdf
+#
+# Or, you can use Makefile.ini:
+#
+#   BINARY_TARGET_DIR := $(HOME)/bin_out
+#
+BINARY_TARGET_DIR	?= _out_
+
+RESTARTS		:= $(if $(MAKE_RESTARTS),$(MAKE_RESTARTS),0)
+# SH NOTES
+#
+# On some systems, /bin/sh, which is the default shell, is not linked to
+# /bin/bash.  While bash is supposed to be sh-compatible when invoked as sh, it
+# just isn't.  This section details some of the things you have to stay away
+# from to remain sh-compatible.
+#
+#	* File pattern expansion does not work for {}
+#	* [ "$x" = "$y" ] has to be [ x"$x" x"$y" ]
+#	* &> for stderr redirection doesn't work, use 2>&1 instead
+#
+# BSD SED NOTES
+#
+# BSD SED is not very nice compared to GNU sed, but it is the most
+# commonly-invoked sed on Macs (being based on BSD), so we have to cater to
+# it or require people to install GNU sed.  It seems like the GNU
+# requirement isn't too bad since this makefile is really a GNU makefile,
+# but apparently GNU sed is much less common than GNU make in general, so
+# I'm supporting it here.
+#
+# Sad experience has taught me the following about BSD sed:
+#
+# 	* \+ is not understood to mean \{1,\}
+# 	* \| is meaningless (does not branch)
+# 	* \n cannot be used as a substitution character
+# 	* ? does not mean \{0,1\}, but is literal
+# 	* a\ works, but only reliably for a single line if subsequent lines
+# 		have forward slashes in them (as is the case in postscript)
+#
+# For more info (on the Mac) you can consult
+#
+# man -M /usr/share/man re_format
+#
+# And look for the word "Obsolete" near the bottom.
+
+#
+# EXTERNAL PROGRAM DOCUMENTATION SCRIPT
+#
+
+# $(call output-all-programs,[<output file>])
+define output-all-programs
+	[ -f '$(this_file)' ] && \
+	$(SED) \
+		-e '/^[[:space:]]*#[[:space:]]*EXTERNAL PROGRAMS:/,/^$$/!d' \
+		-e '/EXTERNAL PROGRAMS/d' \
+		-e '/^$$/d' \
+		-e '/^[[:space:]]*#/i\ '\
+		-e 's/^[[:space:]]*#[[:space:]][^=]*//' \
+		$(this_file) $(if $1,> '$1',) || \
+	$(ECHO) "Cannot determine the name of this makefile."
+endef
+
+# If they misspell gray, it should still work.
+GRAY	?= $(call get-default,$(GREY),)
+
+#
+# Utility Functions and Definitions
+#
+
+# While not exactly a make function, this vim macro is useful.  It takes a
+# verbatim sed script and converts each line to something suitable in a command
+# context.  Just paste the script's contents into the editor, yank this into a
+# register (starting at '0') and run the macro once for each line of the
+# original script:
+#
+# 0i	-e :s/\$/$$/eg
:s/'/'"'"'/eg
^Ela'A' \:noh
j
+
+# don't call this directly - it is here to avoid calling wildcard more than
+# once in remove-files.
+remove-files-helper	= $(if $1,$(RM) $1,$(sh_true))
+
+# $(call remove-files,file1 file2)
+remove-files		= $(call remove-files-helper,$(wildcard $1))
+
+# Removes all cleanable files in the given list
+# $(call clean-files,file1 file2 file3 ...)
+# Works exactly like remove-files, but filters out files in $(neverclean)
+clean-files		= \
+	$(call remove-files-helper,$(call cleanable-files,$(wildcard $1)))
+
+# Outputs all generated files to STDOUT, along with some others that are
+# created by these (e.g., .idx files end up producing .ilg and .ind files).
+# Discovered by reading *.fls OUTPUT lines and producing corresponding .ind
+# filenames as needed.
+#
+# $(call get-generated-names,<source recorder file (*.fls)>)
+define get-generated-names
+[ -f '$1' ] && \
+$(SED) \
+	-e '/^OUTPUT /{' \
+	-e '  s///' \
+	-e '  p' \
+	-e '  s/\.idx/\.ind/p' \
+	-e '  s/\.ind/\.ilg/p' \
+	-e '}' \
+	-e 'd' \
+	'$1' \
+| $(SORT) | $(UNIQ)
+endef
+
+# This removes files without checking whether they are there or not.  This
+# sometimes has to be used when the file is created by a series of shell
+# commands, but there ends up being a race condition: make doesn't know about
+# the file generation as quickly as the system does, so $(wildcard ...) doesn't
+# work right.  Blech.
+# $(call remove-temporary-files,filenames)
+remove-temporary-files	= $(if $1,$(RM) $1,:)
+
+# Create an identifier from a file name
+# $(call cleanse-filename,filename)
+cleanse-filename	= $(subst .,_,$(subst /,__,$1))
+
+# Escape dots
+# $(call escape-dots,str)
+escape-dots		= $(subst .,\\.,$1)
+
+# Test that a file exists
+# $(call test-exists,file)
+test-exists		= [ -e '$1' ]
+
+# $(call move-files,source,destination)
+move-if-exists		= $(call test-exists,$1) && $(MV) '$1' '$2'
+
+# Copy file1 to file2 only if file2 doesn't exist or they are different
+# $(call copy-if-different,sfile,dfile)
+copy-if-different	= $(call test-different,$1,$2) && $(CP) '$1' '$2'
+copy-if-exists		= $(call test-exists,$1) && $(CP) '$1' '$2'
+move-if-different	= $(call test-different,$1,$2) && $(MV) '$1' '$2'
+replace-if-different-and-remove	= \
+	$(call test-different,$1,$2) \
+	&& $(MV) '$1' '$2' \
+	|| $(call remove-files,'$1')
+
+# Note that $(DIFF) returns success when the files are the SAME....
+# $(call test-different,sfile,dfile)
+test-different		= ! $(DIFF) -q '$1' '$2' >/dev/null 2>&1
+test-exists-and-different	= \
+	$(call test-exists,$2) && $(call test-different,$1,$2)
+
+# Return value 1, or value 2 if value 1 is empty
+# $(call get-default,<possibly empty arg>,<default value if empty>)
+get-default	= $(if $1,$1,$2)
+
+# Copy a file and log what's going on
+# $(call copy-with-logging,<source>,<target>)
+define copy-with-logging
+if [ -d '$2/' ]; then \
+	if $(CP) '$1' '$2/'; then \
+		$(ECHO) "$(C_INFO)Copied '$1' to '$2/'$(C_RESET)"; \
+	else \
+		$(ECHO) "$(C_ERROR)Failed to copy '$1' to '$2/'$(C_RESET)"; \
+	fi; \
+fi
+endef
+
+# Gives a reassuring message about the failure to find include files
+# $(call include-message,<list of include files>)
+define include-message
+$(strip \
+$(if $(filter-out $(wildcard $1),$1),\
+	$(shell $(ECHO) \
+	"$(C_INFO)NOTE: You may ignore warnings about the"\
+	"following files:" >&2;\
+	$(ECHO) >&2; \
+	$(foreach s,$(filter-out $(wildcard $1),$1),$(ECHO) '     $s' >&2;)\
+	$(ECHO) "$(C_RESET)" >&2)
+))
+endef
+# Characters that are hard to specify in certain places
+space		:= $(empty) $(empty)
+colon		:= \:
+comma		:= ,
+
+# Useful shell definitions
+sh_true		:= :
+sh_false	:= ! :
+
+# Clear out the standard interfering make suffixes
+.SUFFIXES:
+
+# Turn off forceful rm (RM is usually mapped to rm -f)
+ifdef SAFE_RM
+RM	:= rm
+endif
+
+# Turn command echoing back on with VERBOSE=1
+ifndef VERBOSE
+QUIET	:= @
+endif
+
+# Turn on shell debugging with SHELL_DEBUG=1
+# (EVERYTHING is echoed, even $(shell ...) invocations)
+ifdef SHELL_DEBUG
+SHELL	+= -x
+endif
+
+# Get the name of this makefile (always right in 3.80, often right in 3.79)
+# This is only really used for documentation, so it isn't too serious.
+ifdef MAKEFILE_LIST
+this_file	:= $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+else
+this_file	:= $(wildcard GNUmakefile makefile Makefile)
+endif
+
+# Terminal color definitions
+
+REAL_TPUT 	:= $(if $(NO_COLOR),,$(shell $(WHICH) $(TPUT)))
+
+# $(call get-term-code,codeinfo)
+# e.g.,
+# $(call get-term-code,setaf 0)
+get-term-code = $(if $(REAL_TPUT),$(shell $(REAL_TPUT) $1),)
+
+black	:= $(call get-term-code,setaf 0)
+red	:= $(call get-term-code,setaf 1)
+green	:= $(call get-term-code,setaf 2)
+yellow	:= $(call get-term-code,setaf 3)
+blue	:= $(call get-term-code,setaf 4)
+magenta	:= $(call get-term-code,setaf 5)
+cyan	:= $(call get-term-code,setaf 6)
+white	:= $(call get-term-code,setaf 7)
+bold	:= $(call get-term-code,bold)
+uline	:= $(call get-term-code,smul)
+reset	:= $(call get-term-code,sgr0)
+
+#
+# User-settable definitions
+#
+LATEX_COLOR_WARNING	?= magenta
+LATEX_COLOR_ERROR	?= red
+LATEX_COLOR_INFO	?= green
+LATEX_COLOR_UNDERFULL	?= magenta
+LATEX_COLOR_OVERFULL	?= red bold
+LATEX_COLOR_PAGES	?= bold
+LATEX_COLOR_BUILD	?= cyan
+LATEX_COLOR_GRAPHIC	?= yellow
+LATEX_COLOR_DEP		?= green
+LATEX_COLOR_SUCCESS	?= green bold
+LATEX_COLOR_FAILURE	?= red bold
+
+# Gets the real color from a simple textual definition like those above
+# $(call get-color,ALL_CAPS_COLOR_NAME)
+# e.g., $(call get-color,WARNING)
+get-color	= $(subst $(space),,$(foreach c,$(LATEX_COLOR_$1),$($c)))
+
+#
+# STANDARD COLORS
+#
+C_WARNING	:= $(call get-color,WARNING)
+C_ERROR		:= $(call get-color,ERROR)
+C_INFO		:= $(call get-color,INFO)
+C_UNDERFULL	:= $(call get-color,UNDERFULL)
+C_OVERFULL	:= $(call get-color,OVERFULL)
+C_PAGES		:= $(call get-color,PAGES)
+C_BUILD		:= $(call get-color,BUILD)
+C_GRAPHIC	:= $(call get-color,GRAPHIC)
+C_DEP		:= $(call get-color,DEP)
+C_SUCCESS	:= $(call get-color,SUCCESS)
+C_FAILURE	:= $(call get-color,FAILURE)
+C_RESET		:= $(reset)
+
+#
+# PRE-BUILD TESTS
+#
+
+# Check that clean targets are not combined with other targets (weird things
+# happen, and it's not easy to fix them)
+hascleangoals	:= $(if $(sort $(filter clean clean-%,$(MAKECMDGOALS))),1)
+hasbuildgoals	:= $(if $(sort $(filter-out clean clean-%,$(MAKECMDGOALS))),1)
+ifneq "$(hasbuildgoals)" ""
+ifneq "$(hascleangoals)" ""
+$(error $(C_ERROR)Clean and build targets specified together$(C_RESET)))
+endif
+endif
+
+#
+# VARIABLE DECLARATIONS
+#
+
+# Names of sed scripts that morph gnuplot files -- only the first found is used
+GNUPLOT_SED	:= global-gpi.sed gnuplot.sed
+GNUPLOT_GLOBAL	:= global._include_.gpi gnuplot.global
+
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+default_graphic_extension	?= eps
+latex_build_program		?= $(LATEX)
+build_target_extension		?= dvi
+hyperref_driver_pattern		?= hdvips
+hyperref_driver_error		?= Using dvips: specify ps2pdf in the hyperref options.
+else
+default_graphic_extension	?= pdf
+latex_build_program		?= $(PDFLATEX)
+build_target_extension		?= pdf
+hyperref_driver_pattern		?= hpdf.*
+hyperref_driver_error		?= Using pdflatex: specify pdftex in the hyperref options (or leave it blank).
+endif
+
+# Files of interest
+all_files.tex		?= $(wildcard *.tex)
+all_files.tex.sh	?= $(wildcard *.tex.sh)
+all_files.tex.pl	?= $(wildcard *.tex.pl)
+all_files.tex.py	?= $(wildcard *.tex.py)
+all_files.rst		?= $(wildcard *.rst)
+all_files.fig		?= $(wildcard *.fig)
+all_files.gpi		?= $(wildcard *.gpi)
+all_files.dot		?= $(wildcard *.dot)
+all_files.xvg		?= $(wildcard *.xvg)
+all_files.svg		?= $(wildcard *.svg)
+all_files.png		?= $(wildcard *.png)
+all_files.jpg		?= $(wildcard *.jpg)
+all_files.eps.gz	?= $(wildcard *.eps.gz)
+all_files.eps		?= $(wildcard *.eps)
+
+# Utility function for obtaining all files not specified in $(neverclean)
+# $(call cleanable-files,file1 file2 file3 ...)
+# Returns the list of files that is not in $(wildcard $(neverclean))
+cleanable-files = $(filter-out $(wildcard $(neverclean)), $1)
+
+# Utility function for getting all .$1 files that are to be ignored
+#  * files listed in $(includes.$1)
+#  * files not listed in $(onlysources.$1) if it is defined
+ignore_files = \
+  $(includes.$1) \
+  $(if $(onlysources.$1),$(filter-out $(onlysources.$1), $(all_files.$1)))
+
+# Patterns to never be allowed as source targets
+ignore_patterns	:= %._include_
+
+# Patterns allowed as source targets but not included in 'all' builds
+nodefault_patterns := %._nobuild_ $(ignore_patterns)
+
+# Utility function for getting targets suitable building
+# $(call filter-buildable,suffix)
+filter-buildable	= \
+	$(filter-out $(call ignore_files,$1) \
+		$(addsuffix .$1,$(ignore_patterns)),$(all_files.$1))
+
+# Utility function for getting targets suitable for 'all' builds
+# $(call filter-default,suffix)
+filter-default		= \
+	$(filter-out $(call ignore_files,$1) \
+		$(addsuffix .$1,$(nodefault_patterns)),$(all_files.$1))
+
+# Top level sources that can be built even when they are not by default
+files.tex	:= $(call filter-buildable,tex)
+files.tex.sh	:= $(call filter-buildable,tex.sh)
+files.tex.pl	:= $(call filter-buildable,tex.pl)
+files.tex.py	:= $(call filter-buildable,tex.py)
+files.rst	:= $(call filter-buildable,rst)
+files.gpi	:= $(call filter-buildable,gpi)
+files.dot	:= $(call filter-buildable,dot)
+files.fig	:= $(call filter-buildable,fig)
+files.xvg	:= $(call filter-buildable,xvg)
+files.svg	:= $(call filter-buildable,svg)
+files.png	:= $(call filter-buildable,png)
+files.jpg	:= $(call filter-buildable,jpg)
+files.eps.gz	:= $(call filter-buildable,eps.gz)
+
+# Make all pstex targets secondary.  The pstex_t target requires the pstex
+# target, and nothing else really depends on it, so it often gets deleted.
+# This avoids that by allowing *all* fig files to be pstex targets, which is
+# perfectly valid and causes no problems even if they're going to become eps
+# files in the end.
+.SECONDARY:	$(patsubst %.fig,%.pstex,$(files.fig))
+
+# Top level sources that are built by default targets
+default_files.tex	:= $(call filter-default,tex)
+default_files.tex.sh	:= $(call filter-default,tex.sh)
+default_files.tex.pl	:= $(call filter-default,tex.pl)
+default_files.tex.py	:= $(call filter-default,tex.py)
+default_files.rst	:= $(call filter-default,rst)
+default_files.gpi	:= $(call filter-default,gpi)
+default_files.dot	:= $(call filter-default,dot)
+default_files.fig	:= $(call filter-default,fig)
+default_files.xvg	:= $(call filter-default,xvg)
+default_files.svg	:= $(call filter-default,svg)
+default_files.png	:= $(call filter-default,png)
+default_files.jpg	:= $(call filter-default,jpg)
+default_files.eps.gz	:= $(call filter-default,eps.gz)
+
+# Utility function for creating larger lists of files
+# $(call concat-files,suffixes,[prefix])
+concat-files	= $(foreach s,$1,$($(if $2,$2_,)files.$s))
+
+# Useful file groupings
+all_files_source	:= $(call concat-files,tex,all)
+all_files_scripts	:= $(call concat-files,tex.sh tex.pl tex.py rst,all)
+
+.PHONY: $(all_files_scripts)
+
+default_files_source	:= $(call concat-files,tex,default)
+default_files_scripts	:= $(call concat-files,tex.sh tex.pl tex.py rst,default)
+
+files_source	:= $(call concat-files,tex)
+files_scripts	:= $(call concat-files,tex.sh tex.pl tex.py rst)
+
+# Utility function for obtaining stems
+# $(call get-stems,suffix,[prefix])
+get-stems	= $(sort $($(if $2,$2_,)files.$1:%.$1=%))
+
+# List of all stems (including ._include_ and ._nobuild_ file stems)
+all_stems.tex		:= $(call get-stems,tex,all)
+all_stems.tex.sh	:= $(call get-stems,tex.sh,all)
+all_stems.tex.pl	:= $(call get-stems,tex.pl,all)
+all_stems.tex.py	:= $(call get-stems,tex.py,all)
+all_stems.rst		:= $(call get-stems,rst,all)
+all_stems.fig		:= $(call get-stems,fig,all)
+all_stems.gpi		:= $(call get-stems,gpi,all)
+all_stems.dot		:= $(call get-stems,dot,all)
+all_stems.xvg		:= $(call get-stems,xvg,all)
+all_stems.svg		:= $(call get-stems,svg,all)
+all_stems.png		:= $(call get-stems,png,all)
+all_stems.jpg		:= $(call get-stems,jpg,all)
+all_stems.eps.gz	:= $(call get-stems,eps.gz,all)
+all_stems.eps		:= $(call get-stems,eps,all)
+
+# List of all default stems (all default PDF targets):
+default_stems.tex		:= $(call get-stems,tex,default)
+default_stems.tex.sh		:= $(call get-stems,tex.sh,default)
+default_stems.tex.pl		:= $(call get-stems,tex.pl,default)
+default_stems.tex.py		:= $(call get-stems,tex.py,default)
+default_stems.rst		:= $(call get-stems,rst,default)
+default_stems.fig		:= $(call get-stems,fig,default)
+default_stems.gpi		:= $(call get-stems,gpi,default)
+default_stems.dot		:= $(call get-stems,dot,default)
+default_stems.xvg		:= $(call get-stems,xvg,default)
+default_stems.svg		:= $(call get-stems,svg,default)
+default_stems.png		:= $(call get-stems,png,default)
+default_stems.jpg		:= $(call get-stems,jpg,default)
+default_stems.eps.gz		:= $(call get-stems,eps.gz,default)
+
+# List of all stems (all possible bare PDF targets created here):
+stems.tex		:= $(call get-stems,tex)
+stems.tex.sh		:= $(call get-stems,tex.sh)
+stems.tex.pl		:= $(call get-stems,tex.pl)
+stems.tex.py		:= $(call get-stems,tex.py)
+stems.rst		:= $(call get-stems,rst)
+stems.fig		:= $(call get-stems,fig)
+stems.gpi		:= $(call get-stems,gpi)
+stems.dot		:= $(call get-stems,dot)
+stems.xvg		:= $(call get-stems,xvg)
+stems.svg		:= $(call get-stems,svg)
+stems.png		:= $(call get-stems,png)
+stems.jpg		:= $(call get-stems,jpg)
+stems.eps.gz		:= $(call get-stems,eps.gz)
+
+# Utility function for creating larger lists of stems
+# $(call concat-stems,suffixes,[prefix])
+concat-stems	= $(sort $(foreach s,$1,$($(if $2,$2_,)stems.$s)))
+
+# The most likely to be source but not finished product go first
+graphic_source_extensions	:= fig \
+				   gpi \
+				   xvg \
+				   svg \
+				   dot \
+				   eps.gz
+
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+graphic_source_extensions	+= png jpg
+graphic_target_extensions	:= eps ps
+else
+graphic_source_extensions	+= eps
+graphic_target_extensions	:= pdf png jpg mps tif
+endif
+
+all_stems_source	:= $(call concat-stems,tex,all)
+all_stems_script	:= $(call concat-stems,tex.sh tex.pl tex.py rst,all)
+all_stems_graphic	:= $(call concat-stems,$(graphic_source_extensions),all)
+all_stems_ss		:= $(sort $(all_stems_source) $(all_stems_script))
+all_stems_sg		:= $(sort $(all_stems_script))
+all_stems_ssg		:= $(sort $(all_stems_ss))
+
+default_stems_source	:= $(call concat-stems,tex,default)
+default_stems_script	:= $(call concat-stems,tex.sh tex.pl tex.py rst,default)
+default_stems_ss	:= $(sort $(default_stems_source) $(default_stems_script))
+default_stems_sg	:= $(sort $(default_stems_script))
+default_stems_ssg	:= $(sort $(default_stems_ss))
+
+stems_source		:= $(call concat-stems,tex)
+stems_script		:= $(call concat-stems,tex.sh tex.pl tex.py rst)
+stems_graphic		:= $(call concat-stems,$(graphic_source_extensions))
+stems_gg		:= $(sort $(stems_graphic))
+stems_ss		:= $(sort $(stems_source) $(stems_script))
+stems_sg		:= $(sort $(stems_script))
+stems_ssg		:= $(sort $(stems_ss))
+
+# Calculate names that can generate the need for an include file.  We can't
+# really do this with patterns because it's too easy to screw up, so we create
+# an exhaustive list.
+allowed_source_suffixes	:= \
+	pdf \
+	ps \
+	dvi \
+	ind \
+	nls \
+	bbl \
+	aux \
+	aux.make \
+	d \
+	auxbbl.make \
+	_graphics \
+	_show
+allowed_source_patterns		:= $(addprefix %.,$(allowed_source_suffixes))
+
+allowed_graphic_suffixes	:= \
+	pdf \
+	eps \
+	gpihead.make \
+	gpi.d
+allowed_graphic_patterns	:= $(addprefix %.,$(allowed_graphic_suffixes))
+
+# All targets allowed to build documents
+allowed_source_targets	:= \
+	$(foreach suff,$(allowed_source_suffixes),\
+	$(addsuffix .$(suff),$(stems_ssg)))
+
+# All targets allowed to build graphics
+allowed_graphic_targets	:= \
+	$(foreach suff,$(allowed_graphic_suffixes),\
+	$(addsuffix .$(suff),$(stems_gg)))
+
+# All targets that build multiple documents (like 'all')
+allowed_batch_source_targets	:= \
+	all \
+	all-pdf \
+	all-ps \
+	all-dvi \
+	all-bbl \
+	all-ind \
+	all-gls \
+	all-nls \
+	show
+
+# All targets that build multiple graphics (independent of document)
+allowed_batch_graphic_targets	:= \
+	all-graphics \
+	all-pstex \
+	all-dot2tex \
+	show-graphics
+
+# Now we figure out which stuff is available as a make target for THIS RUN.
+real_goals	:= $(call get-default,$(filter-out _includes,$(MAKECMDGOALS)),\
+			all)
+
+specified_source_targets	:= $(strip \
+	$(filter $(allowed_source_targets) $(stems_ssg),$(real_goals)) \
+	)
+
+specified_batch_source_targets	:= $(strip \
+	$(filter $(allowed_batch_source_targets),$(real_goals)) \
+	)
+
+specified_graphic_targets	:= $(strip \
+	$(filter $(allowed_graphic_targets),$(real_goals)) \
+	)
+
+specified_batch_graphic_targets	:= $(strip \
+	$(filter $(allowed_batch_graphic_targets),$(real_goals)) \
+	)
+
+specified_gpi_targets	:= $(patsubst %.gpi,%.$(default_graphic_extension),\
+	$(filter $(patsubst %.$(default_graphic_extension),%.gpi,$(specified_graphic_targets)),\
+		$(all_files.gpi)) \
+	)
+
+# Determine which .d files need including from the information gained above.
+# This is done by first checking whether a batch target exists.  If it does,
+# then all *default* stems are used to create possible includes (nobuild need
+# not apply for batch status).  If no batch targets exist, then the individual
+# targets are considered and appropriate includes are taken from them.
+source_stems_to_include	:= \
+	$(sort\
+	$(if $(specified_batch_source_targets),\
+		$(default_stems_ss),\
+		$(foreach t,$(specified_source_targets),\
+		$(foreach p,$(allowed_source_patterns),\
+			$(patsubst $p,%,$(filter $p $(stems_ssg),$t)) \
+		)) \
+	))
+
+# Determine which .gpi.d files are needed using the above information.  We
+# first check whether a batch target is specified, then check individual
+# graphics that may have been specified.
+graphic_stems_to_include	:= \
+	$(sort\
+	$(if $(specified_batch_graphic_targets),\
+		$(default_stems.gpi),\
+		$(foreach t,$(specified_gpi_targets),\
+		$(foreach p,$(allowed_graphic_patterns),\
+			$(patsubst $p,%,$(filter $p,$t)) \
+		)) \
+	))
+
+# All dependencies for the 'all' targets
+all_pdf_targets		:= $(addsuffix .pdf,$(stems_ssg))
+all_ps_targets		:= $(addsuffix .ps,$(stems_ssg))
+all_dvi_targets		:= $(addsuffix .dvi,$(stems_ssg))
+all_tex_targets		:= $(addsuffix .tex,$(stems_sg))
+all_d_targets		:= $(addsuffix .d,$(stems_ssg))
+all_graphics_targets	:= $(addsuffix .$(default_graphic_extension),$(stems_gg))
+intermediate_graphics_targets	:= $(if $(filter pdf,$(default_graphic_extension)),$(addsuffix .eps,$(stems_gg)),)
+all_pstex_targets	:= $(addsuffix .pstex_t,$(stems.fig))
+all_dot2tex_targets	:= $(addsuffix .dot_t,$(stems.dot))
+
+all_known_graphics	:= $(sort $(all_graphics_targets) $(wildcard *.$(default_graphic_extension)))
+
+default_pdf_targets	:= $(addsuffix .pdf,$(default_stems_ss))
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+default_ps_targets	:= $(addsuffix .ps,$(default_stems_ss))
+default_dvi_targets	:= $(addsuffix .dvi,$(default_stems_ss))
+pre_pdf_extensions	:= dvi ps
+endif
+
+# Extensions generated by LaTeX invocation that can be removed when complete
+rm_ext		:= \
+	log *.log aux $(pre_pdf_extensions) pdf blg bbl out nav snm toc lof lot lol pfg \
+	fls vrb idx ind ilg glg glo gls lox nls nlo nlg brf mtc maf brf
+backup_patterns	:= *~ *.bak *.backup body.tmp head.tmp
+
+graph_stem	:= _graph
+
+# All LaTeX-generated files that can be safely removed
+
+rm_tex := \
+	$(foreach e,$(rm_ext),$(addsuffix .$e,$(all_stems_source))) \
+	$(foreach e,$(rm_ext) tex,$(addsuffix .$e,$(all_stems_sg))) \
+	$(addsuffix .log,$(all_ps_targets) $(all_pdf_targets)) \
+	$(addsuffix .*.log,$(stems_graphic))
+
+# These are the files that will affect .gpi transformation for all .gpi files.
+#
+# Use only the first one found.  Backward compatible values are at the end.
+# Note that we use foreach, even though wildcard also returns a list, to ensure
+# that the order in the uppercase variables is preserved.  Directory listings
+# provide no such guarantee, so we avoid relying on them.
+gpi_sed		:= $(strip \
+	$(firstword $(foreach f,$(GNUPLOT_SED),$(wildcard $f))))
+gpi_global	:= $(strip \
+	$(firstword $(foreach f,$(GNUPLOT_GLOBAL),$(wildcard $f))))
+
+#
+# Functions used in generating output
+#
+
+# Outputs all source dependencies to stdout.  The first argument is the file to
+# be parsed, the second is a list of files that will show up as dependencies in
+# the new .d file created here.
+#
+# NOTE: BSD sed does not understand \|, so we have to do something more
+# clunky to extract suitable extensions.
+#
+# Also, we do a little bit of funny rewriting up front (TARGETS=) to make sure
+# that we can properly backslash-escape spaces in file names (e.g, on Cygwin
+# for tex distributions that have "Program Files" in their name).
+#
+# $(call get-inputs,<parsed file>,<target files>)
+define get-inputs
+$(SED) \
+-e '/^INPUT/!d' \
+-e 's!^INPUT \(\./\)\{0,1\}!!' \
+-e 's/[[:space:]]/\\ /g' \
+-e 's/\(.*\)\.aux$$/\1.tex/' \
+-e '/\.tex$$/b addtargets' \
+-e '/\.cls$$/b addtargets' \
+-e '/\.sty$$/b addtargets' \
+-e '/\.pstex_t$$/b addtargets' \
+-e '/\.dot_t$$/b addtargets' \
+-e 'd' \
+-e ':addtargets' \
+-e 's/^/$2: /' \
+$1 | $(SORT) | $(UNIQ)
+endef
+
+# $(call get-missing-inputs,<log file>,<target files>)
+define get-missing-inputs
+$(SED) \
+-e '$$ b para' \
+-e '/^$$/b para' \
+-e 'H' \
+-e 'd' \
+-e ':para' \
+-e 'x' \
+-e '/^$$/d' \
+-e 's/^\n*//' \
+-e '/^! LaTeX Error: File /{' \
+-e '  s/^/::DOUBLE_PARAGRAPH::/' \
+-e '  h' \
+-e '  d' \
+-e '}' \
+-e 's/^::DOUBLE_PARAGRAPH:://' \
+-e '/Default extension: /!d' \
+-e 's/[[:space:]]\{1,\}/ /g' \
+-e 's/\n\{1,\}/ /g' \
+-e 's/^.*File `//' \
+-e 's/'"'"' not found\..*//' \
+-e '/\.tex/!s/$$/.tex/' \
+-e 's/[[:space:]]/\\ /g' \
+-e 'h' \
+-e 's/.*/# MISSING input "&" - (presence of comment affects build)/' \
+-e 'p' \
+-e 's/.*//' \
+-e 'x' \
+-e 's/^/$2: /' \
+$1 | $(SORT) | $(UNIQ)
+endef
+
+# Get source file for specified graphics stem.
+#
+# $(call graphics-source,<stem>)
+define graphics-source
+$(strip $(firstword \
+	$(wildcard \
+		$(addprefix $1.,\
+			$(graphic_source_extensions))) \
+	$1 \
+))
+endef
+
+# Get the target file for the specified graphics file/stem
+#
+# $(call graphics-target,<stem>)
+define graphics-target
+$(strip $(if 	$(filter $(addprefix %.,$(graphic_target_extensions)),$1), $1,
+	$(firstword $(patsubst $(addprefix %.,$(graphic_source_extensions) $(graphic_target_extensions)), %, $1).$(default_graphic_extension) $1.$(default_graphic_extension))))
+endef
+
+# Outputs all of the graphical dependencies to stdout.  The first argument is
+# the stem of the source file being built, the second is a list of suffixes
+# that will show up as dependencies in the generated .d file.
+#
+# Note that we try to escape spaces in filenames where possible.  We have to do
+# it with three backslashes so that as the name percolates through the makefile
+# it eventually ends up with the proper escaping when the build rule is found.
+# Ugly, but it appears to work.  Note that graphicx doesn't allow filenames
+# with spaces, so this could in many ways be moot unless you're using something
+# like grffile.
+#
+# For pdflatex, we really need the missing file to be specified without an
+# extension, otherwise compilation barfs on the first missing file.  Truly
+# annoying, but there you have it.
+#
+# It turns out that the graphics errors, although they have lines with empty
+# space, are only made of two paragraphs.  So, we just use some sed magic to
+# get everything into paragraphs, detect when it's a paragraph that interests
+# us, and double it up.  Then we get the filename only if we're missing
+# extensions (a sign that it's graphicx complaining).
+#
+# $(call get-graphics,<target file stem>)
+#.log,$(addprefix $*.,d $(build_target_extension) _graphics)
+define get-graphics
+$(SED) \
+-e '$$ b para' \
+-e '/^$$/b para' \
+-e 'H' \
+-e 'd' \
+-e ':para' \
+-e 'x' \
+-e '/^$$/d' \
+-e 's/^\n*//' \
+-e '/^! LaTeX Error: File `/{' \
+-e '  s/^/::DOUBLE_PARAGRAPH::/' \
+-e '  h' \
+-e '  d' \
+-e '}' \
+-e 's/^::DOUBLE_PARAGRAPH:://' \
+-e '/could not locate the file with any of these extensions:/{' \
+-e '  s/\n\{1,\}/ /g' \
+-e '  s/[[:space:]]\{1,\}/ /g' \
+-e '  s/^.*File `//' \
+-e '  s/'"'"' not found\..*//' \
+-e '  h' \
+-e '  s/.*/# MISSING stem "&" - (presence of comment affects build)/' \
+-e '  p' \
+-e '  g' \
+-e '  b addtargets' \
+-e '}' \
+-e '/.*File: \(.*\) Graphic file (type [^)]*).*/{' \
+-e '  s//\1/' \
+-e '  b addtargets' \
+-e '}' \
+-e 'd' \
+-e ':addtargets' \
+-e 's/[[:space:]]/\\\\\\&/g' \
+-e 'h' \
+-e 's/.*/-include &.gpi.d/' \
+-e 'p' \
+-e 'g' \
+-e 's/.*/$(addprefix $1,.d): $$$$(call graphics-source,&)/' \
+-e 'p' \
+-e 's/.*//' \
+-e 'x' \
+-e 's/.*/$(addprefix $1.,$(build_target_extension) _graphics): $$$$(call graphics-target,&)/' \
+-e 'p' \
+-e 'd' \
+$*.log
+endef
+
+# Checks for build failure due to pstex inclusion, and gives instructions.
+#
+# $(call die-on-pstexs,<parsed file>)
+define die-on-pstexs
+if $(EGREP) -q '^! LaTeX Error: File .*\.pstex.* not found' $1; then \
+	$(ECHO) "$(C_ERROR)Missing pstex_t file(s)$(C_RESET)"; \
+	$(ECHO) "$(C_ERROR)Please run$(C_RESET)"; \
+	$(ECHO) "$(C_ERROR)  make all-pstex$(C_RESET)"; \
+	$(ECHO) "$(C_ERROR)before proceeding.$(C_RESET)"; \
+	exit 1; \
+fi
+endef
+
+# Checks for build failure due to dot2tex, and gives instructions.
+#
+# $(call die-on-dot2tex,<parsed file>)
+define die-on-dot2tex
+if $(EGREP) -q ' LaTeX Error: File .*\.dot_t.* not found' $1; then \
+	$(ECHO) "$(C_ERROR)Missing dot_t file(s)$(C_RESET)"; \
+	$(ECHO) "$(C_ERROR)Please run$(C_RESET)"; \
+	$(ECHO) "$(C_ERROR)  make all-dot2tex$(C_RESET)"; \
+	$(ECHO) "$(C_ERROR)before proceeding.$(C_RESET)"; \
+	exit 1; \
+fi
+endef
+
+# Checks for the existence of a .aux file, and dies with an error message if it
+# isn't there.  Note that we pass the file stem in, not the full filename,
+# e.g., to check for foo.aux, we call it thus: $(call die-on-no-aux,foo)
+#
+# $(call die-on-no-aux,<aux stem>)
+define die-on-no-aux
+if [ ! -e '$1.aux' ]; then \
+	$(call colorize-latex-errors,$1.log); \
+	exit 1; \
+fi
+endef
+
+# Outputs all index files to stdout.  Arg 1 is the source file stem, arg 2 is
+# the list of targets for the discovered dependency.
+#
+# $(call get-log-index,<log file stem>,<target files>)
+define get-log-index
+$(SED) \
+-e 's/^No file \(.*\.ind\)\.$$/TARGETS=\1/' \
+-e 's/^No file \(.*\.[gn]ls\)\.$$/TARGETS=\1/' \
+-e 's/[[:space:]]/\\&/g' \
+-e '/^TARGETS=/{' \
+-e '  h' \
+-e '  s/^TARGETS=/$2: /p' \
+-e '  g' \
+-e '  s/^TARGETS=\(.*\)/\1: $1.tex/p' \
+-e '}' \
+-e 'd' \
+'$1.log' | $(SORT) | $(UNIQ)
+endef
+
+
+# Outputs all bibliography files to stdout.  Arg 1 is the source stem, arg 2 is
+# a list of targets for each dependency found.
+#
+# The script kills all lines that do not contain bibdata.  Remaining lines have
+# the \bibdata macro and delimiters removed to create a dependency list.  A
+# trailing comma is added, then all adjacent commas are collapsed into a single
+# comma.  Then commas are replaced with the string .bib[space], and the
+# trailing space is killed off.  Finally, all filename spaces are escaped.
+# This produces a list of space-delimited .bib filenames, which is what the
+# make dep file expects to see.
+#
+# Note that we give kpsewhich a bogus argument so that a failure of sed to
+# produce output will not cause an error.
+#
+# $(call get-bibs,<aux file>,<targets>)
+define get-bibs
+$(SED) \
+-e '/^\\bibdata/!d' \
+-e 's/\\bibdata{\([^}]*\)}/\1,/' \
+-e 's/,\{2,\}/,/g' \
+-e 's/[[:space:]]/\\&/g' \
+-e 's/,/.bib /g' \
+-e 's/ \{1,\}$$//' \
+$1 | $(XARGS) $(KPSEWHICH) '#######' | \
+$(SED) \
+-e 's/^/$2: /' | \
+\$(SORT) | $(UNIQ)
+endef
+
+# Makes a an aux file that only has stuff relevant to the target in it
+# $(call make-auxtarget-file,<flattened-aux>,<new-aux>)
+define make-auxtarget-file
+$(SED) \
+-e '/^\\newlabel/!d' \
+$1 > $2
+endef
+
+# Makes an aux file that only has stuff relevant to the bbl in it
+# $(call make-auxbbl-file,<flattened-aux>,<new-aux>)
+define make-auxbbl-file
+$(SED) \
+-e '/^\\newlabel/d' \
+$1 > $2
+endef
+
+# Makes a .gpi.d file from a .gpi file
+# $(call make-gpi-d,<.gpi>,<.gpi.d>)
+define make-gpi-d
+$(ECHO) '# vim: ft=make' > $2; \
+$(ECHO) 'ifndef INCLUDED_$(call cleanse-filename,$2)' >> $2; \
+$(ECHO) 'INCLUDED_$(call cleanse-filename,$2) := 1' >> $2; \
+$(call get-gpi-deps,$1,$(addprefix $(2:%.gpi.d=%).,$(GNUPLOT_OUTPUT_EXTENSION) gpi.d)) >> $2; \
+$(ECHO) 'endif' >> $2;
+endef
+
+# Parse .gpi files for data and loaded dependencies, output to stdout
+#
+# The sed script here tries to be clever about obtaining valid
+# filenames from the gpi file.  It assumes that the plot command starts its own
+# line, which is not too difficult a constraint to satisfy.
+#
+# This command script also generates 'include' directives for every 'load'
+# command in the .gpi file.  The load command must appear on a line by itself
+# and the file it loads must have the suffix .gpi.  If you don't want it to be
+# compiled when running make graphics, then give it a suffix of ._include_.gpi.
+#
+# $(call get-gpi-deps,<gpi file>,<targets>)
+define get-gpi-deps
+$(SED) \
+-e '/^[[:space:]]*s\{0,1\}plot/,/[^\\]$$/{' \
+-e ' H' \
+-e ' /[^\\]$$/{' \
+-e '  s/.*//' \
+-e '  x' \
+-e '  s/\\\{0,1\}\n//g' \
+-e '  s/^[[:space:]]*s\{0,1\}plot[[:space:]]*\(\[[^]]*\][[:space:]]*\)*/,/' \
+-e '  s/[[:space:]]*\(['\''"][^'\''"]*['\''"]\)\{0,1\}[^,]*/\1/g' \
+-e '  s/,['\''"]-\{0,1\}['\''"]//g' \
+-e '  s/[,'\''"]\{1,\}/ /g' \
+-e '  s!.*!$2: &!' \
+-e '  p' \
+-e ' }' \
+-e ' d' \
+-e '}' \
+-e 's/^[[:space:]]*load[[:space:]]*['\''"]\([^'\''"]*\.gpi\)['\''"].*$$/-include \1.d/p' \
+-e 'd' \
+$1
+endef
+
+# Colorizes real, honest-to-goodness LaTeX errors that can't be overcome with
+# recompilation.
+#
+# Note that we only ignore file not found errors for things that we know how to
+# build, like graphics files.
+#
+# $(call colorize-latex-errors,<log file>)
+define colorize-latex-errors
+$(SED) \
+-e '$$ b para' \
+-e '/^$$/b para' \
+-e 'H' \
+-e 'd' \
+-e ':para' \
+-e 'x' \
+-e '/^$$/d' \
+-e 's/^\n*//' \
+-e '/^! LaTeX Error: File /{' \
+-e '  s/^/::DOUBLE_PARAGRAPH::/' \
+-e '  h' \
+-e '  d' \
+-e '}' \
+-e 's/^::DOUBLE_PARAGRAPH:://' \
+-e '/could not locate the file with any of these extensions:/d' \
+-e '/Missing .begin.document/{' \
+-e '  h' \
+-e '  s/.*/Are you trying to build an include file?/' \
+-e '  x' \
+-e '  G' \
+-e '}' \
+-e '/ LaTeX Error: Cannot determine size/d' \
+-e 's/.* LaTeX Error .*/$(C_ERROR)&$(C_RESET)/p' \
+-e 's/Error: pdflatex (file .*/$(C_ERROR)& - try specifying it without an extension$(C_RESET)/p' \
+-e '/.*\*hyperref using.*driver \(.*\)\*.*/{' \
+-e '  s//\1/' \
+-e '  /^$(hyperref_driver_pattern)$$/!{' \
+-e '    s/.*//' \
+-e '    p' \
+-e '    s/.*/$(C_ERROR)--- Using incorrect driver for hyperref! ---$(C_RESET)/' \
+-e '    p' \
+-e '    s/.*/$(C_ERROR)$(hyperref_driver_error)$(C_RESET)/' \
+-e '    p' \
+-e '  }' \
+-e '  d' \
+-e '}' \
+-e '/ LaTeX Error: Unknown graphics extension/{' \
+-e '  s/^/     /' \
+-e '  h' \
+-e '  s/.*/--- Graphics extension error:/' \
+-e '  G' \
+-e '  h' \
+-e '  s/.*/--- If you specified the extension explicitly in your .tex file, try removing it./' \
+-e '  H' \
+-e '  g' \
+-e '  s/.*/$(C_ERROR)&$(C_RESET)/' \
+-e '  p' \
+-e '  s/.*//' \
+-e '  h' \
+-e '  b' \
+-e '}' \
+-e 's/.*\(\n\{0,\}! .*\)/$(C_ERROR)\1$(C_RESET)/p' \
+-e 'd' \
+$1
+endef
+
+# Colorize Makeindex errors
+define colorize-makeindex-errors
+$(SED) \
+-e '/^!! /{' \
+-e '  N' \
+-e '  s/^.*$$/$(C_ERROR)&$(C_RESET)/' \
+-e '  p' \
+-e '}' \
+-e 'd' \
+$1
+endef
+
+# Colorize epstopdf errors
+#
+# $(call colorize-epstopdf-errors,<log file>)
+define colorize-epstopdf-errors
+$(SED) \
+-e '/^Error:/,/^Execution stack:/{' \
+-e '  /^Execution stack:/d' \
+-e '  s/.*/$(C_ERROR)&$(C_RESET)/' \
+-e '  p' \
+-e '}' \
+-e 'd' \
+$1
+endef
+
+# Colorize GNUplot errors
+#
+# $(call colorize-gnuplot-errors,<log file>)
+define colorize-gnuplot-errors
+$(SED) \
+-e '/, line [0-9]*:/!{' \
+-e '  H' \
+-e '  x' \
+-e '  s/.*\n\(.*\n.*\)$$/\1/' \
+-e '  x' \
+-e '}' \
+-e '/, line [0-9]*:/{' \
+-e '  H' \
+-e '  /unknown.*terminal type/{' \
+-e '    s/.*/--- Try changing the GNUPLOT_OUTPUT_EXTENSION variable to 'eps'./' \
+-e '	H' \
+-e '  }' \
+-e '  /gpihead/{' \
+-e '    s/.*/--- This could be a Makefile bug - contact the maintainer./' \
+-e '    H' \
+-e '  }' \
+-e '  g' \
+-e '  s/.*/$(C_ERROR)&$(C_RESET)/' \
+-e '  p' \
+-e '}' \
+-e '/^gnuplot>/,/^$$/{' \
+-e '  s/^gnuplot.*/$(C_ERROR)&/' \
+-e '  s/^$$/$(C_RESET)/' \
+-e '  p' \
+-e '}' \
+-e 'd' \
+$1
+endef
+
+# Colorize GraphViz errors
+#
+# $(call colorize-dot-errors,<log file>)
+define colorize-dot-errors
+$(SED) \
+-e '/^Error:/,/context:/s/.*/$(C_ERROR)&$(C_RESET)/p' \
+-e 's/^Warning:.*/$(C_WARNING)&$(C_RESET)/p' \
+-e 'd' \
+'$1'
+endef
+
+# Get all important .aux files from the top-level .aux file and merges them all
+# into a single file, which it outputs to stdout.
+#
+# $(call flatten-aux,<toplevel aux>,<output file>)
+define flatten-aux
+$(SED) \
+-e '/\\@input{\(.*\)}/{' \
+-e     's//\1/' \
+-e     's![.:]!\\&!g' \
+-e     'h' \
+-e     's!.*!\\:\\\\@input{&}:{!' \
+-e     'p' \
+-e     'x' \
+-e     's/\\././g' \
+-e     's/.*/r &/p' \
+-e     's/.*/d/p' \
+-e     's/.*/}/p' \
+-e     'd' \
+-e '}' \
+-e 'd' \
+'$1' > "$1.$$$$.sed.make"; \
+$(SED) -f "$1.$$$$.sed.make" '$1' > "$1.$$$$.make"; \
+$(SED) \
+-e '/^\\relax/d' \
+-e '/^\\bibcite/d' \
+-e 's/^\(\\newlabel{[^}]\{1,\}}\).*/\1/' \
+"$1.$$$$.make" | $(SORT) > '$2'; \
+$(call remove-temporary-files,$1.$$$$.make $1.$$$$.sed.make)
+endef
+
+# Generate pdf from postscript
+#
+# Note that we don't just call ps2pdf, since there are so many versions of that
+# script on various systems.  Instead, we call the postscript interpreter
+# directly.
+#
+# $(call ps2pdf,infile,outfile,[embed fonts])
+define ps2pdf
+	$(GS) \
+		-dSAFER -dCompatibilityLevel=$(PS_COMPATIBILITY) \
+		$(if $3,$(PS_EMBED_OPTIONS)) \
+		-q -dNOPAUSE -dBATCH \
+		-sDEVICE=pdfwrite -sstdout=%stderr \
+		'-sOutputFile=$2' \
+		-dSAFER -dCompatibilityLevel=$(PS_COMPATIBILITY) \
+		$(if $3,$(PS_EMBED_OPTIONS)) \
+		-c .setpdfwrite \
+		-f '$1'
+endef
+
+# Colorize LaTeX output.
+# This uses a neat trick from the Sed & Awk Book from O'Reilly:
+# 1) If a line has a single ending paren, delete it to make a blank line (so
+#	that we catch the first error, which is not always preceded by a blank
+#	line).
+# 2) Ensure that the last line of the file gets appended to the hold buffer,
+# 	and blank it out to trigger end-of-paragraph logic below.
+# 3) When encountering a blank line (LaTeX output helpfully breaks output on
+# 	newlines)
+# 	a) swap the hold buffer (containing the paragraph) into the pattern buffer (putting a blank line into the hold buffer),
+# 	b) remove the newline at the beginning (don't ask),
+# 	c) apply any colorizing substitutions necessary to ensure happiness.
+# 	d) get the newline out of the hold buffer and append it
+# 	e) profit! (print)
+# 4) Anything not colorized is deleted, unless in verbose mode.
+color_tex	:= \
+	$(SED) \
+	-e '$${' \
+	-e '  /^$$/!{' \
+	-e '    H' \
+	-e '    s/.*//' \
+	-e '  }' \
+	-e '}' \
+	-e '/^$$/!{' \
+	-e '  H' \
+	-e '  d' \
+	-e '}' \
+	-e '/^$$/{' \
+	-e '  x' \
+	-e '  s/^\n//' \
+	-e '  /Output written on /{' \
+	-e '    s/.*Output written on \([^(]*\) (\([^)]\{1,\}\)).*/Success!  Wrote \2 to \1/' \
+	-e '    s/[[:digit:]]\{1,\}/$(C_PAGES)&$(C_RESET)/g' \
+	-e '    s/Success!/$(C_SUCCESS)&$(C_RESET)/g' \
+	-e '    s/to \(.*\)$$/to $(C_SUCCESS)\1$(C_RESET)/' \
+	-e '    b end' \
+	-e '  }' \
+	-e '  / *LaTeX Error:.*/{' \
+	-e '    s/.*\( *LaTeX Error:.*\)/$(C_ERROR)\1$(C_RESET)/' \
+	-e '    b end' \
+	-e '  }' \
+	-e '  /.*Warning:.*/{' \
+	-e '    s//$(C_WARNING)&$(C_RESET)/' \
+	-e '    b end' \
+	-e '  }' \
+	-e '  /Underfull.*/{' \
+	-e '    s/.*\(Underfull.*\)/$(C_UNDERFULL)\1$(C_RESET)/' \
+	-e '    b end' \
+	-e '  }' \
+	-e '  /Overfull.*/{' \
+	-e '    s/.*\(Overfull.*\)/$(C_OVERFULL)\1$(C_RESET)/' \
+	-e '    b end' \
+	-e '  }' \
+	$(if $(VERBOSE),,-e '  d') \
+	-e '  :end' \
+	-e '  G' \
+	-e '}' \
+
+# Colorize BibTeX output.
+color_bib	:= \
+	$(SED) \
+	-e 's/^Warning--.*/$(C_WARNING)&$(C_RESET)/' -e 't' \
+	-e '/---/,/^.[^:]/{' \
+	-e '  H' \
+	-e '  /^.[^:]/{' \
+	-e '    x' \
+	-e '    s/\n\(.*\)/$(C_ERROR)\1$(C_RESET)/' \
+	-e '	p' \
+	-e '    s/.*//' \
+	-e '    h' \
+	-e '    d' \
+	-e '  }' \
+	-e '  d' \
+	-e '}' \
+	-e '/(.*error.*)/s//$(C_ERROR)&$(C_RESET)/' \
+	$(if $(VERBOSE),,-e 'd')
+
+
+# Make beamer output big enough to print on a full page.  Landscape doesn't
+# seem to work correctly.
+enlarge_beamer	= $(PSNUP) -l -1 -W128mm -H96mm -pletter
+
+# $(call test-run-again,<source stem>)
+test-run-again	= $(EGREP) -q '^(.*Rerun .*|No file $1\.[^.]+\.)$$' $1.log
+
+# This tests whether the build target commands should be run at all, from
+# viewing the log file.
+# $(call test-log-for-need-to-run,<source stem>)
+define test-log-for-need-to-run
+$(SED) \
+-e '/^No file $(call escape-dots,$1)\.aux\./d' \
+$1.log \
+| $(EGREP) -q '^(.*Rerun .*|No file $1\.[^.]+\.|No file .+\.tex\.|LaTeX Warning: File.*)$$'
+endef
+
+# LaTeX invocations
+#
+# $(call latex,<tex file>,[<extra LaTeX args>])
+run-latex	= $(latex_build_program) --interaction=batchmode $(if $2,$2,) $1 > /dev/null
+
+# $(call latex-color-log,<LaTeX stem>)
+latex-color-log	= $(color_tex) $1.log
+
+# $(call run-makeindex,<input>,<output>,<log>,<extra flags>)
+define run-makeindex
+success=1; \
+if ! $(MAKEINDEX) -q $1 -t $3 -o $2 $4 > /dev/null || $(EGREP) -q '^!!' $3; then \
+	$(call colorize-makeindex-errors,$3); \
+	$(RM) -f '$2'; \
+	success=0; \
+fi; \
+[ "$$success" = "1" ] && $(sh_true) || $(sh_false);
+endef
+
+# This runs the given script to generate output, and it uses MAKE_RESTARTS to
+# ensure that it never runs it more than once for a particular root make
+# invocation.
+#
+# $(call run-script,<interpreter>,<input>,<output>)
+define run-script
+[ ! -e '$2.cookie' ] && $(ECHO) "restarts=$(RESTARTS)" > $2.cookie && $(ECHO) "level=$(MAKELEVEL)" >> $2.cookie; \
+restarts=`$(SED) -n -e 's/^restarts=//p' $2.cookie`; \
+level=`$(SED) -n -e 's/^level=//p' $2.cookie`; \
+if $(EXPR) $(MAKELEVEL) '<=' $$level '&' $(RESTARTS) '<=' $$restarts >/dev/null; then \
+	$(call echo-build,$2,$3,$(RESTARTS)-$(MAKELEVEL)); \
+	$1 '$2' '$3'; \
+	$(ECHO) "restarts=$(RESTARTS)" > '$2.cookie'; \
+	$(ECHO) "level=$(MAKELEVEL)" >> '$2.cookie'; \
+fi
+endef
+
+# BibTeX invocations
+#
+# $(call run-bibtex,<tex stem>)
+run-bibtex	= $(BIBTEX) $1 | $(color_bib)
+
+
+# $(call convert-eps-to-pdf,<eps file>,<pdf file>,[gray])
+# Note that we don't use the --filter flag because it has trouble with bounding boxes that way.
+define convert-eps-to-pdf
+$(if $3,$(CAT) '$1' | $(call kill-ps-color) > '$1.cookie',$(CP) '$1' '$1.cookie'); \
+$(EPSTOPDF) '$1.cookie' --outfile='$2' > $1.log; \
+$(call colorize-epstopdf-errors,$1.log);
+endef
+
+# $(call convert-gpi,<gpi file>,<output file>,[gray])
+#
+define convert-gpi
+$(ECHO) 'set terminal $(if $(filter %.pdf,$2),pdf enhanced,postscript enhanced eps)' \
+$(if $(filter %.pdf,$2),fsize ,)$(call get-default,$(strip \
+$(firstword \
+	$(shell \
+		$(SED) \
+			-e 's/^\#\#FONTSIZE=\([[:digit:]]\{1,\}\)/\1/p' \
+			-e 'd' \
+			$1 $(strip $(gpi_global)) \
+	) \
+) \
+),$(if $(filter %.pdf,$2),$(DEFAULT_GPI_PDF_FONTSIZE),$(DEFAULT_GPI_EPS_FONTSIZE))) \
+$(strip $(if $3,monochrome,$(if \
+$(shell $(EGREP) '^\#\#[[:space:]]*GRAY[[:space:]]*$$' $< $(gpi_global)),\
+,color))) > $1head.make; \
+$(ECHO) 'set output "$2"' >> $1head.make; \
+$(if $(gpi_global),$(CAT) $(gpi_global) >> $1head.make;,) \
+fnames='$1head.make $1';\
+$(if $(gpi_sed),\
+	$(SED) -f '$(gpi_sed)' $$fnames > $1.temp.make; \
+	fnames=$1.temp.make;,\
+) \
+success=1; \
+if ! $(GNUPLOT) $$fnames 2>$1.log; then \
+	$(call colorize-gnuplot-errors,$1.log); \
+	success=0; \
+fi; \
+$(if $(gpi_sed),$(call remove-temporary-files,$1.temp.make);,) \
+$(call remove-temporary-files,$1head.make); \
+[ "$$success" = "1" ] && $(sh_true) || $(sh_false);
+endef
+
+# Creation of .eps files from .png files
+#
+# The intermediate step of PNM (using NetPBM) produces much nicer output than
+# ImageMagick's "convert" binary.  I couldn't get the right combination of
+# flags to make it look nice, anyway.
+#
+# To handle gray scale conversion, we pipe things through ppmtopgm in the
+# middle.
+#
+# $(call convert-png,<png file>,<eps file>)
+define convert-png
+$(PNGTOPNM) "$1" \
+	$(if $3,| $(PPMTOPGM),) \
+	| $(PNMTOPS) -noturn \
+	> "$2"
+endef
+
+# Creation of .eps files from .jpg files
+#
+# Thanks to brubakee for this solution.
+#
+# Uses Postscript level 2 to avoid file size bloat
+# $(call convert-jpg,<jpg file>,<eps file>)
+define convert-jpg
+$(CONVERT) $(if $3,-type Grayscale,) '$1' eps2:'$2'
+endef
+
+# Creation of .eps files from .fig files
+# $(call convert-fig,<fig file>,<output file>,[gray])
+convert-fig	= $(FIG2DEV) -L $(if $(filter %.pdf,$2),pdf,eps) $(if $3,-N,) $1 $2
+
+# Creation of .pstex files from .fig files
+# $(call convert-fig-pstex,<fig file>,<pstex file>)
+convert-fig-pstex	= $(FIG2DEV) -L pstex $1 $2 > /dev/null 2>&1
+
+# Creation of .pstex_t files from .fig files
+# $(call convert-fig-pstex-t,<fig file>,<pstex file>,<pstex_t file>)
+convert-fig-pstex-t	= $(FIG2DEV) -L pstex_t -p $3 $1 $2 > /dev/null 2>&1
+
+# Creation of .dot_t files from .dot files
+# #(call convert-dot-tex,<dot file>,<dot_t file>)
+convert-dot-tex		= $(DOT2TEX) '$1' > '$2'
+
+# Converts svg files into .eps files
+#
+# $(call convert-svg,<svg file>,<eps file>,[gray])
+convert-svg	= $(INKSCAPE) --export-eps='$2' '$1'
+
+# Converts xvg files into .eps files
+#
+# $(call convert-xvg,<xvg file>,<eps file>,[gray])
+convert-xvg	= $(XMGRACE) '$1' -printfile - -hardcopy -hdevice $(if $3,-mono,) EPS > '$2'
+
+# Converts .eps.gz files into .eps files
+#
+# $(call convert-epsgz,<eps.gz file>,<eps file>,[gray])
+convert-epsgz	= $(GUNZIP) -c '$1' $(if $3,| $(call kill-ps-color)) > '$2'
+
+# Converts .eps files into .eps files (usually a no-op, but can make grayscale)
+#
+# $(call convert-eps,<in file>,<out file>,[gray])
+convert-eps	= $(if $3,$(call kill-ps-color) $1 > $2)
+
+# The name of the file containing special postscript commands for grayscale
+gray_eps_file	:= gray.eps.make
+
+# Changes sethsbcolor and setrgbcolor calls in postscript to always produce
+# grayscale.  In general, this is accomplished by writing new versions of those
+# functions into the user dictionary space, which is looked up before the
+# global or system dictionaries (userdict is one of the permanent dictionaries
+# in postscript and is not read-only like systemdict).
+#
+# For setrgbcolor, the weighted average of the triple is computed and the
+# triple is replaced with three copies of that average before the original
+# procedure is called: .299R + .587G + .114B
+#
+# For sethsbcolor, the color is first converted to RGB, then to grayscale by
+# the new setrgbcolor operator as described above.  Why is this done?
+# Because simply using the value component will tend to make pure colors
+# white, a very undesirable thing.  Pure blue should not translate to white,
+# but to some level of gray.  Conversion to RGB does the right thing.  It's
+# messy, but it works.
+#
+# From
+# http://en.wikipedia.org/wiki/HSV_color_space#Transformation_from_HSV_to_RGB,
+# HSB = HSV (Value = Brightness), and the formula used to convert to RGB is
+# as follows:
+#
+# Hi = int(floor(6 * H)) mod 6
+# f = 6 * H - Hi
+# p = V(1-S)
+# q = V(1-fS)
+# t = V(1-(1-f)S)
+# if Hi = 0: R G B <-- V t p
+# if Hi = 1: R G B <-- q V p
+# if Hi = 2: R G B <-- p V t
+# if Hi = 3: R G B <-- p q V
+# if Hi = 4: R G B <-- t p V
+# if Hi = 5: R G B <-- V p q
+#
+# The messy stack-based implementation is below
+# $(call create-gray-eps-file,filename)
+define create-gray-eps-file
+$(ECHO) -n -e '\
+/OLDRGB /setrgbcolor load def\n\
+/setrgbcolor {\n\
+    .114 mul exch\n\
+    .587 mul add exch\n\
+    .299 mul add\n\
+    dup dup\n\
+    OLDRGB\n\
+} bind def\n\
+/OLDHSB /sethsbcolor load def\n\
+/sethsbcolor {\n\
+    2 index                     % H V S H\n\
+    6 mul floor cvi 6 mod       % Hi V S H\n\
+    3 index                     % H Hi V S H\n\
+    6 mul                       % 6H Hi V S H\n\
+    1 index                     % Hi 6H Hi V S H\n\
+    sub                         % f Hi V S H\n\
+    2 index 1                   % 1 V f Hi V S H\n\
+    4 index                     % S 1 V f Hi V S H\n\
+    sub mul                     % p f Hi V S H\n\
+    3 index 1                   % 1 V p f Hi V S H\n\
+    6 index                     % S 1 V p f Hi V S H\n\
+    4 index                     % f S 1 V p f Hi V S H\n\
+    mul sub mul                 % q p f Hi V S H\n\
+    4 index 1 1                 % 1 1 V q p f Hi V S H\n\
+    5 index                     % f 1 1 V q p f Hi V S H\n\
+    sub                         % (1-f) 1 V q p f Hi V S H\n\
+    8 index                     % S (1-f) 1 V q p f Hi V S H\n\
+    mul sub mul                 % t q p f Hi V S H\n\
+    4 -1 roll pop               % t q p Hi V S H\n\
+    7 -2 roll pop pop           % t q p Hi V\n\
+    5 -2 roll                   % Hi V t q p\n\
+    dup 0 eq\n\
+    {1 index 3 index 6 index}\n\
+    {\n\
+        dup 1 eq\n\
+        {3 index 2 index 6 index}\n\
+        {\n\
+            dup 2 eq\n\
+            {4 index 2 index 4 index}\n\
+            {\n\
+                dup 3 eq\n\
+                {4 index 4 index 3 index}\n\
+                {\n\
+                    dup 4 eq\n\
+                    {2 index 5 index 3 index}\n\
+                    {\n\
+                        dup 5 eq\n\
+                        {1 index 5 index 5 index}\n\
+                        {0 0 0}\n\
+                        ifelse\n\
+                    }\n\
+                    ifelse\n\
+                }\n\
+                ifelse\n\
+            }\n\
+            ifelse\n\
+        }\n\
+        ifelse\n\
+    }\n\
+    ifelse                      % B G R Hi V t q p\n\
+    setrgbcolor\n\
+    5 {pop} repeat\n\
+} bind def\n'\
+> $1
+endef
+
+# This actually inserts the color-killing code into a postscript file
+# $(call kill-ps-color)
+define kill-ps-color
+$(SED) -e '/%%EndComments/r $(gray_eps_file)'
+endef
+
+# Converts graphviz .dot files into .eps files
+# Grayscale is not directly supported by dot, so we pipe it through fig2dev in
+# that case.
+# $(call convert-dot,<dot file>,<eps file>,<log file>,[gray])
+define convert-dot
+$(DOT) -Tps '$1' 2>'$3' $(if $4,| $(call kill-ps-color)) > $2; \
+$(call colorize-dot-errors,$3)
+endef
+
+# Convert DVI to Postscript
+# $(call make-ps,<dvi file>,<ps file>,<log file>,[<paper size>])
+make-ps		= \
+	$(DVIPS) -o '$2' $(if $(filter-out BEAMER,$4),-t$(firstword $4),) '$1' \
+		$(if $(filter BEAMER,$4),| $(enlarge_beamer)) > $3 2>&1
+
+# Convert Postscript to PDF
+# $(call make-pdf,<ps file>,<pdf file>,<log file>,<embed file>)
+make-pdf	= \
+	$(call ps2pdf,$1,$2,$(filter 1,$(shell $(CAT) '$4'))) > '$3' 2>&1
+
+# Display information about what is being done
+# $(call echo-build,<input file>,<output file>,[<run number>])
+echo-build	= $(ECHO) "$(C_BUILD)= $1 --> $2$(if $3, ($3),) =$(C_RESET)"
+echo-graphic	= $(ECHO) "$(C_GRAPHIC)= $1 --> $2 =$(C_RESET)"
+echo-dep	= $(ECHO) "$(C_DEP)= $1 --> $2 =$(C_RESET)"
+
+# Display a list of something
+# $(call echo-list,<values>)
+echo-list	= for x in $1; do $(ECHO) "$$x"; done
+
+#
+# DEFAULT TARGET
+#
+
+.PHONY: all
+all: $(default_pdf_targets) ;
+
+.PHONY: all-pdf
+all-pdf: $(default_pdf_targets) ;
+
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+.PHONY: all-ps
+all-ps: $(default_ps_targets) ;
+
+.PHONY: all-dvi
+all-dvi: $(default_dvi_targets) ;
+endif
+
+#
+# VIEWING TARGET
+#
+.PHONY: show
+show: all
+	$(QUIET)for x in $(default_pdf_targets); do \
+		[ -e "$$x" ] && $(VIEW_PDF) $$x & \
+	done
+
+#
+# INCLUDES
+#
+source_includes	:= $(addsuffix .d,$(source_stems_to_include))
+graphic_includes := $(addsuffix .gpi.d,$(graphic_stems_to_include))
+
+# Include only the dependencies used
+ifneq "" "$(source_includes)"
+include $(source_includes)$(call include-message,$(source_includes))
+endif
+ifneq "" "$(graphic_includes)"
+include $(graphic_includes)$(call include-message,$(graphic_includes))
+endif
+
+#
+# MAIN TARGETS
+#
+
+# Note that we don't just say %: %.pdf here - this can tend to mess up our
+# includes, which detect what kind of file we are asking for.  For example,
+# asking to build foo.pdf is much different than asking to build foo when
+# foo.gpi exists, because we look through all of the goals for *.pdf that
+# matches *.gpi, then use that to determine which include files we need to
+# build.
+#
+# Thus, we invoke make recursively with better arugments instead, restarting
+# all of the appropriate machinery.
+.PHONY: $(default_stems_ss)
+$(default_stems_ss): %: %.pdf ;
+
+# This builds and displays the wanted file.
+.PHONY: $(addsuffix ._show,$(stems_ssg))
+%._show: %.pdf
+	$(QUIET)$(VIEW_PDF) $< &
+
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+.SECONDARY: $(all_pdf_targets)
+%.pdf: %.ps %.embed.make
+	$(QUIET)$(call echo-build,$<,$@)
+	$(QUIET)$(call make-pdf,$<,$@.temp,$@.log,$*.embed.make); \
+	if [ x"$$?" = x"0" ]; then \
+	    $(if $(VERBOSE),$(CAT) $@.log,:); \
+	    $(RM) -f '$@'; \
+	    $(MV) '$@.temp' '$@'; \
+	    $(TOUCH) '$@'; \
+	    $(call copy-with-logging,$@,$(BINARY_TARGET_DIR)); \
+	else \
+	    $(CAT) $@.log; \
+	    $(call remove-temporary-files,'$@.temp'); \
+	    $(sh_false); \
+	fi
+
+.SECONDARY: $(all_ps_targets)
+%.ps: %.dvi %.paper.make
+	$(QUIET)$(call echo-build,$<,$@)
+	$(QUIET)$(call make-ps,$<,$@.temp,$@.log,\
+			$(firstword $(shell $(CAT) $*.paper.make))); \
+	if [ x"$$?" = x"0" ]; then \
+	    $(if $(VERBOSE),$(CAT) $@.log,:); \
+	    $(RM) -f '$@'; \
+	    $(MV) '$@.temp' '$@'; \
+	    $(TOUCH) '$@'; \
+	    $(call copy-with-logging,$@,$(BINARY_TARGET_DIR)); \
+	else \
+	    $(CAT) $@.log; \
+	    $(call remove-temporary-files,'$@.temp'); \
+	    $(sh_false); \
+	fi
+endif
+
+# Build the final target (dvi or pdf) file.  This is a very tricky rule because
+# of the way that latex runs multiple times, needs graphics after the first run
+# (or maybe already has them), and relies on bibliographies or indices that may
+# not exist.
+#
+#	Check the log for fatal errors.  If they exist, colorize and bail.
+#
+#	Create the .auxtarget.cookie file.  (Needed for next time if not present)
+#
+#	If any of the following are true, we must rebuild at least one time:
+#
+#	* the .bbl was recently rebuilt
+#
+#		check a cookie, then delete it
+#
+#	* any of several output files was created or changed:
+#
+#		check $*.run.cookie, then delete it
+#
+#	* the .aux file changed in a way that necessitates attention
+#
+#		Note that if the .auxtarget.make file doesn't exist, this means
+#		that we are doing a clean build, so it doesn't figure into the
+#		test for running again.
+#
+#		compare against .auxtarget.make
+#
+#		move if different, remove if not
+#
+#	* the .log file has errors or warnings requiring at least one more run
+#
+#	We use a loop over a single item to simplify the process of breaking
+#	out when we find one of the conditions to be true.
+#
+#	If we do NOT need to run latex here, then we move the $@.1st.make file
+#	over to $@ because the target file has already been built by the first
+#	dependency run and is valid.
+#
+#	If we do, we delete that cookie file and do the normal multiple-runs
+#	routine.
+#
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+.SECONDARY: $(all_dvi_targets)
+endif
+%.$(build_target_extension): %.bbl %.aux %.$(build_target_extension).1st.make
+	$(QUIET)\
+	fatal=`$(call colorize-latex-errors,$*.log)`; \
+	if [ x"$$fatal" != x"" ]; then \
+		$(ECHO) "$$fatal"; \
+		exit 1; \
+	fi; \
+	$(call make-auxtarget-file,$*.aux.make,$*.auxtarget.cookie); \
+	run=0; \
+	for i in 1; do \
+		if $(call test-exists,$*.bbl.cookie); then \
+			run=1; \
+			break; \
+		fi; \
+		if $(call test-exists,$*.run.cookie); then \
+			run=1; \
+		    	break; \
+		fi; \
+		if $(call \
+		test-exists-and-different,$*.auxtarget.cookie,$*.auxtarget.make);\
+		then \
+			run=1; \
+			break; \
+		fi; \
+		if $(call test-log-for-need-to-run,$*); then \
+			run=1; \
+			break; \
+		fi; \
+	done; \
+	$(call remove-temporary-files,$*.bbl.cookie $*.run.cookie); \
+	$(MV) $*.auxtarget.cookie $*.auxtarget.make; \
+	if [ x"$$run" = x"1" ]; then \
+		$(call remove-files,$@.1st.make); \
+		for i in 2 3 4 5; do \
+			$(if $(findstring 3.79,$(MAKE_VERSION)),\
+				$(call echo-build,$*.tex,$@,$(RESTARTS)-$$$$i),\
+				$(call echo-build,$*.tex,$@,$(RESTARTS)-$$i)\
+			); \
+			$(call run-latex,$*); \
+			$(CP) '$*.log' '$*.'$(RESTARTS)-$$i'.log'; \
+			$(call test-run-again,$*) || break; \
+		done; \
+	else \
+		$(MV) '$@.1st.make' '$@'; \
+	fi; \
+	$(call copy-with-logging,$@,$(BINARY_TARGET_DIR)); \
+	$(call latex-color-log,$*)
+
+# Build the .bbl file.  When dependencies are included, this will (or will
+# not!) depend on something.bib, which we detect, acting accordingly.  The
+# dependency creation also produces the %.auxbbl.make file.  BibTeX is a bit
+# finicky about what you call the actual files, but we can rest assured that if
+# a .auxbbl.make file exists, then the .aux file does, as well.  The
+# .auxbbl.make file is a cookie indicating whether the .bbl needs to be
+# rewritten.  It only changes if the .aux file changes in ways relevant to .bbl
+# creation.
+#
+# Note that we do NOT touch the .bbl file if there is no need to
+# create/recreate it.  We would like to leave existing files alone if they
+# don't need to be changed, thus possibly avoiding a rebuild trigger.
+%.bbl: %.auxbbl.make
+	$(QUIET)\
+	$(if $(filter %.bib,$^),\
+		$(call echo-build,$(filter %.bib,$?) $*.aux,$@); \
+		$(call run-bibtex,$*); \
+		$(TOUCH) $@.cookie; \
+	) \
+	if $(EGREP) -q 'bibstyle.(apacann|chcagoa|[^}]*annot)' '$*.aux'; then \
+		$(call echo-build,** annotated extra latex **,output ignored,$(RESTARTS)-1); \
+		$(call run-latex,$*); \
+		$(CP) '$*.log' '$*.$(RESTARTS)-annotated.log'; \
+		$(if $(filter %.bib,$^),\
+			$(call echo-build,** annotated extra bibtex ** $(filter %.bib,$?) $*.aux,$@); \
+			$(call run-bibtex,$*); \
+			$(TOUCH) $@.cookie; \
+		) \
+		$(call echo-build,** annotated extra latex **,output ignored,$(RESTARTS)-2); \
+		$(call run-latex,$*); \
+	fi
+
+# Create the index file - note that we do *not* depend on %.tex here, since
+# that unnecessarily restricts the kinds of indices that we can build to those
+# with exactly the same stem as the source file.  Things like splitidx create
+# idx files with other names.
+#
+# Therefore, we add the .tex dependency in the sourcestem.d file in the call to
+# get index file dependencies from the logs.
+%.ind:	%.idx
+	$(QUIET)$(call echo-build,$<,$@)
+	$(QUIET)$(call run-makeindex,$<,$@,$*.ilg)
+
+# Create the glossary file
+%.gls:	%.glo %.tex
+	$(QUIET)$(call echo-build,$<,$@)
+	$(QUIET)$(call run-makeindex,$<,$@,$*.glg,-s nomencl.ist)
+
+# Create the nomenclature file
+%.nls:	%.nlo %.tex
+	$(QUIET)$(call echo-build,$<,$@)
+	$(QUIET)$(call run-makeindex,$<,$@,$*.nlg,-s nomencl.ist)
+
+# SCRIPTED LaTeX TARGETS
+#
+# Keep the generated .tex files around for debugging if needed.
+.SECONDARY: $(all_tex_targets)
+
+%.tex::	%.tex.sh
+	$(QUIET)$(call run-script,$(SHELL),$<,$@)
+
+%.tex::	%.tex.py
+	$(QUIET)$(call run-script,$(PYTHON),$<,$@)
+
+%.tex::	%.tex.pl
+	$(QUIET)$(call run-script,$(PERL),$<,$@)
+
+%.tex::	%.rst $(RST_STYLE_FILE)
+	$(QUIET)\
+	$(call run-script,$(RST2LATEX)\
+		--documentoptions=letterpaper\
+		$(if $(RST_STYLE_FILE),--stylesheet=$(RST_STYLE_FILE),),$<,$@)
+
+#
+# GRAPHICS TARGETS
+#
+.PHONY: all-graphics
+all-graphics:	$(all_graphics_targets);
+
+ifneq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+.PHONY: all-pstex
+all-pstex:	$(all_pstex_targets);
+endif
+
+.PHONY: all-dot2tex
+all-dot2tex:	$(all_dot2tex_targets);
+
+.PHONY: show-graphics
+show-graphics: all-graphics
+	$(VIEW_GRAPHICS) $(all_known_graphics)
+
+$(gray_eps_file):
+	$(QUIET)$(call echo-build,$^,$@)
+	$(QUIET)$(call create-gray-eps-file,$@)
+
+ifeq "$(strip $(BUILD_STRATEGY))" "pdflatex"
+%.pdf: %.eps $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-eps-to-pdf,$<,$@,$(GRAY))
+
+ifeq "$(strip $(GNUPLOT_OUTPUT_EXTENSION))" "pdf"
+%.pdf:	%.gpi %.gpi.d $(gpi_sed)
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-gpi,$<,$@,$(GRAY))
+endif
+
+%.pdf:	%.fig
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-fig,$<,$@,$(GRAY))
+
+endif
+
+%.eps:	%.gpi %.gpi.d $(gpi_sed)
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-gpi,$<,$@,$(GRAY))
+
+%.eps: %.fig
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-fig,$<,$@,$(GRAY))
+
+%.eps: %.dot $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-dot,$<,$@,$<.log,$(GRAY))
+
+%.eps: %.xvg $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-xvg,$<,$@,$(GRAY))
+
+%.eps: %.svg $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-svg,$<,$@,$(GRAY))
+
+%.eps: %.jpg $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-jpg,$<,$@,$(GRAY))
+
+%.eps: %.png $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-png,$<,$@,$(GRAY))
+
+%.eps: %.eps.gz $(if $(GRAY),$(gray_eps_file))
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-epsgz,$<,$@,$(GRAY))
+
+%.pstex: %.fig
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-fig-pstex,$<,$@,$(GRAY))
+
+%.pstex_t: %.fig %.pstex
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-fig-pstex-t,$<,$@,$*.pstex,$(GRAY))
+
+%.dot_t: %.dot
+	$(QUIET)$(call echo-graphic,$^,$@)
+	$(QUIET)$(call convert-dot-tex,$<,$@)
+
+#
+# DEPENDENCY-RELATED TARGETS.
+#
+
+# Generate all of the information needed to get dependencies
+# As a side effect, this creates a .dvi or .pdf file (depending on the build
+# strategy).  We need to be sure to remove it if there are errors.  Errors can
+# take several forms and all of them are found within the log file:
+#	* There was a LaTeX error
+#	* A needed file was not found
+#	* Cross references need adjustment
+#
+# Behavior:
+#	This rule is responsible for generating the following:
+#	%.aux
+#	%.d
+#	%.aux.make
+#	%.(pdf|dvi).1st.make (the .pdf or .dvi output file, moved)
+#
+#	Steps:
+#
+#	Run latex
+#	Move .pdf or .dvi somewhere else (make no judgements about success)
+#	Flatten the .aux file into another file
+#	Add source dependencies
+#	Add graphic dependencies
+#	Add bib dependencies
+#
+#	Create cookies for various suffixes that may represent files that
+#	need to be read by LaTeX in order for it to function properly.
+#
+#	Note that if some of the dependencies are discovered because they turn
+#	up missing in the log file, we really need the .d file to be reloaded.
+#	Adding a sleep command helps with this.  Otherwise make is extremely
+#	nondeterministic, sometimes working, sometimes not.
+#
+#	Usually we can force this by simply removing the generated pdf file and
+#	not creating a .1st.make file..
+#
+%.$(build_target_extension).1st.make %.d %.aux %.aux.make %.fls: %.tex
+	$(QUIET)$(call echo-build,$<,$*.d $*.$(build_target_extension).1st.make,$(RESTARTS)-1)
+	$(QUIET)\
+	$(call run-latex,$<,--recorder) || $(sh_true); \
+	$(CP) '$*.log' '$*.$(RESTARTS)-1.log'; \
+	$(call die-on-dot2tex,$*.log); \
+	$(call die-on-no-aux,$*); \
+	$(call flatten-aux,$*.aux,$*.aux.make); \
+	$(ECHO) "# vim: ft=make" > $*.d; \
+	$(ECHO) ".PHONY: $*._graphics" >> $*.d; \
+	$(call get-inputs,$*.fls,$(addprefix $*.,aux aux.make d $(build_target_extension))) >> $*.d; \
+	$(call get-missing-inputs,$*.log,$(addprefix $*.,aux aux.make d $(build_target_extension))) >> $*.d; \
+	$(ECHO) ".SECONDEXPANSION:" >> $*.d; \
+	$(call get-graphics,$*) >> $*.d; \
+	$(call get-log-index,$*,$(addprefix $*.,d aux aux.make)) >> $*.d; \
+	$(call get-bibs,$*.aux.make,$(addprefix $*.,bbl aux aux.make)) >> $*.d; \
+	$(EGREP) -q "# MISSING" $*.d && $(SLEEP) 1 && $(RM) $*.pdf; \
+	$(call move-if-exists,$*.$(build_target_extension),$*.$(build_target_extension).1st.make); \
+	for s in toc out lot lof lol nav; do \
+		if [ -e "$*.$$s" ]; then \
+			if ! $(DIFF) -q $*.$$s $*.$$s.make >/dev/null 2>&1; then \
+				$(TOUCH) $*.run.cookie; \
+			fi; \
+			$(CP) $*.$$s $*.$$s.make; \
+		fi; \
+	done
+
+# This is a cookie that is updated if the flattened aux file has changed in a
+# way that affects the bibliography generation.
+.SECONDARY: $(addsuffix .auxbbl.make,$(stems_ssg))
+%.auxbbl.make: %.aux.make
+	$(QUIET)\
+	$(call make-auxbbl-file,$<,$@.temp); \
+	$(call replace-if-different-and-remove,$@.temp,$@)
+
+# Build a dependency file for .gpi files.  These often plot data files that
+# also reside in the directory, so if a data file changes, it's nice to know
+# about it.  This also handles loaded .gpi files, whose filename should have
+# _include_. in it.
+%.gpi.d: %.gpi
+	$(QUIET)$(call echo-build,$<,$@)
+	$(QUIET)$(call make-gpi-d,$<,$@)
+
+# Store the paper size for this document -- note that if beamer is used we set
+# it to the special BEAMER paper size.  We only do this, however, if the
+# special comment exists, in which case we enlarge the output with psnup.
+#
+#	The paper size is extracted from a documentclass attribute.
+%.paper.make: %.tex
+	$(QUIET)$(SED) \
+	-e '/\\documentclass/,/}/{' \
+	-e '  s/%.*//' \
+	-e '  H' \
+	-e '  /}/{' \
+	-e '    s/.*//' \
+	-e '    x' \
+	-e '    /\\documentclass/!d' \
+	-e '    s/[\n[:space:]]*//g' \
+	-e '    s/\([,{[]\)\([[:alnum:]]\{1,\}\)paper\([],}]\)/\1%-\2-%\3/g' \
+	-e '    s/\([,{[]\)\(landscape\)\([],}]\)/\1%-\2-%\3/g' \
+	-e '    s/^[^%]*%-//' \
+	-e '    s/-%[^%]*$$//' \
+	-e '    s/-%[^%]%-/ /g' \
+	-e '    p' \
+	-e '  }' \
+	-e '  d' \
+	-e '}' \
+	-e 'd' \
+	$< > $@; \
+	$(EGREP) -q '^[^%]*\\documentclass[^{]*{beamer}' $< && \
+	(\
+		$(EGREP) -q '^%%[[:space:]]*BEAMER[[:space:]]*LARGE$$' $< && \
+		$(ECHO) "BEAMER" > $@ || \
+		: > $@ \
+	) || $(sh_true)
+
+# Store embedding instructions for this document using a special comment
+%.embed.make: %.tex
+	$(QUIET)$(EGREP) '^%%[[:space:]]*NO[[:space:]]*EMBED[[:space:]]*$$' $< \
+		&& $(ECHO) '' > $@ \
+		|| $(ECHO) '1' > $@;
+
+#
+# HELPFUL PHONY TARGETS
+#
+
+.PHONY: _all_programs
+_all_programs:
+	$(QUIET)$(ECHO) "== All External Programs Used =="
+	$(QUIET)$(call output-all-programs)
+
+.PHONY: _check_programs
+_check_programs:
+	$(QUIET)$(ECHO) "== Checking Makefile Dependencies =="; $(ECHO)
+	$(QUIET) \
+	$(ECHO) hi; \
+	allprogs=`\
+	 ($(call output-all-programs)) | \
+	 $(SED) \
+	 -e 's/^[[:space:]]*//' \
+	 -e '/^#/d' \
+	 -e 's/[[:space:]]*#.*//' \
+	 -e '/^=/s/[[:space:]]/_/g' \
+	 -e '/^[[:space:]]*$$/d' \
+	 -e 's/^[^=].*=[[:space:]]*\([^[:space:]]\{1,\}\).*$$/\\1/' \
+	 `; \
+	spaces='                             '; \
+	for p in $${allprogs}; do \
+	case $$p in \
+		=*) $(ECHO); $(ECHO) "$$p";; \
+		*) \
+			$(ECHO) -n "$$p:$$spaces" | $(SED) -e 's/^\(.\{0,20\}\).*$$/\1/'; \
+			loc=`$(WHICH) $$p`; \
+			if [ x"$$?" = x"0" ]; then \
+				$(ECHO) "$(C_SUCCESS)Found:$(C_RESET) $$loc"; \
+			else \
+				$(ECHO) "$(C_FAILURE)Not Found$(C_RESET)"; \
+			fi; \
+			;; \
+	esac; \
+	done
+
+.PHONY: _check_gpi_files
+_check_gpi_files:
+	$(QUIET)$(ECHO) "== Checking all .gpi files for common errors =="; \
+	$(ECHO); \
+	for f in $(files.gpi); do \
+	result=`$(EGREP) '^([^#]*set terminal |set output )' $$f`; \
+	$(ECHO) -n "$$f: "; \
+	if [ x"$$result" = x"" ]; then \
+		$(ECHO) "$(C_SUCCESS)Okay$(C_RESET)"; \
+	else \
+		$(ECHO) "$(C_FAILURE)Warning: Problematic commands:$(C_RESET)";\
+		$(ECHO) "$(C_ERROR)$$result$(C_RESET)"; \
+	fi; \
+	done; \
+	$(ECHO)
+
+.PHONY: _all_stems
+_all_stems:
+	$(QUIET)$(ECHO) "== All Stems =="
+	$(QUIET)$(call echo-list,$(sort $(default_stems_ss)))
+
+.PHONY: _includes
+_includes:
+	$(QUIET)$(ECHO) "== Include Stems =="
+	$(QUIET)$(ECHO) "=== Sources ==="
+	$(QUIET)$(call echo-list,$(sort $(source_includes)))
+	$(QUIET)$(ECHO) "=== Graphics ==="
+	$(QUIET)$(call echo-list,$(sort $(graphic_includes)))
+
+.PHONY: _all_sources
+_all_sources:
+	$(QUIET)$(ECHO) "== All Sources =="
+	$(QUIET)$(call echo-list,$(sort $(all_files.tex)))
+
+.PHONY: _dependency_graph
+_dependency_graph:
+	$(QUIET)$(ECHO) "/* LaTeX Dependency Graph */"
+	$(QUIET)$(call output-dependency-graph)
+
+.PHONY: _show_dependency_graph
+_show_dependency_graph:
+	$(QUIET)$(call output-dependency-graph,$(graph_stem).dot)
+	$(QUIET)$(DOT) -Tps -o $(graph_stem).eps $(graph_stem).dot
+	$(QUIET)$(VIEW_POSTSCRIPT) $(graph_stem).eps
+	$(QUIET)$(call remove-temporary-files,$(graph_stem).*)
+
+.PHONY: _sources
+_sources:
+	$(QUIET)$(ECHO) "== Sources =="
+	$(QUIET)$(call echo-list,$(sort $(files.tex)))
+
+.PHONY: _scripts
+_scripts:
+	$(QUIET)$(ECHO) "== Scripts =="
+	$(QUIET)$(call echo-list,$(sort $(files_scripts)))
+
+.PHONY: _graphic_outputs
+_graphic_outputs:
+	$(QUIET)$(ECHO) "== Graphic Outputs =="
+	$(QUIET)$(call echo-list,$(sort $(all_graphics_targets)))
+
+.PHONY: _env
+_env:
+ifdef .VARIABLES
+	$(QUIET)$(ECHO) "== MAKE VARIABLES =="
+	$(QUIET)$(call echo-list,$(foreach var,$(sort $(.VARIABLES)),'$(var)'))
+endif
+	$(QUIET)$(ECHO) "== ENVIRONMENT =="
+	$(QUIET)$(ENV)
+
+#
+# CLEAN TARGETS
+#
+# clean-generated is somewhat unique - it relies on the .fls file being
+# properly built so that it can determine which of the files was generated, and
+# which was not.  Expect it to silently fail if the .fls file is missing.
+#
+# This is used to, e.g., clean up index files that are generated by the LaTeX.
+.PHONY: clean-generated
+clean-generated:
+	$(QUIET)$(call clean-files,$(foreach e,$(addsuffix .fls,$(all_stems_source)),\
+						$(shell $(call get-generated-names,$e))))
+
+.PHONY: clean-deps
+clean-deps:
+	$(QUIET)$(call clean-files,$(all_d_targets) *.make *.make.temp *.cookie)
+
+.PHONY: clean-tex
+clean-tex: clean-deps
+	$(QUIET)$(call clean-files,$(rm_tex))
+
+.PHONY: clean-graphics
+# TODO: This *always* deletes pstex files, even if they were not generated by
+# anything....  In other words, if you create a pstex and pstex_t pair by hand
+# an drop them in here without the generating fig file, they will be deleted
+# and you won't get them back.  It's a hack put in here because I'm not sure we
+# even want to keep pstex functionality, so my motivation is not terribly high
+# for doing it right.
+clean-graphics:
+	$(QUIET)$(call clean-files,$(all_graphics_targets) $(intermediate_graphics_targets) *.gpi.d *.pstex *.pstex_t *.dot_t)
+
+.PHONY: clean-backups
+clean-backups:
+	$(QUIET)$(call clean-files,$(backup_patterns) *.temp)
+
+.PHONY: clean-auxiliary
+clean-auxiliary:
+	$(QUIET)$(call clean-files,$(graph_stem).*)
+
+.PHONY: clean-nographics
+clean-nographics: clean-tex clean-deps clean-backups clean-auxiliary ;
+
+.PHONY: clean
+clean:	clean-generated clean-tex clean-graphics clean-deps clean-backups clean-auxiliary
+
+#
+# HELP TARGETS
+#
+
+.PHONY: help
+help:
+	$(help_text)
+
+.PHONY: version
+version:
+	$(QUIET)\
+	$(ECHO) "$(fileinfo) Version $(version)"; \
+	$(ECHO) "by $(author)"; \
+
+#
+# HELP TEXT
+#
+
+define help_text
+# $(fileinfo) Version $(version)
+#
+# by $(author)
+#
+# Generates a number of possible output files from a LaTeX document and its
+# various dependencies.  Handles .bib files, \include and \input, and .eps
+# graphics.  All dependencies are handled automatically by running LaTeX over
+# the source.
+#
+# USAGE:
+#
+#    make [GRAY=1] [VERBOSE=1] [SHELL_DEBUG=1] <target(s)>
+#
+# STANDARD OPTIONS:
+#    GRAY:
+#        Setting this variable forces all recompiled graphics to be grayscale.
+#        It is useful when creating a document for printing.  The default is
+#        to allow colors.  Note that it only changes graphics that need to be
+#        rebuilt!  It is usually a good idea to do a 'make clean' first.
+#
+#    VERBOSE:
+#        This turns off all @ prefixes for commands invoked by make.  Thus,
+#        you get to see all of the gory details of what is going on.
+#
+#    SHELL_DEBUG:
+#        This enables the -x option for sh, meaning that everything it does is
+#        echoed to stderr.  This is particularly useful for debugging
+#        what is going on in $$(shell ...) invocations.  One of my favorite
+#        debugging tricks is to do this:
+#
+#        make -d SHELL_DEBUG=1 VERBOSE=1 2>&1 | less
+#
+# STANDARD AUXILIARY FILES:
+#
+#      Makefile.ini
+#
+#          This file can contain variable declarations that override various
+#          aspects of the makefile.  For example, one might specify
+#
+#          neverclean := *.pdf *.ps
+#          onlysources.tex := main.tex
+#          LATEX_COLOR_WARNING := 'bold red uline'
+#
+#          And this would override the neverclean setting to ensure that pdf
+#          and ps files always remain behind, set the makefile to treat all
+#          .tex files that are not "main.tex" as includes (and therefore not
+#          default targets).  It also changes the LaTeX warning output to be
+#          red, bold, and underlined.
+#
+#          There are numerous variables in this file that can be overridden in
+#          this way.  Search for '?=' to find them all.
+#
+#          Also, you can put arbitrary targets into it if, for example, you
+#          want your source built from something else, e.g.:
+#
+#          generated.tex: generating_script.weird_lang depA depB
+#          	./generating_script.weird_lang > $$@
+#
+#          Note that if you are not careful, you can override the default
+#          target (what happens when you type "make" without arguments), so if
+#          you do use Makefile.ini, you probably want to start it with
+#          something like the following line:
+#
+#          default: all
+#
+#          Since the first target in any makefile is automatically the default,
+#          and the makefile already has a sensible "all" target, this will do
+#          what you want.
+#
+#          The Makefile.ini is imported before *anything else* is done, so go
+#          wild with your ideas for changes to this makefile in there.  It
+#          makes it easy to test them before submitting patches.
+#
+# STANDARD ENVIRONMENT VARIABLES:
+#
+#      LATEX_COLOR_WARNING		'$(LATEX_COLOR_WARNING)'
+#      LATEX_COLOR_ERROR		'$(LATEX_COLOR_ERROR)'
+#      LATEX_COLOR_UNDERFULL		'$(LATEX_COLOR_UNDERFULL)'
+#      LATEX_COLOR_OVERFULL		'$(LATEX_COLOR_OVERFULL)'
+#      LATEX_COLOR_PAGES		'$(LATEX_COLOR_PAGES)'
+#      LATEX_COLOR_BUILD		'$(LATEX_COLOR_BUILD)'
+#      LATEX_COLOR_GRAPHIC		'$(LATEX_COLOR_GRAPHIC)'
+#      LATEX_COLOR_DEP			'$(LATEX_COLOR_DEP)'
+#      LATEX_COLOR_SUCCESS		'$(LATEX_COLOR_SUCCESS)'
+#      LATEX_COLOR_FAILURE		'$(LATEX_COLOR_FAILURE)'
+#
+#   These may be redefined in your environment to be any of the following:
+#
+#      black
+#      red
+#      green
+#      yellow
+#      blue
+#      magenta
+#      cyan
+#      white
+#
+#   Bold or underline may be used, as well, either alone or in combination
+#   with colors:
+#
+#      bold
+#      uline
+#
+#   Order is not important.  You may want, for example, to specify:
+#
+#   export LATEX_COLOR_SUCCESS='bold blue uline'
+#
+#   in your .bashrc file.  I don't know why, but you may want to.
+#
+# STANDARD TARGETS:
+#
+#    all:
+#        Make all possible documents in this directory.  The documents are
+#        determined by scanning for .tex and .tex.sh (described in more detail
+#        later) and omitting any file that ends in ._include_.tex or
+#        ._nobuild_.tex.  The output is a set of .pdf files.
+#
+#        If you wish to omit files without naming them with the special
+#        underscore names, set the following near the top of the Makefile,
+#        or (this is recommended) within a Makefile.ini in the same directory:
+#
+#        	includes.tex := file1.tex file2.tex
+#
+#        This will cause the files listed to be considered as include files.
+#
+#        If you have only few source files, you can set
+#
+#        	onlysources.tex := main.tex
+#
+#        This will cause only the source files listed to be considered in
+#        dependency detection.  All other .tex files will be considered as
+#        include files.  Note that these options work for *any* source type,
+#        so you could do something similar with includes.gpi, for example.
+#        Note that this works for *any valid source* target.  All of the
+#        onlysources.* variables are commented out in the shipping version of
+#        this file, so it does the right thing when they simply don't exist.
+#        The comments are purely documentation.  If you know, for example, that
+#        file.mycoolformat is supported by this Makefile, but don't see the
+#        "onlysources.mycoolformat" declared in the comments, that doesn't mean
+#        you can't use it.  Go ahead and set "onlysources.mycoolformat" and it
+#        should do the right thing.
+#
+#    show:
+#        Builds and displays all documents in this directory.  It uses the
+#        environment-overridable value of VIEW_PDF (currently $(VIEW_PDF)) to
+#        do its work.
+#
+#    all-graphics:
+#        Make all of the graphics in this directory.
+#
+#    all-pstex (only for BUILD_STRATEGY=latex):
+#        Build all fig files into pstex and pstex_t files.  Gray DOES NOT WORK.
+#
+#    all-gray-pstex (only for BUILD_STRATEGY=latex):
+#    	 Build all fig files into grayscale pstex and pstex_t files.
+#
+#    all-dot2tex:
+#    	 Build all dot files into tex files.
+#
+#    show-graphics:
+#        Builds and displays all graphics in this directory.  Uses the
+#        environment-overridable value of VIEW_GRAPHICS (currently
+#        $(VIEW_GRAPHICS)) to do its work.
+#
+#    clean:
+#        Remove ALL generated files, leaving only source intact.
+#        This will *always* skip files mentioned in the "neverclean" variable,
+#        either in this file or specified in Makefile.ini:
+#
+#        	neverclean := *.pdf *.ps
+#
+#       The neverclean variable works on all "clean" targets below, as well.
+#
+#    clean-graphics:
+#        Remove all generated graphics files.
+#
+#    clean-backups:
+#        Remove all backup files: $(backup_patterns)
+#        (XFig and other editors have a nasty habit of leaving them around)
+#        Also removes Makefile-generated .temp files
+#
+#    clean-tex:
+#        Remove all files generated from LaTeX invocations except dependency
+#        information.  Leaves graphics alone.
+#
+#    clean-deps:
+#        Removes all auto-generated dependency information.
+#
+#    clean-auxiliary:
+#        Removes extra files created by various targets (like the dependency
+#        graph output).
+#
+#    clean-nographics:
+#        Cleans everything *except* the graphics files.
+#
+#    help:
+#        This help text.
+#
+#    version:
+#        Version information about this LaTeX makefile.
+#
+# DEBUG TARGETS:
+#
+#    _all_programs:
+#        A list of the programs used by this makefile.
+#
+#    _check_programs:
+#        Checks your system for the needed software and reports what it finds.
+#
+#    _check_gpi_files:
+#        Checks the .gpi files in the current directory for common errors, such
+#        as specification of the terminal or output file inside of the gpi file
+#        itself.
+#
+#    _dependency_graph:
+#        Outputs a .dot file to stdout that represents a graph of LaTeX
+#        dependencies.  To see it, use the _show_dependency_graph target or
+#        direct the output to a file, run dot on it, and view the output, e.g.:
+#
+#        make _dependency_graph > graph.dot
+#        dot -T ps -o graph.eps graph.dot
+#        gv graph.eps
+#
+#    _show_dependency_graph:
+#        Makes viewing the graph simple: extracts, builds and displays the
+#        dependency graph given in the _dependency_graph target using the value
+#        of the environment-overridable VIEW_POSTSCRIPT variable (currently set
+#        to $(VIEW_POSTSCRIPT)).  The postscript viewer is used because it
+#        makes it easier to zoom in on the graph, a critical ability for
+#        something so dense and mysterious.
+#
+#    _all_sources:
+#        List all .tex files in this directory.
+#
+#    _sources:
+#        Print out a list of all compilable sources in this directory.  This is
+#        useful for determining what make thinks it will be using as the
+#        primary source for 'make all'.
+#
+#    _scripts:
+#        Print out a list of scripts that make knows can be used to generate
+#        .tex files (described later).
+#
+#    _all_stems:
+#        Print a list of stems.  These represent bare targets that can be
+#        executed.  Listing <stem> as a bare target will produce <stem>.pdf.
+#
+#    _includes:
+#        A list of .d files that would be included in this run if _includes
+#        weren't specified.  This target may be used alone or in conjunction
+#        with other targets.
+#
+#    _graphic_outputs:
+#        A list of all generated .eps files
+#
+#    _env:
+#        A list of environment variables and their values.  If supported by
+#        your version of make, also a list of variables known to make.
+#
+# FILE TARGETS:
+#
+#    %, %.pdf:
+#        Build a PDF file from the corresponding %.tex file.
+#
+#        If BUILD_STRATEGY=pdflatex, then this builds the pdf directly.
+#        Otherwise, it uses this old-school but effective approach:
+#
+#            latex -> dvips -> ps2pdf
+#
+#        The BUILD_STRATEGY can be overridden in Makefile.ini in the same
+#        directory.  The default is pdflatex.
+#
+#        Reasons for using latex -> dvips include the "psfrag" package, and the
+#        generation of postscript instead of PDF.  Arguments for using pdflatex
+#        include "new and shiny" and "better supported."  I can't argue with
+#        either of those, and supporting them both didn't turn out to be that
+#        difficult, so there you have it.  Choices.
+#
+#    %._show:
+#        A phony target that builds the pdf file and then displays it using the
+#        environment-overridable value of VIEW_PDF ($(VIEW_PDF)).
+#
+#    %._graphics:
+#        A phony target that generates all graphics on which %.pdf (or %.dvi)
+#        depends.
+#
+#    %.ps (only for BUILD_STRATEGY=latex):
+#        Build a Postscript file from the corresponding %.tex file.
+#        This is done using dvips.  Paper size is automatically
+#        extracted from the declaration
+#
+#        \documentclass[<something>paper]
+#
+#        or it is the system default.
+#
+#        If using beamer (an excellent presentation class), the paper
+#        size is ignored.  More on this later.
+#
+#    %.dvi (only for BUILD_STRATEGY=latex):
+#        Build the DVI file from the corresponding %.tex file.
+#
+#    %.ind:
+#        Build the index for this %.tex file.
+#
+#    %.gls:
+#        Build the nomenclature glossary for this %.tex file.
+#
+#    %.nls:
+#        Build the (newer) nomenclature file for this %.tex file.
+#
+#    %.eps:
+#        Build an eps file from one of the following file types:
+#
+#       .dot    : graphviz
+#       .gpi    : gnuplot
+#       .fig    : xfig
+#       .xvg    : xmgrace
+#       .svg    : scalable vector graphics (goes through inkscape)
+#       .png    : png (goes through NetPBM)
+#       .jpg	: jpeg (goes through ImageMagick)
+#       .eps.gz : gzipped eps
+#
+#       The behavior of this makefile with each type is described in
+#       its own section below.
+#
+#    %.pstex{,_t} (only for BUILD_STRATEGY=latex):
+#       Build a .pstex_t file from a .fig file.
+#
+# FEATURES:
+#
+#    Optional Binary Directory:
+#        If you create the _out_ directory in the same place as the makefile,
+#        it will automatically be used as a dumping ground for .pdf (or .dvi,
+#        .ps, and .pdf) output files.
+#
+#        Alternatively, you can set the BINARY_TARGET_DIR variable, either as a
+#        make argument or in Makefile.ini, to point to your directory of
+#        choice.  Note that no pathname wildcard expansion is done in the
+#        makefile, so make sure that the path is complete before going in
+#        there.  E.g., if you want to specify something in your home directory,
+#        use $$HOME/ instead of ~/ so that the shell expands it before it gets
+#        to the makefile.
+#
+#    External Program Dependencies:
+#        Every external program used by the makefile is represented by an
+#        ALLCAPS variable at the top of this file.  This should allow you to
+#        make judgments about whether your system supports the use of this
+#        makefile.  The list is available in the ALL_PROGRAMS variable and,
+#        provided that you are using GNU make 3.80 or later (or you haven't
+#        renamed this file to something weird like "mylatexmakefile" and like
+#        invoking it with make -f) can be viewed using
+#
+#        make _all_programs
+#
+#        Additionally, the availability of these programs can be checked
+#        automatically for you by running
+#
+#        make _check_programs
+#
+#        The programs are categorized according to how important they are and
+#        what function they perform to help you decide which ones you really
+#        need.
+#
+#    Colorized Output:
+#        The output of commands is colorized to highlight things that are often
+#        important to developers.  This includes {underfull,overfull}
+#        {h,v}boxes, general LaTeX Errors, each stage of document building, and
+#        the number of pages in the final document.  The colors are obtained
+#        using 'tput', so colorization should work pretty well on any terminal.
+#
+#        The colors can be customized very simply by setting any of the
+#        LATEX_COLOR_<CONTEXT> variables in your environment (see above).
+#
+#    Predecessors to TeX Files:
+#        Given a target <target>, if no <target>.tex file exists but a
+#        corresponding script or predecessor file exists, then appropriate
+#        action will be taken to generate the tex file.
+#
+#        Currently supported script or predecessor languages are:
+#
+#        sh:     %.tex.sh
+#        perl:   %.tex.pl
+#        python: %.tex.py
+#
+#           Calls the script using the appropriate interpreter, assuming that
+#           its output is a .tex file.
+#
+#           The script is called thus:
+#
+#              <interpreter> <script file name> <target tex file>
+#
+#           and therefore sees exactly one parameter: the name of the .tex
+#           file that it is to create.
+#
+#           Why does this feature exist?  I ran into this while working on
+#           my paper dissertation.  I wrote a huge bash script that used a
+#           lot of sed to bring together existing papers in LaTeX.  It
+#           would have been nice had I had something like this to make my
+#           life easier, since as it stands I have to run the script and
+#           then build the document with make.  This feature provides hooks
+#           for complicated stuff that you may want to do, but that I have
+#           not considered.  It should work fine with included dependencies,
+#           too.
+#
+#           Scripts are run every time make is invoked.  Some trickery is
+#           employed to make sure that multiple restarts of make don't cause
+#           them to be run again.
+#
+#        reST: %.rst
+#
+#           Runs the reST to LaTeX converter to generate a .tex file
+#           If it finds a file names _rststyle_._include_.tex, uses it as
+#           the "stylesheet" option to rst2latex.
+#
+#           Note that this does not track sub-dependencies in rst files.  It
+#           assumes that the top-level rst file will change if you want a
+#           rebuild.
+#
+#    Dependencies:
+#
+#        In general, dependencies are extracted directly from LaTeX output on
+#        your document.  This includes
+#
+#        *    Bibliography information
+#        *    \include or \input files (honoring \includeonly, too)
+#        *    Graphics files inserted by the graphicx package
+#
+#        Where possible, all of these are built correctly and automatically.
+#        In the case of graphics files, these are generated from the following
+#        file types:
+#
+#        GraphViz:      .dot
+#        GNUPlot:       .gpi
+#        XFig:          .fig
+#        XMgrace:       .xvg
+#        SVG:           .svg
+#        PNG:           .png
+#        JPEG:          .jpg
+#        GZipped EPS:   .eps.gz
+#
+#        If the file exists as a .eps already, it is merely used (and will not
+#        be deleted by 'clean'!).
+#
+#        LaTeX and BibTeX are invoked correctly and the "Rerun to get
+#        cross-references right" warning is heeded a reasonable number of
+#        times.  In my experience this is enough for even the most troublesome
+#        documents, but it can be easily changed (if LaTeX has to be run after
+#        BibTeX more than three times, it is likely that something is moving
+#        back and forth between pages, and no amount of LaTeXing will fix
+#        that).
+#
+#        \includeonly is honored by this system, so files that are not
+#        specified there will not trigger a rebuild when changed.
+#
+#    Beamer:
+#        A special TeX source comment is recognized by this makefile (only when
+#        BUILD_STRATEGY=latex, since this invokes psnup):
+#
+#        %%[[:space:]]*BEAMER[[:space:]]*LARGE
+#
+#        The presence of this comment forces the output of dvips through psnup
+#        to enlarge beamer slides to take up an entire letter-sized page.  This
+#        is particularly useful when printing transparencies or paper versions
+#        of the slides.  For some reason landscape orientation doesn't appear
+#        to work, though.
+#
+#        If you want to put multiple slides on a page, use this option and then
+#        print using mpage, a2ps, or psnup to consolidate slides.  My personal
+#        favorite is a2ps, but your mileage may vary.
+#
+#        When beamer is the document class, dvips does NOT receive a paper size
+#        command line attribute, since beamer does special things with sizes.
+#
+#    GNUPlot Graphics:
+#        When creating a .gpi file, DO NOT INCLUDE the "set terminal" or "set
+#        output" commands!  The makefile will include terminal information for
+#        you.  Besides being unnecessary and potentially harmful, including the
+#        terminal definition in the .gpi file makes it harder for you, the one
+#        writing the document, to preview your graphics, e.g., with
+#
+#           gnuplot -persist myfile.gpi
+#
+#        so don't do specify a terminal or an output file in your .gpi files.
+#
+#        When building a gpi file into an eps file, there are several features
+#        available to the document designer:
+#
+#        Global Header:
+#            The makefile searches for the files in the variable GNUPLOT_GLOBAL
+#            in order:
+#
+#            ($(GNUPLOT_GLOBAL))
+#
+#            Only the first found is used.  All .gpi files in the directory are
+#            treated as though the contents of GNUPLOT_GLOBAL were directly
+#            included at the top of the file.
+#
+#            NOTE: This includes special comments! (see below)
+#
+#        Font Size:
+#            A special comment in a .gpi file (or a globally included file) of
+#            the form
+#
+#            ## FONTSIZE=<number>
+#
+#            will change the font size of the GPI output.  If font size is
+#            specified in both the global file and the GPI file, the
+#            specification in the individual GPI file is used.
+#
+#        Grayscale Output:
+#            GNUplot files also support a special comment to force them to be
+#            output in grayscale *no matter what*:
+#
+#            ## GRAY
+#
+#            This is not generally advisable, since you can always create a
+#            grayscale document using the forms mentioned above.  But, if your
+#            plot simply must be grayscale even in a document that allows
+#            colors, this is how you do it.
+#
+#    XFig Graphics:
+#            No special handling is done with XFig, except when a global
+#            grayscale method is used, e.g.
+#
+#                make GRAY=1 document
+#
+#            In these cases the .eps files is created using the -N switch to
+#            fig2dev to turn off color output.  (Only works with eps, not pstex
+#            output)
+#
+#    GraphVis Graphics:
+#            Color settings are simply ignored here.  The 'dot' program is used
+#            to transform a .dot file into a .eps file.
+#
+#            If you want, you can use the dot2tex program to convert dot files
+#            to tex graphics.  The default is to just call dot2tex with no
+#            arguments, but you can change the DOT2TEX definition to include
+#            options as needed (in your Makefile.ini).
+#
+#            Note that, as with pstex, the makefile cannot use latex's own
+#            output to discover all missing dot_t (output) files, since anytime
+#            TeX includes TeX, it has to bail when it can't find the include
+#            file.  It can therefore only stop on the first missing file it
+#            discovers, and we can't get a large list of them out easily.
+#
+#            So, the makefile errors out if it's missing an included dot_t
+#            file, then prompts the user to run this command manually:
+#
+#                make all-dot2tex
+#
+#    GZipped EPS Graphics:
+#
+#        A .eps.gz file is sometimes a nice thing to have.  EPS files can get
+#        very large, especially when created from bitmaps (don't do this if you
+#        don't have to).  This makefile will unzip them (not in place) to
+#        create the appropriate EPS file.
+#
+endef
+
+#
+# DEPENDENCY CHART:
+#
+#digraph "g" {
+#    rankdir=TB
+#    size="9,9"
+#    edge [fontsize=12 weight=10]
+#    node [shape=box fontsize=14 style=rounded]
+#
+#    eps [
+#        shape=Mrecord
+#        label="{{<gpi> GNUplot|<epsgz> GZip|<dot> Dot|<fig> XFig}|<eps> eps}"
+#        ]
+#    pstex [label="%.pstex"]
+#    pstex_t [label="%.pstex_t"]
+#    tex_outputs [shape=point]
+#    extra_tex_files [shape=point]
+#    gpi_data [label="<data>"]
+#    gpi_includes [label="_include_.gpi"]
+#    aux [label="%.aux"]
+#    fls [label="%.fls"]
+#    idx [label="%.idx"]
+#    glo [label="%.glo"]
+#    ind [label="%.ind"]
+#    log [label="%.log"]
+#    tex_sh [label="%.tex.sh"]
+#    rst [label="%.rst"]
+#    tex [
+#        shape=record
+#        label="<tex> %.tex|<include> _include_.tex"
+#        ]
+#    include_aux [label="_include_.aux"]
+#    file_bib [label=".bib"]
+#    bbl [label="%.bbl"]
+#    dvi [label="%.dvi"]
+#    ps [label="%.ps"]
+#    pdf [label="%.pdf"]
+#    fig [label=".fig"]
+#    dot [label=".dot"]
+#    gpi [label=".gpi"]
+#    eps_gz [label=".eps.gz"]
+#
+#    gpi_files [shape=point]
+#
+#    rst -> tex:tex [label="reST"]
+#    tex_sh -> tex:tex [label="sh"]
+#    tex_pl -> tex:tex [label="perl"]
+#    tex_py -> tex:tex [label="python"]
+#    tex -> tex_outputs [label="latex"]
+#    tex_outputs -> dvi
+#    tex_outputs -> aux
+#    tex_outputs -> log
+#    tex_outputs -> fls
+#    tex_outputs -> idx
+#    tex_outputs -> include_aux
+#    aux -> bbl [label="bibtex"]
+#    file_bib -> bbl [label="bibtex"]
+#    idx -> ind [label="makeindex"]
+#    glo -> gls [label="makeindex"]
+#    nlo -> nls [label="makeindex"]
+#    gls -> extra_tex_files
+#    nls -> extra_tex_files
+#    ind -> extra_tex_files
+#    bbl -> extra_tex_files
+#    eps -> extra_tex_files
+#    extra_tex_files -> dvi [label="latex"]
+#    gpi_files -> eps:gpi [label="gnuplot"]
+#    gpi -> gpi_files
+#    gpi_data -> gpi_files
+#    gpi_includes -> gpi_files
+#    eps_gz -> eps:epsgz [label="gunzip"]
+#    fig -> eps:fig [label="fig2dev"]
+#    fig -> pstex [label="fig2dev"]
+#    fig -> pstex_t [label="fig2dev"]
+#    pstex -> pstex_t [label="fig2dev"]
+#    dot -> eps:dot [label="dot"]
+#    dvi -> ps [label="dvips"]
+#    include_aux -> bbl [label="bibtex"]
+#    ps -> pdf [label="ps2pdf"]
+#
+#    edge [ color=blue label="" style=dotted weight=1 fontcolor=blue]
+#    fls -> tex:include [label="INPUT: *.tex"]
+#    fls -> file_bib [label="INPUT: *.aux"]
+#    aux -> file_bib [label="\\bibdata{...}"]
+#    include_aux -> file_bib [label="\\bibdata{...}"]
+#    log -> gpi [label="Graphic file"]
+#    log -> fig [label="Graphic file"]
+#    log -> eps_gz [label="Graphic file"]
+#    log -> dot [label="Graphic file"]
+#    log -> idx [label="No file *.ind"]
+#    log -> glo [label="No file *.gls"]
+#    log -> nlo [label="No file *.nls"]
+#    gpi -> gpi_data [label="plot '...'"]
+#    gpi -> gpi_includes [label="load '...'"]
+#    tex:tex -> ps [label="paper"]
+#    tex:tex -> pdf [label="embedding"]
+#}
+
+#
+# DEPENDENCY CHART SCRIPT
+#
+# $(call output_dependency_graph,[<output file>])
+define output-dependency-graph
+	if [ -f '$(this_file)' ]; then \
+	$(SED) \
+		-e '/^[[:space:]]*#[[:space:]]*DEPENDENCY CHART:/,/^$$/!d' \
+		-e '/DEPENDENCY CHART/d' \
+		-e '/^$$/d' \
+		-e 's/^[[:space:]]*#//' \
+		$(this_file) $(if $1,> '$1',); \
+	else \
+		$(ECHO) "Cannot determine the name of this makefile."; \
+	fi
+endef
+# vim: noet sts=0 sw=8 ts=8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/README	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,4 @@
+Zum Erzeugen der Dokumentation folgenden Befehl auf
+der Kommandozeile absetzen:
+
+  make importer-manual.pdf
Binary file flys-backend/doc/documentation/de/figures/bfg_logo.png has changed
Binary file flys-backend/doc/documentation/de/figures/intevation-logo.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/importer-geodaesie.tex	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,356 @@
+\section{Geodatenimport}
+
+Der Geodaten Importer ist ein in Python geschriebenes Kommandozeilen Tool zum
+Import von Shapefiles in eine Datenbank. Zum Lesen der Shapefiles und zum
+Schreiben der Geodaten in die Datenbank wird GDAL verwendet. Der Import in eine
+Oracle Datenbank erfordert, dass GDAL und GDAL Python Bindungs mit
+Oracle Unterstützung installiert sind. Weitere Details hierzu befinden sich im
+Kapitel \ref{Systemanforderungen} und \ref{Installationsanleitung}.
+
+Der Importer kann mit einem Shellscript von der Kommandozeile gestartet werden
+(siehe Kapitel \ref{Starten des Geodaten Importers}). Nach dem Start wird anhand der
+Konfiguration festgestellt, welche Klassen von Shapefiles aus dem Dateisystem
+importiert werden sollen. Für jede Klasse gibt es einen speziellen
+Parser, der die speziellen Attribute eines Shapefiles liest und in die entsprechende
+Relation der Datenbank schreibt. Die Parser sind speziell auf das
+Dateisystem der BfG ausgerichtet. So wird z.B. erwartet, dass die Shapefiles der
+Gewässerachse im Ordner $Geodaesie/Flussachse+km$ liegen. Weitere Informationen zu
+den einzelnen Parsern sind dem nächsten Kapitel \ref{Beschreibung der Parser} zu
+entnehmen. Der Erfolg oder Misserfolg eines Shape-Imports wird je nach
+Konfiguration im Logfile vermerkt. Folgende Einträge können dem Logfile
+entnommen werden:
+
+\textbf{INFO: Inserted 4 features}
+\\Gibt die Anzahl der erfolgreich importierten Features an.\\
+
+\textbf{INFO: Failed to create 2 features}
+\\Gibt die Anzahl der Features an, die nicht importiert werden konnten.\\
+
+\textbf{INFO: Found 3 unsupported features}
+\\Gibt die Anzahl der Features an, die aufgrund ihres Datentyps nicht importiert
+werden konnten. Z.B: es werden Linien erwartet, im Shapefile sind jedoch
+Polygone enthalten.\\
+
+\textbf{ERROR: No source SRS given! No transformation possible!}
+\\Das Shapefile enthält keine Information, in welcher Projektion die Geometrien
+vorliegen. Es findet keine Transformation in die Zielprojektion statt. Bitte
+beachten Sie, dass FLYS diese Geometrien später ggf nicht korrekt darstellen
+kann.
+
+\textbf{ERROR: Unable to insert feature: DETAIL}
+\\Beim Lesen der Attribute eines Features ist ein Fehler aufgetreten.
+Das Feature konnte nicht in die Datenbank geschrieben werden.\\
+
+\textbf{ERROR: Exception while committing transaction}
+\\Beim Abschluss des Schreib-Vorgangs in die Datenbank ist ein unerwarteter
+Fehler aufgetreten. Die Features des Shapes sind nicht importiert worden.\\
+
+\textbf{ERROR 1: ORA-01017: invalid username/password; logon denied}
+\\Es konnte keine Verbindung zur Oracle Datenbank hergestellt werden. Prüfen Sie
+die Verbindungseinstellungen.
+
+Damit die Geodaten eines Shapes später eindeutig in der Datenbank identifiziert
+werden können, wird für jede Geometrie der Pfad des Shapes im Dateisystem in
+einer Spalte der Datenbank gespeichert. Anwendungen, die auf der Datenbank
+aufbauen, können die Geodaten eines Shapefiles später anhand dieses Merkmals
+gruppieren und anzeigen.
+
+
+\subsection{Beschreibung der Parser}
+\label{Beschreibung der Parser}
+
+Wie im letzten Kapitel beschrieben, sind die Parser speziell an das Dateisystem
+der BfG ausgerichtet. Im Folgenden werden zu jedem Parser folgende Informationen
+angegeben:
+
+\textbf{Pfad}
+\\Der Pfad, in dem die Shapefiles im Dateisystem abgelegt sein müssen ausgehend
+vom Gewässer Verzeichnis.
+
+\textbf{Geometrie}
+\\Der Geometrie Typ, der für diese Klasse von Shapefiles erwartet wird.
+
+\textbf{Attribute}
+\\Eine Liste der Attribute, die vom Parser aus dem Shape gelesen werden.
+
+
+\subsubsection{Achsen}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Geodaesie/Flussachse+km \\
+Geometrie   &   LINESTRING \\
+Attribute   &   name, kind \\
+\end{tabular}
+
+
+\subsubsection{Hydrologische Grenzen}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Hydrologie/Hydr.Grenzen/Linien \\
+Geometrie   &   LINESTRING, POLYGON \\
+Attribute   &   name, kind \\
+\end{tabular}
+
+\subsubsection{Bauwerke}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Geodaesie/Bauwerke \\
+Geometrie   &   LINESTRING \\
+Attribute   &   name, Name, KWNAAM \\
+\end{tabular}
+
+
+\subsubsection{Einzugsgebiete}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Hydrologie/Einzugsgebiet \\
+Geometrie   &   POLYGON, MULTIPOLYGON \\
+Attribute   &   name, Name, AREA, area \\
+\end{tabular}
+
+
+\subsubsection{Querprofilspuren}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Geodaesie/Querprofile \\
+Geometrie   &   LINESTRING \\
+Attribute   &   KILOMETER, KM, STATION, ELEVATION \\
+\end{tabular}
+
+
+\subsubsection{Festpunkte}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Geodaesie/Festpunkte \\
+Geometrie   &   POINT \\
+Attribute   &   name, KM, ELBE\_KM, X, Y, HPGP \\
+\end{tabular}
+
+
+\subsubsection{Talaue}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Hydrologie/Hydr.Grenzen \\
+Geometrie   &   POLYGON, MULTIPOLYGON \\
+Attribute   &   name \\
+\end{tabular}
+
+
+\subsubsection{Pegelstationen}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Hydrologie/Streckendaten \\
+Geometrie   &   POINT \\
+Attribute   &   Name, name, MPNAAM \\
+\end{tabular}
+
+
+\subsubsection{Hochwasserschutzanlagen}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Hydrologie/HW-Schutzanlagen \\
+Geometrie   &   LINESTRING \\
+Attribute   &   TYP, Bauart, Name, name \\
+\end{tabular}
+
+
+\subsubsection{Kilometrierung}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Geodaesie/Flussachse+km \\
+Geometrie   &   POINT \\
+Attribute   &   name, km, KM \\
+\end{tabular}
+
+
+\subsubsection{Linien}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Geodaesie/Linien \\
+Geometrie   &   LINESTRING, MULTILINESTRING \\
+Attribute   &   name, TYP, Z \\
+
+Anmerkung   & Wenn kein Attribut 'TYP' definiert ist, wird standardmäßig der Wert \\
+            & 'DAMM' angenommen. Fehlt ein Attribut 'Z' wird '9999' als Höhe \\
+            & angenommen. \\
+\end{tabular}
+
+
+\subsubsection{Überschwemmungsfläche}
+\hspace{1cm}
+\begin{tabular}[t]{ll}
+Pfad        &   Hydrologie/UeSG/Berechnung \\
+Geometrie   &   POLYGON, MULTIPOLYGON \\
+Attribut    &   name, diff, count, area, perimeter \\
+\end{tabular}
+
+
+\subsection{Systemanforderungen}
+\label{Systemanforderungen}
+\begin{itemize}
+  \item Oracle Datenbank inkl. Schema für FLYS
+  \item GDAL Binding für Python mit Oracle Support
+  \item ogr2ogr
+  \item Python $>=$ 2.6
+\end{itemize}
+
+
+\subsection{Installationsanleitung}
+\label{Installationsanleitung}
+\begin{itemize}
+
+ \item Python\\
+ Zum Starten des Importers ist es notwendig Python zu installieren. Dies können
+ Sie mit folgendem Befehl auf der Kommandozeile erledigen:
+
+ \begin{lstlisting}
+    zypper in python
+ \end{lstlisting}
+
+ \item Oracle Instantclient\\
+ Der Oracle Instantclient 11.2 wird benötigt, damit der Importer mittels Python
+ und GDAL in die bestehende Oracle Datenbank schreiben kann. Dazu ist es
+ erforderlich, folgende Archive von Oracle herunterzuladen. Zu finden sind die
+ folgenden Pakete unter\\
+ \href{http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html}{http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html}
+
+ \begin{itemize}
+    \item instantclient-basic-linux-x86-64-11.2.0.2.0.zip
+    \item instantclient-sdk-linux-x86-64-11.2.0.2.0.zip
+    \item instantclient-sqlplus-linux-x86-64-11.2.0.2.0.zip
+ \end{itemize}
+
+ Anschließend führen Sie folgende Befehle auf der Kommandozeile aus:
+
+ \begin{lstlisting}
+
+    mkdir /opt
+
+    unzip ~/instantclient-basic-linux-x86-64-11.2.0.2.0.zip -d /opt
+    unzip ~/instantclient-sdk-linux-x86-64-11.2.0.2.0.zip -d /opt
+    unzip ~/instantclient-sqlplus-linux-x86-64-11.2.0.2.0.zip -d /opt
+
+    mkdir /opt/instantclient_11_2/lib
+    cd /opt/instantclient_11_2/lib
+    ln -s ../libclntsh.so.11.1 .
+    ln -s ../libclntsh.so.11.1 libclntsh.so
+    ln -s ../libnnz11.so .
+    ln -s ../libocci.so.11.1 .
+    ln -s ../libocci.so.11.1 libocci.so
+    ln -s ../libociei.so .
+    ln -s ../libocijdbc11.so .
+    ln -s ../libsqlplusic.so .
+    ln -s ../libsqlplus.so .
+
+    rpm -i --nodeps ~/flys-importer/rpm/RPMS/x86_64/libgdal1180-1.8.0-intevation1.x86_64.rpm 
+    rpm -i --nodeps ~/flys-importer/rpm/RPMS/x86_64/libgdal180-devel-1.8.0-intevation1.x86_64.rpm
+    rpm -i --nodeps ~/flys-importer/rpm/RPMS/x86_64/gdal180-1.8.0-intevation1.x86_64.rpm
+
+ \end{lstlisting}
+
+ Sollten keine Fehler aufgetreten sein, haben Sie den \textit{Oracle
+ Instantclient 11.2} erfolgreich entpackt und im Dateisystem unter
+ \textit{/opt/instantclient\_11\_2} abgelegt. Mit den Befehlen $rpm -i --nodeps$
+ haben Sie anschließend die notwendigen Bindings installiert, damit der Importer
+ die Geodaten in die Oracle Datenbank schreiben kann.
+
+\end{itemize}
+
+
+\subsection{Konfiguration}
+\label{Konfiguration}
+Der Geodaten Importer kann über die Datei \textit{contrib/run\_geo.sh}
+konfiguriert werden. Öffnen Sie die Datei mit einem Texteditor Ihrer Wahl.
+In den Zeilen 4-9 werden Optionen definiert, die zwangsläufig angepasst
+werden müssen:
+
+\textbf{RIVER\_PATH}
+\\Der Pfad zum Gewässer im Dateisystem.
+
+\textbf{RIVER\_ID}
+\\Die Datenbank ID des zu importierenden Gewässers.
+
+\textbf{TARGET\_SRS}
+\\Das EPSG Referenzsystem in das die Geodaten beim Import projeziert werden
+sollen.
+
+\textbf{HOST}
+\\Der Host der Datenbank.
+
+\textbf{USER}
+\\Der Nutzer, der zum Verbinden zur Datenbank verwendet wird.
+
+\textbf{PASS}
+\\Das Passwort für USER zum Verbinden zur Datenbank.
+
+In den Zeilen 12-23 werden weitere Optionen definiert, die bei Bedarf angepasst
+werden können. Falls nicht anders angegeben, können die Optionen mit den Werten
+`0` und `1` belegt werden.
+
+\textbf{VERBOSE}
+\\Dieser Wert gibt die Granularität der Log-Ausgaben während des
+Imports an. Je höher der Wert, desto mehr Informationen werden
+in das Logfile geschrieben. Aktuell sind die Werte `0`, `1` und
+`2` definiert. Wird der Wert `0` gesetzt, werden nur Fehler und
+Warnungen in das Logfile geschrieben. Bei `1` werden neben
+Fehlern und Warnungen auch Infos in das Logfile geschrieben. Bei
+`2` werden sämtliche Ausgaben des Programms geschrieben. Dieser
+Modus ist hauptsächlich für die Entwicklung gedacht.
+
+\textbf{SKIP\_AXIS}
+\\Bei gesetztem Wert `1` werden keine Flussachsen importiert.
+
+\textbf{SKIP\_KMS}
+\\Bei gesetztem Wert `1` werden keine Kilometrierungen importiert.
+
+\textbf{SKIP\_CROSSSECTIONS}
+\\Bei gesetztem Wert `1` werden keine Querprofilespuren importiert.
+
+\textbf{SKIP\_LINES}
+\\Bei gesetztem Wert `1` werden keine Linien importiert.
+
+\textbf{SKIP\_FIXPOINTS}
+\\Bei gesetztem Wert `1` werden keine Festpunkte importiert.
+
+\textbf{SKIP\_BUILDINGS}
+\\Bei gesetztem Wert `1` werden keine Bauwerke importiert.
+
+\textbf{SKIP\_FLOODPLAINS}
+\\Bei gesetztem Wert `1` werden keine Talauen importiert.
+
+\textbf{SKIP\_HYDR\_BOUNDARIES}
+\\Bei gesetztem Wert `1` werden keine hydrologischen Grenzen importiert.
+
+\textbf{SKIP\_HWS}
+\\Bei gesetztem Wert `1` werden kein Hochwasserschutzanlagen importiert.
+
+\textbf{SKIP\_GAUGE\_LOCATION}
+\\Bei gesetztem Wert `1` werden keine Pegelorte importiert.
+
+\textbf{SKIP\_CATCHMENTS}
+\\Bei gesetztem Wert `1` werden keine Einzugsgebiete importiert.
+
+\textbf{SKIP\_UESG}
+\\Bei gesetztem Wert `1` werden keine Überschwemmungsflächen importiert.
+
+
+\subsection{Starten des Geodaten Importers}
+\label{Starten des Geodaten Importers}
+Der Geodaten Importer wird mittels eines Shellskripts von einer Konsole
+gestartet. Dazu führen Sie folgenden Befehl aus:\\
+
+\begin{lstlisting}
+    sh contrib/run_geo.sh > geo-import.log
+\end{lstlisting}
+
+Der Importer wird nun gestartet. Sämtliche Log-Ausgaben werden in die Datei
+$geo-import.log$ geschrieben.
+
+\textbf{Hinweis}
+\\Bitte beachten Sie, dass der Geodaten Importer aufgrund der eingesetzten
+Technologien derzeit nicht in der Lage ist, lesend auf die Oracle Datenbank
+zuzugreifen. Entsprechend kann beim Import nicht festgestellt werden, ob sich
+Shapefiles bereits in der Datenbank befinden, oder nicht. Ein erneuter Import
+Vorgang der Geodaten würde also dazu führen, dass Geometrien doppelt in der
+Datenbank abgelegt werden.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/importer-hydr-morph.tex	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,749 @@
+\section{Fachdatenimport}
+
+Der Fachdatenimporter dient dazu, hydrologische und morphologische Gewässerdaten
+aus dem Dateisystem in die FLYS3-Datenbank zu importieren. Das Werkzeug
+orientiert sich hierbei an der Dateihierachie, so wie sie auch von Desktop-FLYS
+ausgelesen wird. Der Import Vorgang ist in zwei Phasen unterteilt:
+
+\begin{itemize}
+    \item Lesen aller Daten eines Gewässers aus dem Dateisystem.
+    \item Schreiben der erfolgreich eingelesenen Daten in die Datenbank.
+\end{itemize}
+
+Sollte beim Lese- oder Schreib-Vorgang eines Gewässers ein Fehler auftreten, so
+werden sämtliche Daten des Gewässers verworfen. Beide Phasen zusammen bilden
+somit eine Transaktion.
+
+\textbf{Hinweis}
+\\Der Import geht wie auch Desktop-FLYS davon aus, dass die Dateien Latin-1
+encodiert vorliegen! Stellen Sie also sicher, dass das von Ihnen verwendete
+Encoding korrekt ist. Andernfalls ist es möglich, dass es während des Imports zu
+unerwarteten Problemen kommt.
+
+Der Importer ist ein in Java geschriebenes Werkzeug und kann von der Konsole aus
+gestartet werden. Sämtlich Konfigurationen können über sogenannte
+\textit{System-Properties} übergeben werden. Eine \textit{System-Property} wird
+dabei mittels \textit{-Dkey=value} beim Start übergeben. Im folgenden Beispiel
+würde der Importer mit einer Konfiguration \textit{flys.backend.importer.dry.run},
+welche den Wert \textit{true} gesetzt hat, gestartet.
+
+\begin{lstlisting}
+    java -Dflys.backend.importer.dry.run=true de.intevation.flys.importer.Importer
+\end{lstlisting}
+
+Auf gleiche Weise können dem Importer sämtliche Optionen zur Konfiguration
+beim Start mitgegeben werden. Im folgenden werden die möglichen System-Properties und
+ihre Auswirkung auf den Import genauer beschrieben. In den Kapiteln
+\ref{configuration} und \ref{start-hydr} wird zur Einfachheit jedoch ein
+Shellskript verwendet, das eine Standardkonfiguration vorgibt und den Importer
+mit allen erforderlichen Konfigurationen startet.
+
+
+\subsection{Importierte Daten}
+In diesem Kapitel werden die Datentypen aufgelistet und erläutert, wie sie vom
+Importer eingelesen werden.
+
+\subsubsection{Streckenfavoriten (*.km-Dateien)}
+Der Import der Streckenfavoriten kann mit \textbf{-Dflys.backend.importer.skip.annotations=true}
+unterdrückt werden.
+
+Zur Klassifikation von Streckenfavoriten muss mittels\\
+\textbf{-Dflys.backend.importer.annotation.types=DATEI} der Pfad zu einer
+XML-Datei angegeben werden. In dieser Datei werden die Typen und Regeln
+festgelegt, anhand derer die Klassifikation während des Import-Vorgangs
+vorgenommen wird. Details hierzu befinden sich im Kapitel \ref{annotation-types}.
+
+\subsubsection{Pegel, Stammdaten (*.glt, *.sta-Dateien)}
+Der Import von Pegel- und Stammdaten kann mit \textbf{'-Dflys.backend.importer.skip.gauges=true'}
+unterdrückt werden. Die .glt-Datei, die neben der .wst-Datei liegt, wird zuerst
+ausgelesen. Es werden nur *.sta-Datei von Pegeln geladen, die in der .glt-Datei
+vermerkt sind.
+
+Mittels \textbf{-Dflys.backend.sta.parse.gauge.numbers=true'} wird versucht, die
+offiziellen Pegelnummern aus den Stammdaten zu extrahieren.
+\textbf{Dies ist mit Vorsicht zu behandeln, denn die meisten STA-Dateien
+enthalten invalide Pegelnummern.}
+
+Die System-Property \textbf{flys.backend.main.value.types} kann einen String
+mit gültigen Typen von Stammdaten enthalten. Vorbelegt ist \textit{QWTD}. In der
+Praxis ist \textit{QWD} eine sinnvolle Belegung.
+
+\subsubsection{Basis-Wasserstände (gewaesser.wst-Dateien)}
+Der Import von Wasserständen kann mit \textbf{-Dflys.backend.importer.skip.wst=true} unterdrückt werden.
+
+\subsubsection{Zusätzliche Längsschnitte (*.zus, *.wst-Dateien)}
+Der Import von zusätzlichen Längsschnitten kann mit \textbf{-Dflys.backend.importer.skip.extra.wsts=true}
+unterdrückt werden. Es werden die *.zus- und *.wst-Dateien aus dem Verzeichnis
+\textit{../Zus.Längsschnitte} relativ zur gewaesser.wst-Datei betrachtet.
+
+\subsubsection{Fixierungen (*.wst-Dateien)}
+Der Import von Fixierungen kann mit \textbf{-Dflys.backend.importer.skip.fixations=true}
+unterdrückt werden. Es werden die *.wst-Dateien aus dem Verzeichnis
+\textit{../Fixierungen} relativ zur gewaesser.wst-Datei betrachtet.
+
+\subsubsection{Amtliche Linien (*.wst-Dateien)}
+Der Import von amtlichen Linien kann mit \textbf{-Dflys.backend.importer.skip.official.lines=true}
+unterdrückt werden. Es werden die \textit{Amtl\_Linien.wst}-Dateien aus dem
+Verzeichnis \textit{../Basisdaten} und \textit{../Fixierungen} relativ zur
+\textit{gewaesser.wst}-Datei betrachtet.
+
+\subsubsection{Profilspuren (*.prf-Dateien)}
+Der Import von Profilspuren kann mit \textbf{-Dflys.backend.importer.skip.prfs=true}
+unterdrückt werden. Es werden rekursiv alle *.prf-Dateien aus \textit{../../..}
+relativ zur gewaesser.wst-Datei betrachtet. Vor dem Import werden mit Hilfe
+eines Längen- und eines MD5-Summen-Vergleichs inhaltliche Duplikate
+ausgeschlossen.
+
+\subsubsection{Hydraulische Kennzahlen (*.hyk)}
+Der Import von hydraulischen Kennzahlen kann mit \textbf{-Dflys.backend.importer.skip.hyks=true} unterdrückt
+werden. Es werden rekursiv alle *.hyk-Dateien aus \textit{../../..} relativ zur
+gewaesser.wst-Datei betrachtet. Vor dem Import werden mit Hilfe eines Längen- und
+eines MD5-Summen-Vergleichs inhaltliche Duplikate ausgeschlossen.
+
+\subsubsection{Hochwassermarken (*.zus, *.wst)}
+Der Import von Hochwassermarken kann mit \textbf{-Dflys.backend.importer.skip.flood.water=true}
+unterdrückt werden. Es werden die *.zus- und *.wst-Dateien aus dem Verzeichnis
+\textit{../HW-Marken} relativ zur gewaesser.wst-Datei betrachtet.
+
+\subsubsection{Hochwasserschutzanlagen (*.zus)}
+Der Import von Hochwasserschutzanlagen kann mit \textbf{-Dflys.backend.importer.skip.flood.protection=true}
+unterdrückt werden. Es werden die *.zus- und *.wst-Dateien aus dem Verzeichnis
+\textit{../HW-Schutzanlagen} relativ zur \textit{gewaesser.wst}-Datei betrachtet.
+
+\subsubsection{Sohlhöhen (Peilungen)}
+Der Import von Sohlhöhen-Peilungen kann mit \textbf{-Dflys.backend.importer.skip.bed.height.single=true}
+unterdrückt werden. Es werden die Dateien aus dem Verzeichnis
+\textit{Morphologie/Sohlhoehen/Einzeljahre} geladen.
+
+\subsubsection{Sohlhöhen (Epochen)}
+Der Import Sohlhöhen-Epochen kann mit \textbf{-Dflys.backend.importer.skip.bed.height.epoch=true}
+unterdrückt werden. Es werden die Dateien aus dem Verzeichnis
+\textit{Morphologie/Sohlhoehen/Epochen} geladen.
+
+\subsubsection{Sedimentdichte}
+Der Import der Sedimentdichte kann mit
+\textbf{-Dflys.backend.importer.skip.sediment.density=true}
+unterdrückt werden. Es werden alle Dateien aus dem Verzeichnis
+\textit{Morphologie/Sedimentdichte} geladen.
+
+\subsubsection{Morphologische Breite}
+Der Import der morphologischen Breite kann mit
+\textbf{-Dflys.backend.importer.skip.morphological.width=true}
+unterdrückt werden. Es werden alle Dateien aus dem Verzeichnis
+\textit{Morphologie/morphologische\_Breite} geladen.
+
+\subsubsection{Fließgeschwindigkeit}
+Der Import der Fließgeschwindigkeit kann mit
+\textbf{-Dflys.backend.importer.skip.flow.velocity=true}
+unterdrückt werden. Es werden alle Modellrechnungen aus dem Verzeichnis\\
+\textit{Morphologie/Geschwindigkeit\_Schubspannung/Modellrechnungen} und\\
+\textit{Morphologie/Geschwindigkeit\_Schubspannung/v-Messungen} geladen.
+
+\subsubsection{Sedimentfracht}
+Der Import der Sedimentfracht kann mit
+\textbf{-Dflys.backend.importer.skip.sediment.yield=true}
+unterdrückt werden. Es werden alle Dateien aus dem Verzeichnis
+\textit{Morphologie/Fracht} geladen. Dabei werden die Dateien aus dem
+Unterverzeichnissen \textit{Einzeljahre} und \textit{Epochen} entsprechend als
+\textit{Einzeljahre} und \textit{Epochen} vermerkt.
+
+\subsubsection{Wasserspiegellagen für MINFO}
+Der Import der MINFO spezifischen Wasserspiegellagen kann mit\\
+\textbf{-Dflys.backend.importer.skip.waterlevels=true}
+unterdrückt werden. Es werden alle Dateien aus dem Verzeichnis
+\textit{Morphologie/Fixierungsanalyse/Wasserspiegellagen} geladen.
+
+\subsubsection{Wasserspiegeldifferenzen für MINFO}
+Der Import der Wasserspiegellagendifferenzen kann mit\\
+\textbf{-Dflys.backend.importer.skip.waterlevel.differences=true}
+unterdrückt werden. Es werden alle Dateien aus dem Verzeichnis
+\textit{Morphologie/Fixierungsanalyse/Wasserspiegeldifferenzen} geladen.
+
+\subsubsection{Transport Abfluss Beziehung}
+Der Import der Daten für die Transport Abfluss Beziehung kann mit\\
+\textbf{flys.backend.importer.skip.sq.relation=true} unterdrückt
+werden. Es werden alle Dateien unter
+\textit{Feststofftransport-Abfluss-Beziehung} geladen.
+
+
+\subsection{Klassifikation von Streckenfavoriten}
+\label{annotation-types}
+Streckenfavoriten werden aus KM-Dateien importiert. Um die einzelnen Einträge
+einer Kategorie (Brücke, Pegel, etc.) zuzuordnen, kann eine XML angegeben werden,
+in der Regeln für diese Klassifikation definiert werden. Schematisch gliedert
+sich diese Datei in die zwei Bereiche 'types' und 'patterns':
+
+\begin{lstlisting}
+    <annotation>
+        <types>
+            <type>...</type>
+            <type>...</type>
+            ...
+        </types>
+        <patterns>
+            <pattern>...</pattern>
+            <pattern>...</pattern>
+            ...
+        </patterns>
+    </annotation>
+\end{lstlisting}
+
+In der Sektion \textit{types} werden die Kategorien vereinbart, in die klassifiziert
+werden soll. Dies geschieht mit entsprechenden Zeilen in der XML Datei. Es folgt
+ein Auszug aus einer solchen Datei:
+
+\begin{lstlisting}
+  <type name="Pegel"/>
+  <type name="Brücke"/>
+  ...
+  <type name="Sonstige" default="true"/>
+\end{lstlisting}
+
+Das Attribut 'default' darf maximal einmal vergeben werden und besagt, dass diese
+Kategorie gewählt werden soll, wenn keine andere Kategorie zugeordnet werden kann.
+
+In der Sektion 'patterns' werden dann die Regeln definiert, die einzelne Einträge
+den zuvor definierten Kategorien zuordnet. Hierfür können zwei Arten von
+Definitionen angegeben werden:
+
+\begin{lstlisting}
+  <file pattern="^Brücken$" type="Brücke"/>
+\end{lstlisting}
+
+oder
+
+\begin{lstlisting}
+  <line pattern="^Brücke[:\s].*$" type="Brücke"/>
+\end{lstlisting}
+
+Die erste Variante bestimmt die Kategorie, die pro KM-Datei gelten soll.
+\textit{pattern} ist hierbei ein regulärer Ausdruck, der auf den Dateinamen
+angewandt wird. Passt der Name der Datei auf den regulären Ausdruck, wird
+\textit{type} als Vorgabe angenommen. Treffen mehrere \textit{file}-Regeln zu,
+wird der erste Treffer angewandt. Findet keine der \textit{file}-Regeln Anwendung, wird
+die Kategorie ausgewählt, die in der \textit{types}-Section das Attribut
+\textit{default} gesetzt hat.
+
+Die zweite Regel-Variante \textit{line} wird auf jeden Eintrag innerhalb einer KM-Datei
+auf den Bezeichner der Streckenfavoriten angewandt. Als Muster dient auch hier
+ein regulärer Ausdruck, der über das Attribut \textit{pattern} definiert wird.
+Die Kategorie wird im Trefferfall über das Attribut \textit{type} bestimmt.
+Treffen mehrere Regeln zu, wird die Kategorie gewählt, die zum ersten Treffer
+gehört. Trifft keine Regel zu wird der Eintrag der Kategorie zugeteilt, die für
+die beinhaltende Datei als Vorgabe gilt.
+
+
+\subsection{Konfiguration}
+\label{configuration}
+Zum Starten des Importers ist es notwendig, in der Datei
+\textit{contrib/run\_hydr\_morph.sh} die Variablen am Anfang der Datei
+anzupassen. Im folgenden werden notwendige und optionale Einstellungen
+beschrieben, die beim Starten des Importers berücksichtigt werden. Folgende
+Einstellungen sind zwangsläufig an die bestehende Umgebung anzupassen:
+
+\textbf{INFO\_GEW}
+\\Diese Option muss auf eine valide *.gew Datei verweisen (bekannt aus
+Desktop-FLYS). Wichtig für den Importer sind in dieser Datei die Zeilen, die mit
+\textit{WSTDatei:} beginnen. In ihnen wird der Pfad zu der zentralen WST-Datei
+des jeweiligen Gewässers angegeben. Alle anderen importierten Dateien werden in
+ihrer Lage im Dateisystem relativ zur Lage dieser Datei betrachtet.
+
+\textbf{BACKEND\_USER}
+\\Der Nutzername, der zum Verbinden zur Datenbank verwendet werden soll.
+
+\textbf{BACKEND\_PASS}
+\\Das Passwort, welches in Kombination mit \textbf{BACKEND\_USER} zum Verbinden
+zur Datenbank verwendet werden soll.
+
+\textbf{BACKEND\_HOST}
+\\Der Datenbank-Host. In der Regel sollte hier \textit{localhost} eingetragen
+werden, da es empfohlen wird, den Importer auf dem selben Host zu starten, auf
+dem auch die Datenbank läuft.
+
+\textbf{BACKEND\_PORT}
+\\Der Port auf dem die Datenbank zu erreichen ist. Bei einer Oracle XE Instanz
+z.B.: \textit{1521}, sofern nicht anders konfiguriert.
+
+\textbf{BACKEND\_NAME}
+\\Der Name der Datenbank Instanz. Beispielsweise \textit{XE} bei einer Oracle XE
+Instanz.
+
+\textbf{BACKEND\_DB\_PREFIX}
+\\Der Präfix zum Aufbau einer Datenbankverbindung. Für Oracle z.B.: \textit{jdbc:oracle:thin:@}.
+
+\textbf{BACKEND\_DB\_DRIVER}
+\\Der Name des JDBC-Treibers, der es erlaubt das Protokoll der Datenbank zu
+sprechen. Im Falle einer Oracle XE wäre dies z.B.: \textit{oracle.jdbc.OracleDriver}.
+
+\textbf{BACKEND\_DB\_DIALECT}
+\\Der Hibernate-Dialekt, den die Datenbank versteht. Im Falle einer Oracle-XE
+wäre dies z.B.: \textit{org.hibernate.dialect.OracleDialect}.
+
+
+Weitere Details zum Verbinden zu einer Oracle Datenbank finden Sie unter\\
+\href{http://www.orafaq.com/wiki/JDBC}{http://www.orafaq.com/wiki/JDBC}. Alle weiteren Einstellungen sind
+optional anpassbar:
+
+\textbf{LOG4J\_CONFIG}
+\\Der Fachdatenimport verwendet die externe Bibliothek \textit{Apache Log4J} zum Loggen
+von Informationen. Dazu ist es notwendig eine entsprechende Konfiguration beim
+Start anzugeben. \textit{LOG4J\_CONFIG} verweist in diesem Fall auf eine externe
+Datei zur Konfiguration von Log4J. Im Standardfall wird die Datei
+\textit{conf/log4j.properties} verwendet, welche eine sinnvolle Standardkonfiguration
+enthält. Sollten Sie diese Konfiguration verwenden, wird beim Import eine
+Log-Datei namens \textit{import.log} erstellt, die maximal 100 MB groß werden
+kann. Sollte die Log-Datei größer als 100 MB anwachsen, wird die aktuelle Datei
+nach \textit{import.log.1} umbenannt und eine neue Datei \textit{import.log}
+wird begonnen. Maximal werden 10 Log-Dateien gespeichert. Für weitere Details
+zu Log4J siehe Online Dokumentation unter
+\href{http://logging.apache.org/log4j/1.2/}{http://logging.apache.org/log4j/1.2/}
+
+
+\textbf{IMPORTER\_MAINVALUE\_TYPES}
+\\Diese Einstellung erlaubt die Angabe eines Textes, der aus den gültigen Typen
+für Hauptwerte zusammengesetzt ist. \textit{QWTD} ist standardmäßig gesetzt.
+
+\textbf{IMPORTER\_ANNOTATION\_TYPES}
+\\Diese Einstellung verweist auf eine Datei (relativ zum Ort der \textit{run.sh}
+im Dateisystem), die die möglichen Typen von Streckenfavoriten und deren Regeln
+definiert. Siehe hierzu auch Kapitel \ref{annotation-types}.
+
+
+Die im folgenden beschriebenen Einstellungen können jeweils die Werte
+\textit{true} oder \textit{false} annehmen und sind optional anzupassen.
+
+\textbf{IMPORTER\_DRY\_RUN}
+\\Falls \textit{true} gesetzt wird, wird der Import nur simuliert. Es werden
+keine Daten in die Datenbank geschrieben. Dies kann z.B.: zum Ermitteln
+potentieller Dateninkonsistenzen sinnvoll sein.
+
+\textbf{IMPORTER\_SKIP\_GAUGES}
+\\Wenn \textit{true} gesetzt ist werden keine Pegel- und Stammdaten bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_ANNOTATIONS}
+\\Wenn \textit{true} gesetzt ist werden keine Streckenfavoriten bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_WST}
+\\Wenn \textit{true} gesetzt ist werden keine WST Dateien bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_PRFS}
+\\Wenn \textit{true} gesetzt ist werden keine Querprofilspuren bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_HYKS}
+\\Wenn \textit{true} gesetzt ist werden keine HYK Dateien bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_EXTRA\_WST}
+\\Wenn \textit{true} gesetzt ist werden keine zusätzlichen Längsschnitte
+bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_FIXATIONS}
+\\Wenn \textit{true} gesetzt ist werden keine Fixierungen bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_OFFICIAL\_LINES}
+\\Wenn \textit{true} gesetzt ist werden keine offiziellen Linien bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_FLOOD\_WATER}
+\\Wenn \textit{true} gesetzt ist werden keine Hochwassermarken bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_FLOOD\_PROTECTION}
+\\Wenn \textit{true} gesetzt ist werden keine Hochwasserschutzanlagen
+bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_BED\_HEIGHT\_SINGLE}
+\\Wenn \textit{true} gesetzt ist werden keine mittleren Sohlhöhen (Peilungen) bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_BED\_HEIGHT\_EPOCH}
+\\Wenn \textit{true} gesetzt ist werden keine mittleren Sohlhöhen (Epochen)
+bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_SEDIMENT\_DENSITY}
+\\Wenn \textit{true} gesetzt ist werden keine Dateien zur Sedimentdichte
+bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_MORPHOLOGICAL\_WIDTH}
+\\Wenn \textit{true} gesetzt ist wird keine morphologische Breite bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_FLOW\_VELOCITY}
+\\Wenn \textit{true} gesetzt ist werden keine Fließgeschwindigkeiten bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_SEDIMENT\_YIELD}
+\\Wenn \textit{true} gesetzt ist werden keine Sedimentfrachten bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_WATERLEVELS}
+\\Wenn \textit{true} gesetzt ist werden keine Wasserspiegellagen für MINFO bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_WATERLEVEL\_DIFFERENCES}
+\\Wenn \textit{true} gesetzt ist werden keine Wasserspiegellagendifferenzen für
+MINFO bearbeitet.
+
+\textbf{IMPORTER\_SKIP\_SQ\_RELATION}
+\\Wenn \textit{true} gesetzt ist werden keine Daten für die Berechnungsart
+SQ-Beziehung bearbeitet.
+
+
+
+\subsection{Fehler und Warnungen}
+
+\subsubsection{Fehler}
+
+\textbf{error while parsing gew}
+\\Die GEW-Datei ist fehlerhaft oder konnte nicht geöffnet werden.
+
+\textbf{File 'XYZ' is broken!}
+\\Die Datei XYZ ist inkonsistent und führt zu Fehlern.
+
+\textbf{Error while parsing file for morph. width.}
+\\Beim Lesen der morphologischen Breite trat ein Fehler auf.
+
+\textbf{Error while storing flow velocity model.}
+\\Beim Schreiben eines Fließgeschwindigkeitsmodells trat ein Fehler auf.
+
+\textbf{Error while storing flow velocity measurement.}
+\\Beim Schreiben einer Fließgeschwindigkeitsmessung trat ein Fehler auf.
+
+\textbf{Error while storing sediment yield.}
+\\Beim Schreiben einer Sedimentablagerung trat ein Fehler auf.
+
+\textbf{Error while storing waterlevel diff.}
+\\Beim Schreiben einer Wasserspiegeldifferenz trat ein Fehler auf.
+
+\textbf{Error while storing sq relation.}
+\\Beim Schreiben einer S(Q) Beziehung trat ein Fehler auf.
+
+\textbf{Error reading PRF file.}
+\\Beim Lesen einer PRF-Datei trat ein Fehler auf.
+
+\textbf{Error closing PRF file.}
+\\Beim Schließen einer PRF-Datei trat ein Fehler auf.
+
+\textbf{HYK 1: not enough elements in line \#}
+\\Eine Zeile in einer HYK-Datei hat nicht genügend Elemente.
+
+\textbf{HYK 2: not enough elements in line \#}
+\\Eine Zeile in einer HYK-Datei hat nicht genügend Elemente.
+
+\textbf{HYK 5: not enough elements in line \#}
+\\Eine Zeile in einer HYK-Datei hat nicht genügend Elemente.
+
+\textbf{HYK 6: not enough elements in line \#}
+\\Eine Zeile in einer HYK-Datei hat nicht genügend Elemente.
+
+\textbf{HYK: parsing num zones, bottom or top height failed in line \#}
+\\Die Anzahl der Zonen oder Daten über die Zonen sind nicht korrekt.
+
+\textbf{HYK: HYK: number of flow zones mismatches in line \#}
+\\Die Anzahl der Zonen oder Daten über die Zonen sind nicht korrekt.
+
+\textbf{HYK: cannot parse number in line \#}
+\\Eine Zahl wurde erwartet.
+
+\textbf{HYK: Error reading file.}
+\\Beim Lesen einer HYK-Datei trat ein Fehler auf.
+
+\textbf{HYK: Error closing file.}
+\\Beim Schließen einer HYK-Datei trat ein Fehler auf.
+
+\subsubsection{Warnungen}
+\textbf{annotation type file 'XYZ' is not readable.}
+\\Die Datein XYZ kann nicht gelesen werden.
+
+\textbf{cannot parse annotation types file.}
+\\Während der Verarbeitung der Annotationsdatei ist Fehler aufgetreten.
+
+\textbf{Cannot read directory.}
+\\Verzeichnis konnte nicht gelesen werden.
+
+\textbf{no official lines wst file found}
+\\Keine Datei mit amtlichen Linien gefunden.
+
+\textbf{cannot read fixations wst file directory}
+\\Das Verzeichnis mit den Fixierungen kann nicht gelesen werden.
+
+\textbf{cannot read extra longitudinal wst file directory}
+\\Das Verzeichnis mit den zusätzlichen Längsschnitten kann nicht gelesen werden.
+
+\textbf{cannot read gauges from 'XYZ'}
+\\Die Pegelgültigkeiten können nicht gelesen werden.
+
+\textbf{HYK file 'XYZ' seems to be a duplicate.}
+\\Die HYK-Datei wurde unter anderem Namen aber gleichen Inhalts bereits
+gefunden.
+
+\textbf{PRF file 'XYZ' seems to be a duplicate.}
+\\Die PRF-Datei wurde unter anderem Namen aber mit gleichem Inhalt bereits
+gefunden.
+
+\textbf{Skip invalid SedimentYield: time interval or unit null!}
+\\Eine Sedimentablagerung ist ungültig und wurde ausgelassen.
+
+\textbf{skip flow velocity model: No discharge zone specified.}
+\\Da kein Abflussbereich angegeben wurde, wurde das Fließgeschwindigkeitsmodell ausgelassen.
+
+\textbf{skip invalid waterlevel - no unit set!}
+\\Ein einheitenloser Wasserstand wurde ausgelassen.
+
+\textbf{Cannot parse time range.}
+\\Das Zeitformat wurde nicht erkannt.
+
+\textbf{skip invalid data line \#}
+\\Ungültige Datenzeile wurde ausgelassen.
+
+\textbf{Error while parsing sq relation row \#}
+\\Eine Zeile in der S(Q)-Beziehung ist ungültig.
+
+\textbf{GLT: no gauge found in line \#}
+\\In der GLT-Datei wurde ein Pegel erwartet, aber nicht gefunden.
+
+\textbf{GLT: line \# has not enough columns.}
+\\Eine Zeile in der Pegelgültigkeitsdatei hat nicht genug Spalten.
+
+\textbf{Error while parsing flow velocity values.}
+\\Invalide Datenzeile in einer Datei mit einer Fliessgeschwindigkeitsmessung.
+
+\textbf{skip invalid data line: \#}
+\\Invalide Datenzeile in einer Datei mit einer Fliessgeschwindigkeitsmessung.
+
+\textbf{skip invalid waterlevel line: \#}
+\\Invalide Datenzeile in einer Datei mit Wasserstandsdifferenzen.
+
+\textbf{Error while parsing value: \#}
+\\Invalide Datenzeile in einer Datei mit Wasserstandsdifferenzen.
+
+\textbf{Error while parsing station: \#}
+\\Invalide Datenzeile in einer Datei mit Wasserstandsdifferenzen.
+
+\textbf{skip invalid MainValue part: \#}
+\\Invalide Datenzeile in einer Datei Fließgeschwindigkeitsmodellen.
+
+\textbf{skip invalid gauge part: \#}
+\\Invalide Datenzeile in einer Datei Fließgeschwindigkeitsmodellen.
+
+\textbf{Error while parsing Q value: $<Q>$}
+\\Invalide Datenzeile in einer Datei Fließgeschwindigkeitsmodellen.
+
+\textbf{skip invalid data line: \#}
+\\Invalide Datenzeile in einer Datei Fließgeschwindigkeitsmodellen.
+
+\textbf{Error while parsing flow velocity values.}
+\\Invalide Datenzeile in einer Datei Fließgeschwindigkeitsmodellen.
+
+\textbf{Error while parsing number from data row: \#}
+\\In der eingelesenen Zeile konnte keine Zahl gefunden werden.
+
+\textbf{Unknown meta line: \#}
+\\Invalide Datenzeile in einer Datei mit Sedimentdichten.
+
+\textbf{Error while parsing numbers in: \#}
+\\Invalide Datenzeile in einer Datei mit Sedimentdichten.
+
+\textbf{skip invalid data line: \#}
+\\Invalide Datenzeile in einer Datei mit Sedimentdichten.
+
+\textbf{Error while parsing numbers in \#}
+\\Invalide Datenzeile in einer Datei mit Sedimentdichten.
+
+\textbf{STA file is empty}
+\\Stammdatendatei ist leer oder hat zu wenige Zeilen.
+
+\textbf{STA file has not enough lines}
+\\Stammdatendatei ist leer oder hat zu wenige Zeilen.
+
+\textbf{STA file is too short}
+\\Stammdatendatei ist leer oder hat zu wenige Zeilen.
+
+\textbf{First line in STA file is too short.}
+\\Die erste Zeile der Stammdaten ist zu kurz.
+
+\textbf{STA: second line is too short}
+\\Die zweite Zeile ist zu kurz.
+
+\textbf{STA: parsing of the datum of the gauge failed}
+\\Das Datum in der Stammdatendatei konnte nicht gelesen werden.
+
+\textbf{STA: 'XYZ' is not a valid long number.}
+\\Die Pegelnummer ist invalide.
+
+\textbf{STA: Not enough columns for aeo and datum}
+\\AEO und Pegelnullpunkt können nicht ermittelt werden.
+
+\textbf{STA: cannot parse aeo or datum.}
+\\AEO oder Pegelnullpunkt sind invalide.
+
+\textbf{STA: value not parseable in line \#}
+\\Wert ist nicht als Zahl zu interpretieren.
+
+\textbf{PRF: cannot open file $<FILE>$}
+\\Die PRF kann nicht geöffnet werden.
+
+\textbf{PRF: file is empty}\\
+\textbf{PRF: First line does not look like a PRF data pattern.}\\
+\textbf{PRF: premature EOF. Expected integer in line 2}\\
+\textbf{PRF: Expected $<num>$ in line 2}\\
+\textbf{PRF: invalid integer in line 2}\\
+\textbf{PRF: premature EOF. Expected pattern for km extraction}\\
+\textbf{PRF: line 4 does not look like a PRF km extraction pattern.}\\
+\textbf{PRF: premature EOF. Expected skip row count.}\\
+\textbf{PRF: line 5 is not an positive integer.}\\
+\textbf{PRF: cannot extract km in line \#}
+\\Das PRF-Format ist komplex. Bei oben genannten Fehlern sollten weitere
+Information zur genaueren Analyse herangezogen werden.
+
+\textbf{cannot access WST file $FILE$}
+\\Die WST-Datei konnte nicht gefunden werden.
+
+\textbf{Found an invalid row in the AT file.}
+\\Eine Zeile in einer AT-Datei ist nicht korrekt.
+
+\textbf{AT: invalid number $XYZ$}
+\\Eine Zahl wurde erwartet aber nicht gefunden.
+
+\textbf{Try to add Q range without waterlevel!}
+\\Q-Bereich ohne Wasserstand gefunden.
+
+\textbf{Error while parsing Q range: \#}
+\\Invalider Q-Bereich
+
+\textbf{skip invalid waterlevel line: \#}
+\\Ungültige Wasserstandslinie
+
+\textbf{Error while parsing number values: \#}
+\\Ungültige Zahlenwerte.
+
+\textbf{ANN: not enough columns in line \#}
+\\Nicht genug Zeichenspalten in KM-Datei
+
+\textbf{ANN: invalid number in line \#}
+\\Ungültige Zahl.
+
+\textbf{ANN: cannot parse 'Unterkante' in line \#}
+\\Die Unterkante in einer KM-Datei konnte nicht gelesen werden.
+
+\textbf{ANN: cannot parse 'Unterkante' or 'Oberkante' in line \#}
+\\Unter- oder Oberkannte liegen in einem falschen Format vor.
+
+\textbf{ANN: duplicated annotation 'XYZ' in line \#}
+\\Ein Duplikat eines Streckenfavoriten wurde gefunden.
+
+\textbf{ANN: 'XYZ' is not a directory.}
+\\Unterverzeichnis konnte nicht geöffnet werden.
+
+\textbf{ANN: cannot list directory 'XYZ'}
+\\Unterverzeichnis konnte nicht durchsucht werden.
+
+\textbf{BHP: Meta line did not match any known type: \#}
+\\Unbekannter Typ.
+
+\textbf{BHP: Error while parsing timeinterval!}
+\\Ungültiges Zeitinterval.
+
+\textbf{BHP: Error while parsing year!}
+\\Ungültige Jahresangabe.
+
+\textbf{BHP: Error while parsing sounding width!}
+\\Unbekannte Peilungsbreite.
+
+\textbf{BHP: Error while parsing range!}
+\\Bereichsangabe fehlerhaft.
+
+\textbf{MWP: Unknown meta line: \#}
+\\Meta-Informationen ungültig.
+
+\textbf{MWP: skip invalid data line: \#}
+\\Ungültige Datenzeile wurde übersprungen.
+
+\textbf{MWP: Error while parsing numbers in \#}
+\\Falsche Zahlenformat.
+
+\textbf{ANNCLASS: rule has no name}
+\\Klassifizierungsregel für Streckenfavoriten hat keinen Namen.
+
+\textbf{ANNCLASS: pattern has no 'pattern' attribute.}
+\\Klassifizierungsmuster für Streckenfavoriten hat kein Muster.
+
+\textbf{ANNCLASS: pattern has unknown type 'XYZ'}
+\\Klassifizierungsmuster für Streckenfavoriten konnte keinem Typ zugeordnet werden.
+
+\textbf{ANNCLASS: pattern 'XYZ' is invalid.}
+\\Klassifizierungsmuster für Streckenfavoriten ist ungültig.
+
+\textbf{BSP: Error while parsing data row.}
+\\Ungültige Datenzeile.
+
+\textbf{SYP: Unknown meta line: \#}
+\\Ungültige Metadatenzeile.
+
+\textbf{SYP: skip invalid data line \#}
+\\Ungültige Datenzeile wurde übersprungen.
+
+\textbf{SYP: Error while parsing numbers in \#}
+\\Ungültige Zahlenformatierung.
+
+\textbf{SYP: Unknown time interval string 'XYZ'}
+\\Falsches Datumformat.
+
+\textbf{SYP: Error while parsing years 'XYZ'}
+\\Falsches Jahreszahlformat.
+
+\textbf{SYP: Error while parsing ranges of 'XYZ'}
+\\Bereichsangaben fehlerhaft.
+
+\textbf{SYP: Unknown grain fraction 'XYZ'}
+\\Unbekannte Kornfraktion.
+
+\textbf{WST: invalid number.}
+\\Ungültige Zahl.
+
+\textbf{WST: km $km$ ($<Zeile>$) found more than once. $->$ ignored.}
+\\Ein Kilometer ist doppelt in einer WST-Datei enthalten.
+
+\textbf{HYK: zone coordinates swapped in line \#}
+\\Fließzonenkordinaten wurden in umgekehrter Reihenfolge angeben.
+
+\textbf{BHS: Skip invalid file 'XYZ'}
+\\Die Inhalte der Datei sind ungültig.
+
+\textbf{ISQ: Unable to store sq relation value.}
+\\S(Q) Beziehung konnte nicht gespeichert werden.
+
+\textbf{ISQ: Cannot determine sq relation without time interval.}
+\\Einer S(Q)-Beziehung ist keine zeitliche Gültigkeit zugeordnet.
+
+\textbf{IWD: skip invalid waterlevel difference - no unit set!}
+\\Wasserstandsdifferenz hat keine Einheit.
+
+\textbf{BHE: Skip file - invalid current elevation model.}
+\\Höhenmodell ungültig.
+
+\textbf{BHE: Skip file - invalid time range.}
+\\Zeitbereich ungültig.
+
+\textbf{BHE: Skip file - invalid km range.}
+\\Kilometerbereich ungültig.
+
+
+\subsection{Hinweise zum Betrieb}
+Aufgrund des hohen Speicherverbrauchs des Importers wird empfohlen, der JVM
+mindestens 8 GiB Hauptspeicher zuzuordnen. Dies kann beim Starten des Java
+Prozesses mittels folgendem Parameter '-Xmx8192m' getan werden. Das
+Shellskript zum Starten des Importers setzt diesen Wert standardmäßig.
+Besonders speicherintensiv ist der Import der HYKs und der PRFs.
+Hier ist es unter Umständen empfehlenswert, diese in zwei oder drei
+Schritten zu importieren. Zuerst die sonstigen hydrologischen Daten importieren;
+anschließend einen Import-Vorgang ausschließlich für HYKs starten; anschließend
+einen Import-Vorgang für PRFs starten. Siehe Kapitel \ref{configuration} für
+weitere Informationen zum Aktivieren/Deaktivieren einzelner Dateitypen beim
+Import.
+
+
+\subsection{Starten des Fachdaten Importers}
+\label{start-hydr}
+Der Fachdaten Importer wird mit Hilfe eines Shellskripts von einer Konsole
+gestartet. Dazu führen folgenden Befehl aus:\\
+
+\begin{lstlisting}
+    contrib/run_hydr_morph.sh
+\end{lstlisting}
+
+Nachdem der Prompt der Konsole zurückkehrt, ist der Import abgeschlossen oder es
+ist ein Fehler aufgetreten. Weitere Informationen entnehmen Sie der Log-Datei.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/importer-manual.tex	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,204 @@
+\documentclass[12pt]{scrartcl}
+
+%----------------------------------------------
+% Load packages
+
+\usepackage{a4}
+\usepackage{times}
+\usepackage[latin1]{inputenc}
+\usepackage{fancyhdr}
+%\usepackage{german}
+%\usepackage[marvosym]{eurofont}
+%\usepackage[all, light]{draftcopy}
+%\usepackage{supertabular}
+%\usepackage{colortbl}
+%\usepackage{epsf}
+\usepackage{graphicx}
+\usepackage{lastpage}
+%\usepackage{proposal}
+\usepackage{listings}
+\usepackage[hyperindex=true, bookmarks=true, breaklinks=true,
+colorlinks=true, linkcolor=red,bookmarksopen]{hyperref}
+
+%----------------------------------------------
+% Document DATE and VERSION
+% set these values when releasing a new version
+
+\newcommand{\documentdate}{30. August 2012}
+\newcommand{\documentversion}{1.0}
+\newcommand{\documentrevision}{rev5303}
+\newcommand{\documentID}{importer-manual.tex}
+%----------------------------------------------
+
+%----------------------------------------------
+% Document TITLE
+\newcommand{\documenttitle}{FLYS: Datenimport von Fach- und Geodaten}
+
+\newcommand{\todo}{\textcolor{red}{ TODO }}
+
+
+%----------------------------------------------
+% Some parameters for layouting
+
+\paperwidth=21cm
+\hoffset=-0.54cm
+\textwidth=16cm
+
+\paperheight=29.7cm
+\voffset=-1.5cm
+\topmargin=0cm
+\headheight=1cm
+\textheight=24cm
+
+\setcounter{secnumdepth}{4}
+\setcounter{tocdepth}{4}
+
+%----------------------------------------------
+
+\begin{document}
+
+\lstset{ %
+language=sh,
+basicstyle=\ttfamily,       % the size of the fonts that are used for the code
+numbers=left,                   % where to put the line-numbers
+numberstyle=\footnotesize,      % the size of the fonts that are used for the line-numbers
+numbersep=5pt,                  % how far the line-numbers are from the code
+% backgroundcolor=\color{white},  % choose the background color. You must add \usepackage{color}
+showspaces=false,               % show spaces adding particular underscores
+showstringspaces=false,         % underline spaces within strings
+showtabs=false,                 % show tabs within strings adding particular underscores
+frame=single,                   % adds a frame around the code
+tabsize=2,                      % sets default tabsize to 2 spaces
+captionpos=b,                   % sets the caption-position to bottom
+breaklines=true,                % sets automatic line breaking
+breakatwhitespace=false,        % sets if automatic breaks should only happen at whitespace
+title=\lstname,                 % show the filename of files included with \lstinputlisting; also try caption instead of title
+escapeinside={\%*}{*)}          % if you want to add a comment within your code
+% morekeywords={*,...}            % if you want to add more keywords to the set
+}
+
+%-----------------------------------
+% HEADER/FOOTER DEFINITION
+
+% for some pages latex switches back to pagestyle plain :-(
+\fancypagestyle{plain}{%
+	\fancyhf{} % clear all header and footer fields
+	\fancyhead[LO,RE]{\footnotesize \documenttitle\\ \leftmark}
+	\fancyfoot[RO,LE]{\footnotesize Intevation GmbH} % Author
+	\fancyfoot[CO,CE]{\footnotesize \thepage/\pageref{LastPage}}
+	\fancyfoot[LO,RE]{\footnotesize \documentdate
+	\\\documentID}
+	\renewcommand{\footrulewidth}{0.4pt}
+}
+
+% and now define pagestyle fancy
+\fancyhead{} % clear all fields
+\fancyhead[LO]{\footnotesize \documenttitle\\ \leftmark}
+
+\fancyfoot{}% clear all fields
+\fancyfoot[RO]{\footnotesize Intevation GmbH} % Author
+\fancyfoot[CO]{\footnotesize \thepage/\pageref{LastPage}}
+\fancyfoot[LO]{\footnotesize \documentdate
+\\\documentID}
+
+\renewcommand{\footrulewidth}{0.4pt}
+
+%
+% END Header/Footer Definition
+%-----------------------------------
+
+%----------------------------------------------
+% MACRO DEFINITION
+%
+%   \Fig{figure}{lof text}{caption} :
+%			places 'figure' and
+%                       writes 'caption' at the bottom with leading
+%                       'Abbildung figno:'. 'lof text' is added to the list of
+%                       figures.
+%                       Example:
+%                       \Fig{\epsfxsize30mm \epsffile{x.eps}}{the x}{the x}
+%
+%   \FigNoEntry{}{} :
+%			same as above, no entry in figures list
+%
+%   \FigCaption{} :
+%			line with figure caption, setting figure
+%                       counter and figures list
+%
+%   \Tab{table}{lot text}{caption} :
+%			places 'table' and writes caption on top of the table
+%			with leading 'Tabelle tabno:'. 'lot text' is added to
+%			the list of tables.
+%****************************************************************************
+%       Figure makro for graphics continously enumerated.
+%
+
+\newcounter{FigCnt}
+\newcounter{TabCnt}
+
+\newcommand{\Fig}[3]%
+{
+        \refstepcounter{FigCnt}
+        \addcontentsline{lof}{figure}%
+                {\protect\numberline{\arabic{FigCnt}}{#2}}
+        \mbox{#1}
+
+\nopagebreak
+        {Abbildung \arabic{FigCnt}: #3}
+
+}
+
+\newcommand{\FigNoEntry}[2]%
+{
+        \refstepcounter{FigCnt}
+        \mbox{#1}
+
+\nopagebreak
+        {Abbildung \arabic{FigCnt}: #2}
+
+}
+
+\newcommand{\FigCaption}[1]%
+{
+        \refstepcounter{FigCnt}
+        \addcontentsline{lof}{figure}%
+                {\protect\numberline{\arabic{FigCnt}}{#1}}
+
+        %{Figure \thesection.\arabic{FigCnt}: #1}
+}
+
+\newcommand{\Tab}[3]%
+{
+        \refstepcounter{TabCnt}
+        \addcontentsline{lot}{figure}%
+                {\protect\numberline{\arabic{TabCnt}}{#2}}
+        {Tabelle \arabic{TabCnt}: #3}
+\nopagebreak
+        #1
+
+}
+
+\hyphenation{Intevation}
+% end macro definition
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcounter{schritt}
+\renewcommand{\theschritt}{\Roman{schritt}}
+%\makeatletter\renewcommand{\p@schritt}{Abschnitt~\thesubsubsection~}\makeatother
+
+%-----------------------------------
+% DOCUMENT SETTINGS
+\pagestyle{fancy}
+\setlength{\parindent}{0cm}
+\setlength{\parskip}{5pt plus 2pt minus 1pt}
+
+% Start actual content here
+\include{title}
+\newpage
+\tableofcontents
+\include{overview}
+\include{importer-hydr-morph}
+\include{importer-geodaesie}
+
+\end{document}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/overview.tex	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,104 @@
+\section{Übersicht}
+
+Diese Dokumentation beschreibt die von Intevation entwickelten Werkzeuge zum
+Importieren der hydrologischen, morphologischen und geodätischen Daten der BfG.
+Die im folgenden\\ beschriebenen Werkzeuge zum Importieren der fachlichen und
+geodätischen Daten sind speziell auf das Verzeichnissystem der BfG ausgerichtet.
+Dabei wird angenommen, dass sich das Verzeichnis eines Gewässers auf oberster
+Ebene in drei Unterverzeichnisse aufgliedert:
+
+\begin{itemize}
+    \item Geodaesie
+    \item Hydrologie
+    \item Morphologie
+\end{itemize}
+
+Desweiteren beziehen sich die Befehle, die auf der Kommandozeile abgesetzt
+werden, auf ein SuSE-Linux-Enterprise-Server Version 11. Bitte beachten Sie
+auch, dass einige der Befehle \textit{root}-Rechte benötigen.
+
+\subsection{Vorbereitungen}
+
+\subsubsection{Entpacken des Datenimporters}
+
+Damit die Software performant und korrekt ausgeführt werden kann, ist es
+erforderlich, dass sie auf dem selben System installiert und ausgeführt wird,
+wie auch die Datenbank installiert ist. Sollten Sie das Paket nicht auf dem
+Zielsystem selbst heruntergeladen haben, sind ggf. weitere Werkzeuge notwendig.
+Im Fall, dass das Sie von einem Windows System auf das Zielsystem zugreifen
+wollen, können Sie beispielsweise folgende Werkzeuge verwenden:
+
+\begin{itemize}
+\item WinSCP \\
+WinSCP ist ein Open Source Werkzeug zum Transferieren von Dateien zwischen zwei
+Systemen. Um das heruntergeladene Paket auf das Zielsystem zu transferieren,
+können Sie WinSCP benutzen. Für weitere Informationen und den Gebrauch von
+WinSCP lesen Sie bitte unter folgender Adresse nach:
+\href{http://winscp.net/}{http://winscp.net/}.
+
+\item Putty \\
+Putty ist ein Open Source Werkzeug, mit dem Sie sich von einem Windows System
+per SSH auf das Zielsystem verbinden können. Anschließend können Sie über die
+Kommandozeile auf dem Zielsystem die Befehle, die in diesem Dokument beschrieben
+sind, ausführen. Für weitere Informationen zu Putty und dessen Gebrauch lesen
+Sie bitte unter folgender Adresse nach: \href{http://www.putty.org/}
+{http://www.putty.org/}.
+\end{itemize}
+
+Bitte beachten Sie, dass diese Werkzeuge nicht zur Installtion und zum Betrieb
+der Software selbst notwendig sind!
+
+
+\subsubsection{Vorbereiten der Datenbank}
+
+Nachdem Sie das Paket nun in das Heimatverzeichnis des Nutzers auf das
+Zielsystem kopiert haben, entpacken Sie es mit folgenden Befehlen:
+
+\begin{lstlisting}
+    cd ~
+    tar xvfz flys-importer.tar.gz
+    cd flys-importer
+\end{lstlisting}
+
+Bevor die Importer verwendet werden können, ist es notwendig, dass eine leere
+Oracle Datenbank vorhanden ist. Anschließend müssen folgende SQL Skripte in
+diese Datenbank eingespielt werden:
+
+\begin{enumerate}
+\item oracle.sql \\
+In diesem SQL Skript befindet sich das Schema zum Speichern der hydrologischen
+Daten.
+
+\item oracle-minfo.sql \\
+In diesem SQL Skript befindet sich das Schema zum Speichern der morphologischen
+Daten.
+
+\item oracle-spatial.sql \\
+In diesem SQL Skript befindet sich das Schema zum Speichern der geodätischen
+Daten.
+
+\item oracle-spatial\_idx.sql \\
+Mittels diesem SQL Skript werden die Indizes zum geodätischen Datenbankschema\\
+hinzugefügt.
+
+\item import-dems.sql \\
+In diesem Skript sind Befehle zum Einfügen der digitalen Geländemodelle
+enthalten. Die Dateipfade in diesem Skript sind so anzupassen, dass sie auf die
+entsprechenden Geländemodelle im Dateisystem verweisen. Es ist notwendig die
+Pfade absolut anzugeben.
+
+\end{enumerate}
+
+Zum Einspielen dieser Schemata setzen Sie folgende Befehle auf der Kommandozeile
+ab. Beachten Sie, dass $sqlplus$ im Pfad liegen muss, und der Linux-Nutzer
+dies Kommando ausführen können muss. Außerdem sind $benutzername$ und $passwort$
+entsprechend Ihres Datenbank-Zugangs anzupassen.
+
+\begin{lstlisting}
+    sqlplus benutzername/passwort @schema/oracle.sql
+    sqlplus benutzername/passwort @schema/oracle-minfo.sql
+    sqlplus benutzername/passwort @schema/oracle-spatial.sql
+    sqlplus benutzername/passwort @schema/oracle-spatial_idx.sql
+    sqlplus benutzername/passwort @schema/import-dems.sql
+\end{lstlisting}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/documentation/de/title.tex	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,52 @@
+%-----------------------------------
+% TITLE PAGE
+
+\begin{figure}[ht]
+  \begin{minipage}[b]{0.5\linewidth}
+    \centering
+     \includegraphics[scale=0.75]{figures/bfg_logo} \\
+     {\tt http://www.bafg.de}\\[4.0cm]
+  \end{minipage}
+  \begin{minipage}[b]{0.5\linewidth}
+    \centering
+    \includegraphics[width=0.75\textwidth]{figures/intevation-logo}
+     {\tt http://intevation.de/geospatial}\\[2.0cm]
+  \end{minipage}
+\end{figure}
+
+ \vspace{4cm}
+ 
+ {
+ 	\sffamily\large
+ 	Dokumentation Datenimport FLYS, BfG
+ 
+ 	\vspace{1cm}
+ 	{
+ 		\bfseries\huge
+ 		Installation, Konfiguration, Betrieb
+ 	}
+ 
+ 	\vspace{1cm}
+ 	Version \documentversion
+
+    Datum: \documentdate
+ 
+ 	Revision: \documentrevision
+ }
+ 
+ \vspace{4cm}
+ 
+ \thispagestyle{empty}
+ 
+ \vfill
+ 
+ \begin{flushleft}
+ {\bf Authors}:\\
+ Ingo Weinzierl$<$ingo.weinzierl@intevation.de$>$\\
+ Sascha Teichmann $<$sascha.teichmann@intevation.de$>$\\
+ {\bf Intevation GmbH},\\
+ Neuer Graben 17, 49074 Osnabrück, Germany\\
+ Tel: ++49 541 33 50 83 - 0 \\
+ \url{http://www.intevation.net/geospatial}
+ 
+ \end{flushleft}
--- a/flys-backend/doc/schema/import-dems.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/import-dems.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -1,165 +1,24 @@
--- SAAR
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    0,
-    7.9,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0000-0079_long.txt'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    8.0,
-    20.4,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0080-0204_long.txt'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    20.5,
-    31.4,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0205-0314_long.txt'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    31.5,
-    54.1,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0315-0541_long.txt'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    54.2,
-    65.5,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0542-0655_long.txt'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    65.6,
-    82.8,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0656-0828_long.txt'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Saar'),
-    82.9,
-    93.1,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0829-0931_erweitert.txt'
-);
-
-
--- ELBE
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Elbe'),
-    0.0,
-    101.1,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_00000_10110.grd'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Elbe'),
-    99.2,
-    203.0,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_09920_20300.grd'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Elbe'),
-    202.0,
-    299.8,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_20200_29980.grd'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Elbe'),
-    298.1,
-    401.0,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_29810_40100.grd'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Elbe'),
-    400.0,
-    500.9,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_40000_50090.grd'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Elbe'),
-    500.1,
-    583.3,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_50010_58330.grd'
-);
-
-
--- MOSEL
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    0.0,
-    5.8,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0000-0580.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    5.8,
-    15.3,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0058-0153.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    15.3,
-    41.6,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0153-0416.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    41.4,
-    101.2,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0414-1012O.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    41.4,
-    101.21,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0414-1012W.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    101.2,
-    148.8,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1012-1488.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    148.8,
-    166.6,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1488-1666.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    166.6,
-    196.0,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1666-1960.xyz'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    196.0,
-    204.4,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1960-2044.XYZ'
-);
-
-INSERT INTO dem (river_id, lower, upper, path) VALUES (
-    (SELECT id FROM rivers WHERE name = 'Mosel'),
-    204.4,
-    218.4,
-    '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/2044-2184.XYZ'
-);
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Elbe'), 'GRD_00000_01010', 0.0, 101.0, 2003, 2007, 'GK-3', 'DHHN92', 'ESRI-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_00000_10110.grd');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Elbe'), 'GRD_00992_02030', 99.0, 203.0, 2003, 2007, 'GK-3', 'DHHN92', 'ESRI-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_09920_20300.grd');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Elbe'), 'GRD_02020_02998', 202.0, 300.0, 2003, 2007, 'GK-3', 'DHHN92', 'ESRI-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_20200_29980.grd');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Elbe'), 'GRD_02981_04010', 298.0, 401.0, 2003, 2007, 'GK-3', 'DHHN92', 'ESRI-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_29810_40100.grd');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Elbe'), 'GRD_04000_05009', 400.0, 501.0, 2003, 2007, 'GK-3', 'DHHN92', 'ESRI-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_40000_50090.grd');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Elbe'), 'GRD_05001_05830', 500.0, 583.0, 2003, 2007, 'GK-3', 'DHHN92', 'ESRI-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Elbe/Geodaesie/Hoehenmodelle/m_50010_58330.grd');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_00000_00058', 0.0, 6.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0000-0580.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_00058_00153', 6.0, 15.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0058-0153.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_00153_00416', 15.0, 42.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0153-0416.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_00414_01012_O', 41.0, 101.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', 'muss überarbeitet werden', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0414-1012O.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_00414_01012_W', 41.0, 101.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', 'muss überarbeitet werden', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/0414-1012W.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_01012_01488', 101.0, 145.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1012-1488.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_01488_01666', 145.0, 167.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1488-1666.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_01666_01960', 167.0, 196.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1666-1960.xyz');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_01960_02044', 196.0, 204.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/1960-2044.XYZ');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_02044_02184', 204.0, 218.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/2044-2184.XYZ');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Mosel'), 'GRD_02184_02420', 218.0, 242.0, null, null, 'GK-2', 'DHHN85', 'ASCII-Grid', false, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Mosel/Geodaesie/Hoehenmodelle/DGMW-ASCII/525480MO.XYZ');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00000_00079', 0.0, 8.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0000-0079_long.txt');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00080_00204', 8.0, 20.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0080-0204_long.txt');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00205_00314', 20.0, 31.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0205-0314_long.txt');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00315_00541', 31.0, 54.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0315-0541_long.txt');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00542_00655', 54.0, 65.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0542-0655_long.txt');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00656_00828', 65.0, 83.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0656-0828_long.txt');
+INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,projection, elevation_state, format, border_break, resolution, description, path) VALUES ((SELECT id from rivers WHERE name = 'Saar'), 'GRD_00829_00931', 83.0, 93.0, 1999, 2002, 'GK-2', '', 'ASCII-Grid', true, '2', '', '/vol1/projects/Geospatial/flys-3.0/testdaten/Gewaesser/Saar/Geodaesie/Hoehenmodelle/km0829-0931_erweitert.txt');
--- a/flys-backend/doc/schema/oracle-minfo.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/oracle-minfo.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -84,9 +84,9 @@
     station                 NUMBER(38,2) NOT NULL,
     height                  NUMBER(38,2),
     uncertainty             NUMBER(38,2),
-    data_gap                NUMBER(38,2) NOT NULL,
-    sounding_width          NUMBER(38,2) NOT NULL,
-    width                   NUMBER(38,2) NOT NULL,
+    data_gap                NUMBER(38,2),
+    sounding_width          NUMBER(38,2),
+    width                   NUMBER(38,2),
     PRIMARY KEY(id),
     CONSTRAINT fk_bed_single_values_parent FOREIGN KEY (bed_height_single_id) REFERENCES bed_height_single(id)
 );
@@ -245,7 +245,7 @@
     name    VARCHAR(64)    NOT NULL,
     lower   NUMBER(38,3),
     upper   NUMBER(38,3),
-    unit_id NUMBER (38,0),
+    unit_id NUMBER(38,0),
     PRIMARY KEY (id),
     CONSTRAINT fk_gf_unit_id FOREIGN KEY (unit_id) REFERENCES units(id)
 );
@@ -306,7 +306,7 @@
 
 CREATE SEQUENCE WATERLEVEL_VALUES_ID_SEQ;
 
-CREATE TABLE waterlevel_values(
+CREATE TABLE waterlevel_values (
     id                      NUMBER(38,0) NOT NULL,
     waterlevel_q_range_id   NUMBER(38,0) NOT NULL,
     station                 NUMBER(38,3) NOT NULL,
@@ -374,7 +374,7 @@
     fraction       VARCHAR(32)  NOT NULL,
     function       VARCHAR(32)  NOT NULL,
     km             NUMBER(38,3) NOT NULL,
-    a              NUMBER       NOT NULL,
+    a              NUMBER(38, 3) NOT NULL,
     b              NUMBER(38,3) NOT NULL,
     PRIMARY KEY (id),
     CONSTRAINT fk_sqr_id FOREIGN KEY (sq_relation_id) REFERENCES sq_relation(id)
--- a/flys-backend/doc/schema/oracle-spatial.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/oracle-spatial.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -6,6 +6,7 @@
     river_id NUMBER(38),
     kind     NUMBER(38) DEFAULT 0 NOT NULL,
     name     VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('river_axes', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -25,6 +26,7 @@
     river_id NUMBER(38),
     km NUMBER(6,3),
     name     VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('river_axes_km', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -45,6 +47,7 @@
     km       NUMBER(38,12) NOT NULL,
     z        NUMBER(38,12) DEFAULT 0 NOT NULL,
     name     VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('cross_section_tracks', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -66,6 +69,7 @@
     kind     VARCHAR2(16) NOT NULL,
     z        NUMBER(38,12) DEFAULT 0,
     name     VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('lines', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -89,6 +93,7 @@
     GEOM MDSYS.SDO_GEOMETRY,
     river_id NUMBER(38),
     name VARCHAR2(255),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('buildings', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -111,6 +116,7 @@
     km NUMBER(38,11) NOT NULL,
     HPGP VARCHAR2(255),
     name VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('fixpoints', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -129,6 +135,7 @@
     GEOM MDSYS.SDO_GEOMETRY,
     river_id NUMBER(38),
     name     VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('floodplain', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -148,10 +155,18 @@
     ID NUMBER PRIMARY KEY NOT NULL,
     river_id NUMBER(38),
     -- XXX Should we use the ranges table instead?
-    lower    NUMBER(19,5),
-    upper    NUMBER(19,5),
-    path     VARCHAR(256),
-    UNIQUE (river_id, lower, upper)
+    name            VARCHAR(64),
+    lower           NUMBER(19,5),
+    upper           NUMBER(19,5),
+    year_from       VARCHAR(32) NOT NULL,
+    year_to         VARCHAR(32) NOT NULL,
+    projection      VARCHAR(32) NOT NULL,
+    elevation_state VARCHAR(32),
+    format          VARCHAR(32),
+    border_break    BOOLEAN NOT NULL DEFAULT FALSE,
+    resolution      VARCHAR(16),
+    description     VARCHAR(256),
+    path            VARCHAR(256)
 );
 CREATE OR REPLACE TRIGGER dem_trigger BEFORE INSERT ON dem FOR each ROW
     BEGIN
@@ -168,6 +183,7 @@
     river_id NUMBER(38),
     area NUMBER(19,5),
     name VARCHAR2(255),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('CATCHMENT', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -188,6 +204,7 @@
     hws_facility VARCHAR2(255),
     type VARCHAR2(255),
     name VARCHAR(64),
+    path     VARCHAR(256),
     ID NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('hws', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -211,6 +228,7 @@
     count NUMBER(38),
     area NUMBER(19,5),
     perimeter NUMBER(19,5),
+    path     VARCHAR(256),
     id NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('floodmaps', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -230,6 +248,7 @@
     river_id NUMBER(38),
     name VARCHAR(255),
     kind NUMBER(38),
+    path     VARCHAR(256),
     id NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('hydr_boundaries', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -247,6 +266,7 @@
     river_id NUMBER(38),
     name VARCHAR(255),
     kind NUMBER(38),
+    path     VARCHAR(256),
     id NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('hydr_boundaries_poly', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
@@ -265,6 +285,7 @@
     GEOM        MDSYS.SDO_GEOMETRY,
     river_id    NUMBER(38),
     name        VARCHAR(64),
+    path     VARCHAR(256),
     id          NUMBER PRIMARY KEY NOT NULL
 );
 INSERT INTO USER_SDO_GEOM_METADATA VALUES ('gauge_location', 'GEOM', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',3282450,3912240,0.001),MDSYS.SDO_DIM_ELEMENT('Y',5248260,6100130,0.001),MDSYS.SDO_DIM_ELEMENT('Z',-100000,100000,0.002)), 31467);
--- a/flys-backend/doc/schema/oracle.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/oracle.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -249,6 +249,7 @@
 
 CREATE TABLE rivers (
     id                  NUMBER(38,0) NOT NULL,
+    official_number     NUMBER(38,0),
     km_up               NUMBER(38,0),
     name                VARCHAR2(255),
     wst_unit_id         NUMBER(38,0),
@@ -425,7 +426,8 @@
   SELECT w.river_id AS river_id,
          w.id       AS wst_id,
          wc.id      AS wst_column_id,
-         wc.name    AS name
+         wc.name    AS name,
+         wc.position AS wst_column_pos
   FROM   wsts w
          JOIN wst_columns wc
            ON wc.wst_id = w.id
@@ -465,7 +467,8 @@
          a,
          b,
          ol.name,
-         value
+         value,
+         wst_column_pos
   FROM   official_lines ol
          JOIN q_main_values qmv
            ON ol.river_id = qmv.river_id
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/doc/schema/postgresql-drop-spatial.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,45 @@
+BEGIN;
+
+DROP TABLE river_axes;
+DROP SEQUENCE RIVER_AXES_ID_SEQ;
+
+DROP TABLE river_axes_km;
+DROP SEQUENCE RIVER_AXES_KM_ID_SEQ;
+
+DROP TABLE cross_section_tracks;
+DROP SEQUENCE CROSS_SECTION_TRACKS_ID_SEQ;
+
+DROP TABLE lines;
+DROP SEQUENCE LINES_ID_SEQ;
+
+DROP TABLE buildings;
+DROP SEQUENCE BUILDINGS_ID_SEQ;
+
+DROP TABLE fixpoints;
+DROP SEQUENCE FIXPOINTS_ID_SEQ;
+
+DROP TABLE floodplain;
+DROP SEQUENCE FLOODPLAIN_ID_SEQ;
+
+DROP TABLE dem;
+DROP SEQUENCE DEM_ID_SEQ;
+
+DROP TABLE catchment;
+DROP SEQUENCE CATCHMENT_ID_SEQ;
+
+DROP TABLE hws;
+DROP SEQUENCE HWS_ID_SEQ;
+
+DROP TABLE floodmaps;
+DROP SEQUENCE FLOODMAPS_ID_SEQ;
+
+DROP TABLE hydr_boundaries;
+DROP SEQUENCE HYDR_BOUNDARIES_ID_SEQ;
+
+DROP TABLE hydr_boundaries_poly;
+DROP SEQUENCE HYDR_BOUNDARIES_POLY_ID_SEQ;
+
+DROP TABLE gauge_location;
+DROP SEQUENCE GAUGE_LOCATION_ID_SEQ;
+
+COMMIT;
--- a/flys-backend/doc/schema/postgresql-minfo.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/postgresql-minfo.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -84,9 +84,9 @@
     station                 NUMERIC NOT NULL,
     height                  NUMERIC,
     uncertainty             NUMERIC,
-    data_gap                NUMERIC NOT NULL,
-    sounding_width          NUMERIC NOT NULL,
-    width                   NUMERIC NOT NULL,
+    data_gap                NUMERIC,
+    sounding_width          NUMERIC,
+    width                   NUMERIC,
     PRIMARY KEY(id),
     CONSTRAINT fk_bed_single_values_parent FOREIGN KEY (bed_height_single_id) REFERENCES bed_height_single(id)
 );
@@ -306,7 +306,7 @@
 
 CREATE SEQUENCE WATERLEVEL_VALUES_ID_SEQ;
 
-CREATE TABLE waterlevel_values(
+CREATE TABLE waterlevel_values (
     id                      int NOT NULL,
     waterlevel_q_range_id   int NOT NULL,
     station                 NUMERIC NOT NULL,
@@ -351,4 +351,32 @@
     CONSTRAINT fk_wdv_column_id FOREIGN KEY (column_id) REFERENCES waterlevel_difference_column (id)
 );
 
+
+CREATE SEQUENCE SQ_RELATION_ID_SEQ;
+
+CREATE TABLE sq_relation (
+    id               int NOT NULL,
+    river_id         int NOT NULL,
+    time_interval_id int NOT NULL,
+    description      VARCHAR(256),
+    PRIMARY KEY (id),
+    CONSTRAINT fk_sqr_river_id FOREIGN KEY (river_id) REFERENCES rivers(id),
+    CONSTRAINT fk_sqr_tinterval_id FOREIGN KEY (time_interval_id) REFERENCES time_intervals(id)
+);
+
+
+CREATE SEQUENCE SQ_RELATION_VALUES_ID_SEQ;
+
+CREATE TABLE sq_relation_value (
+    id             int NOT NULL,
+    sq_relation_id int NOT NULL,
+    parameter      VARCHAR(16)  NOT NULL,
+    fraction       VARCHAR(32)  NOT NULL,
+    function       VARCHAR(32)  NOT NULL,
+    km             NUMERIC NOT NULL,
+    a              NUMERIC NOT NULL,
+    b              NUMERIC NOT NULL,
+    PRIMARY KEY (id),
+    CONSTRAINT fk_sqr_id FOREIGN KEY (sq_relation_id) REFERENCES sq_relation(id)
+);
 COMMIT;
--- a/flys-backend/doc/schema/postgresql-spatial.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/postgresql-spatial.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -5,9 +5,11 @@
 CREATE TABLE river_axes (
     id       int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
-    kind     int             NOT NULL DEFAULT 0
+    kind     int             NOT NULL DEFAULT 0,
+    name     VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('river_axes', 'geom', 31466, 'LINESTRING', 2);
+SELECT AddGeometryColumn('river_axes', 'geom', 31467, 'LINESTRING', 2);
 ALTER TABLE river_axes ALTER COLUMN id SET DEFAULT NEXTVAL('RIVER_AXES_ID_SEQ');
 
 
@@ -17,9 +19,11 @@
 CREATE TABLE river_axes_km (
     id       int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
-    km       NUMERIC NOT NULL
+    km       NUMERIC NOT NULL,
+    name     VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('river_axes_km', 'geom', 31466, 'POINT', 2);
+SELECT AddGeometryColumn('river_axes_km', 'geom', 31467, 'POINT', 2);
 ALTER TABLE river_axes_km ALTER COLUMN id SET DEFAULT NEXTVAL('RIVER_AXES_KM_ID_SEQ');
 
 
@@ -29,9 +33,11 @@
     id       int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
     km       NUMERIC NOT NULL,
-    z        NUMERIC NOT NULL DEFAULT 0
+    z        NUMERIC NOT NULL DEFAULT 0,
+    name     VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('cross_section_tracks', 'geom', 31466, 'LINESTRING', 2);
+SELECT AddGeometryColumn('cross_section_tracks', 'geom', 31467, 'LINESTRING', 2);
 ALTER TABLE cross_section_tracks ALTER COLUMN id SET DEFAULT NEXTVAL('CROSS_SECTION_TRACKS_ID_SEQ');
 
 
@@ -41,9 +47,11 @@
     id       int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
     kind     VARCHAR(16) NOT NULL,
-    z        NUMERIC DEFAULT 0
+    z        NUMERIC DEFAULT 0,
+    name     VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('lines', 'geom', 31466, 'LINESTRING', 4);
+SELECT AddGeometryColumn('lines', 'geom', 31467, 'LINESTRING', 3);
 ALTER TABLE lines ALTER COLUMN id SET DEFAULT NEXTVAL('LINES_ID_SEQ');
 -- 'kind':
 -- 0: ROHR1
@@ -55,9 +63,10 @@
 CREATE TABLE buildings (
     id       int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
-    name     VARCHAR(256)
+    name     VARCHAR(256),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('buildings', 'geom', 31466, 'LINESTRING', 2);
+SELECT AddGeometryColumn('buildings', 'geom', 31467, 'LINESTRING', 2);
 ALTER TABLE buildings ALTER COLUMN id SET DEFAULT NEXTVAL('BUILDINGS_ID_SEQ');
 
 
@@ -69,9 +78,11 @@
     x        int,
     y        int,
     km       NUMERIC NOT NULL,
-    HPGP     VARCHAR(2)
+    HPGP     VARCHAR(2),
+    name     VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('fixpoints', 'geom', 31466, 'POINT', 2);
+SELECT AddGeometryColumn('fixpoints', 'geom', 31467, 'POINT', 2);
 ALTER TABLE fixpoints ALTER COLUMN id SET DEFAULT NEXTVAL('FIXPOINTS_ID_SEQ');
 
 
@@ -79,9 +90,11 @@
 CREATE SEQUENCE FLOODPLAIN_ID_SEQ;
 CREATE TABLE floodplain (
     id       int PRIMARY KEY NOT NULL,
-    river_id int REFERENCES rivers(id)
+    river_id int REFERENCES rivers(id),
+    name     VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('floodplain', 'geom', 31466, 'POLYGON', 2);
+SELECT AddGeometryColumn('floodplain', 'geom', 31467, 'POLYGON', 2);
 ALTER TABLE floodplain ALTER COLUMN id SET DEFAULT NEXTVAL('FLOODPLAIN_ID_SEQ');
 
 
@@ -91,10 +104,18 @@
     id       int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
     -- XXX Should we use the ranges table instead?
-    lower    NUMERIC,
-    upper    NUMERIC,
-    path     VARCHAR(256),
-    UNIQUE (river_id, lower, upper)
+    name            VARCHAR(64),
+    lower           NUMERIC,
+    upper           NUMERIC,
+    year_from       VARCHAR(32) NOT NULL,
+    year_to         VARCHAR(32) NOT NULL,
+    projection      VARCHAR(32) NOT NULL,
+    elevation_state VARCHAR(32),
+    format          VARCHAR(32),
+    border_break    BOOLEAN NOT NULL DEFAULT FALSE,
+    resolution      VARCHAR(16),
+    description     VARCHAR(256),
+    path            VARCHAR(256)
 );
 ALTER TABLE dem ALTER COLUMN id SET DEFAULT NEXTVAL('DEM_ID_SEQ');
 
@@ -105,9 +126,10 @@
     id int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
     area NUMERIC,
-    name VARCHAR(256)
+    name VARCHAR(256),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('catchment','geom',31466,'POLYGON',2);
+SELECT AddGeometryColumn('catchment','geom',31467,'POLYGON',2);
 ALTER TABLE catchment ALTER COLUMN id SET DEFAULT NEXTVAL('CATCHMENT_ID_SEQ');
 
 
@@ -117,9 +139,11 @@
     id int PRIMARY KEY NOT NULL,
     river_id int REFERENCES rivers(id),
     hws_facility VARCHAR(256),
-    type VARCHAR(256)
+    type VARCHAR(256),
+    name VARCHAR(64),
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('hws','geom',31466,'LINESTRING',2);
+SELECT AddGeometryColumn('hws','geom',31467,'LINESTRING',2);
 ALTER TABLE hws ALTER COLUMN id SET DEFAULT NEXTVAL('HWS_ID_SEQ');
 
 
@@ -133,14 +157,7 @@
 -- 121 = Berechnung->Potenziell->BfG
 -- 122 = Berechnung->Potenziell->Land
 --
-CREATE SEQUENCE FLOODMAPS_SEQ;
-CREATE FUNCTION floodmaps_id_func() RETURNS trigger AS $floodmaps_id_func$
-    BEGIN
-        NEW.id := nextval('floodmaps_seq');
-        RETURN NEW;
-    END;
-$floodmaps_id_func$ LANGUAGE plpgsql;
-
+CREATE SEQUENCE FLOODMAPS_ID_SEQ;
 CREATE TABLE floodmaps (
     id         int PRIMARY KEY NOT NULL,
     river_id   int REFERENCES rivers(id),
@@ -149,13 +166,47 @@
     diff       real,
     count      int,
     area       real,
-    perimeter  real
+    perimeter  real,
+    path     VARCHAR(256)
 );
-SELECT AddGeometryColumn('floodmaps', 'geom', 31466, 'MULTIPOLYGON', 2);
+SELECT AddGeometryColumn('floodmaps', 'geom', 31467, 'MULTIPOLYGON', 2);
 ALTER TABLE floodmaps DROP CONSTRAINT enforce_geotype_geom;
 ALTER TABLE floodmaps ADD CONSTRAINT enforce_geotype_geom CHECK (geometrytype(geom) = 'POLYGON'::text OR geometrytype(geom) = 'MULTIPOLYGON'::text);
-ALTER TABLE floodmaps ALTER COLUMN id SET DEFAULT NEXTVAL('FLOODMAPS_SEQ');
+ALTER TABLE floodmaps ALTER COLUMN id SET DEFAULT NEXTVAL('FLOODMAPS_ID_SEQ');
 
-CREATE TRIGGER floodmaps_id_trigger BEFORE INSERT OR UPDATE ON floodmaps
-    FOR EACH ROW EXECUTE PROCEDURE floodmaps_id_func();
-END;
+
+CREATE SEQUENCE HYDR_BOUNDARIES_ID_SEQ;
+CREATE TABLE hydr_boundaries (
+    id         int PRIMARY KEY NOT NULL,
+    river_id   int REFERENCES rivers(id),
+    name       VARCHAR(255),
+    kind       int,
+    path       VARCHAR(256)
+);
+SELECT AddGeometryColumn('hydr_boundaries','geom',31467,'LINESTRING',3);
+ALTER TABLE hydr_boundaries ALTER COLUMN id SET DEFAULT NEXTVAL('HYDR_BOUNDARIES_ID_SEQ');
+
+
+CREATE SEQUENCE HYDR_BOUNDARIES_POLY_ID_SEQ;
+CREATE TABLE hydr_boundaries_poly (
+    id         int PRIMARY KEY NOT NULL,
+    river_id   int REFERENCES rivers(id),
+    name       VARCHAR(255),
+    kind       int,
+    path       VARCHAR(256)
+);
+SELECT AddGeometryColumn('hydr_boundaries_poly','geom',31467,'POLYGON',3);
+ALTER TABLE hydr_boundaries_poly ALTER COLUMN id SET DEFAULT NEXTVAL('HYDR_BOUNDARIES_POLY_ID_SEQ');
+
+
+CREATE SEQUENCE GAUGE_LOCATION_ID_SEQ;
+CREATE TABLE gauge_location (
+    id         int PRIMARY KEY NOT NULL,
+    river_id   int REFERENCES rivers(id),
+    name       VARCHAR(255),
+    path       VARCHAR(256)
+);
+SELECT AddGeometryColumn('gauge_location','geom',31467,'POINT',2);
+ALTER TABLE gauge_location ALTER COLUMN id SET DEFAULT NEXTVAL('GAUGE_LOCATION_ID_SEQ');
+
+COMMIT;
--- a/flys-backend/doc/schema/postgresql.sql	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/doc/schema/postgresql.sql	Fri Sep 28 12:15:40 2012 +0200
@@ -11,10 +11,11 @@
 CREATE SEQUENCE RIVERS_ID_SEQ;
 
 CREATE TABLE rivers (
-    id          int PRIMARY KEY NOT NULL,
-    name        VARCHAR(256)    NOT NULL UNIQUE,
-    km_up       BOOLEAN         NOT NULL DEFAULT true,
-    wst_unit_id int             NOT NULL REFERENCES units(id)
+    id              int PRIMARY KEY NOT NULL,
+    official_number int8                     UNIQUE,
+    name            VARCHAR(256)    NOT NULL UNIQUE,
+    km_up           BOOLEAN         NOT NULL DEFAULT true,
+    wst_unit_id int                 NOT NULL REFERENCES units(id)
 );
 
 -- Bruecke, Haefen, etc.
@@ -280,12 +281,6 @@
     description      VARCHAR(256)
 );
 
--- Indices for faster access of the points
-CREATE INDEX cross_section_lines_km_idx
-    ON cross_section_lines(km);
-CREATE INDEX cross_section_points_line_idx
-    ON cross_section_points(cross_section_line_id);
-
 CREATE SEQUENCE CROSS_SECTION_LINES_ID_SEQ;
 
 CREATE TABLE cross_section_lines (
@@ -306,6 +301,12 @@
     UNIQUE (cross_section_line_id, col_pos)
 );
 
+-- Indices for faster access of the points
+CREATE INDEX cross_section_lines_km_idx
+    ON cross_section_lines(km);
+CREATE INDEX cross_section_points_line_idx
+    ON cross_section_points(cross_section_line_id);
+
 -- Hydraulische Kenngroessen
 
 CREATE SEQUENCE HYKS_ID_SEQ;
@@ -364,7 +365,8 @@
   SELECT w.river_id AS river_id,
          w.id       AS wst_id,
          wc.id      AS wst_column_id,
-         wc.name    AS name
+         wc.name    AS name,
+         wc.position AS wst_column_pos
   FROM   wsts w
          JOIN wst_columns wc
            ON wc.wst_id = w.id
@@ -404,7 +406,8 @@
          a,
          b,
          ol.name,
-         value
+         value,
+         wst_column_pos
   FROM   official_lines ol
          JOIN q_main_values qmv
            ON ol.river_id = qmv.river_id
--- a/flys-backend/pom.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/pom.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -33,8 +33,8 @@
         <artifactId>maven-compiler-plugin</artifactId>
         <version>2.0.2</version>
         <configuration>
-          <source>1.5</source>
-          <target>1.5</target>
+          <source>1.6</source>
+          <target>1.6</target>
         </configuration>
       </plugin>
     </plugins>
@@ -53,6 +53,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>net.sf.opencsv</groupId>
+      <artifactId>opencsv</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>3.6.5.Final</version>
--- a/flys-backend/src/main/java/de/intevation/flys/importer/Config.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/Config.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,6 +2,9 @@
 
 public class Config
 {
+    public static final String SKIP_DEFAULT =
+        "flys.backend.importer.skip.default";
+
     public static final String DRY_RUN =
         "flys.backend.importer.dry.run";
 
@@ -74,8 +77,15 @@
     private Config () {
     }
 
+    public static final boolean getFlag(String key) {
+        String flag = System.getProperty(key);
+        return flag != null
+            ? Boolean.valueOf(flag)
+            : Boolean.getBoolean(SKIP_DEFAULT);
+    }
+
     public boolean dryRun() {
-        return Boolean.getBoolean(DRY_RUN);
+        return getFlag(DRY_RUN);
     }
 
     public String getInfoGewFile() {
@@ -87,79 +97,79 @@
     }
 
     public boolean skipGauges() {
-        return Boolean.getBoolean(SKIP_GAUGES);
+        return getFlag(SKIP_GAUGES);
     }
 
     public boolean skipAnnotations() {
-        return Boolean.getBoolean(SKIP_ANNOTATIONS);
+        return getFlag(SKIP_ANNOTATIONS);
     }
 
     public boolean skipPRFs() {
-        return Boolean.getBoolean(SKIP_PRFS);
+        return getFlag(SKIP_PRFS);
     }
 
     public boolean skipHYKs() {
-        return Boolean.getBoolean(SKIP_HYKS);
+        return getFlag(SKIP_HYKS);
     }
 
     public boolean skipWst() {
-        return Boolean.getBoolean(SKIP_WST);
+        return getFlag(SKIP_WST);
     }
 
     public boolean skipExtraWsts() {
-        return Boolean.getBoolean(SKIP_EXTRA_WSTS);
+        return getFlag(SKIP_EXTRA_WSTS);
     }
 
     public boolean skipFixations() {
-        return Boolean.getBoolean(SKIP_FIXATIONS);
+        return getFlag(SKIP_FIXATIONS);
     }
 
     public boolean skipOfficialLines() {
-        return Boolean.getBoolean(SKIP_OFFICIAL_LINES);
+        return getFlag(SKIP_OFFICIAL_LINES);
     }
 
     public boolean skipFloodWater() {
-        return Boolean.getBoolean(SKIP_FLOOD_WATER);
+        return getFlag(SKIP_FLOOD_WATER);
     }
 
     public boolean skipFloodProtection() {
-        return Boolean.getBoolean(SKIP_FLOOD_PROTECTION);
+        return getFlag(SKIP_FLOOD_PROTECTION);
     }
 
     public boolean skipBedHeightSingle() {
-        return Boolean.getBoolean(SKIP_BED_HEIGHT_SINGLE);
+        return getFlag(SKIP_BED_HEIGHT_SINGLE);
     }
 
     public boolean skipBedHeightEpoch() {
-        return Boolean.getBoolean(SKIP_BED_HEIGHT_EPOCH);
+        return getFlag(SKIP_BED_HEIGHT_EPOCH);
     }
 
     public boolean skipSedimentDensity() {
-        return Boolean.getBoolean(SKIP_SEDIMENT_DENSITY);
+        return getFlag(SKIP_SEDIMENT_DENSITY);
     }
 
     public boolean skipMorphologicalWidth() {
-        return Boolean.getBoolean(SKIP_MORPHOLOGICAL_WIDTH);
+        return getFlag(SKIP_MORPHOLOGICAL_WIDTH);
     }
 
     public boolean skipFlowVelocity() {
-        return Boolean.getBoolean(SKIP_FLOW_VELOCITY);
+        return getFlag(SKIP_FLOW_VELOCITY);
     }
 
     public boolean skipSedimentYield() {
-        return Boolean.getBoolean(SKIP_SEDIMENT_YIELD);
+        return getFlag(SKIP_SEDIMENT_YIELD);
     }
 
     public boolean skipWaterlevels() {
-        return Boolean.getBoolean(SKIP_WATERLEVELS);
+        return getFlag(SKIP_WATERLEVELS);
     }
 
     public boolean skipWaterlevelDifferences() {
-        return Boolean.getBoolean(SKIP_WATERLEVEL_DIFFERENCES);
+        return getFlag(SKIP_WATERLEVEL_DIFFERENCES);
     }
 
     public boolean skipSQRelation() {
-        return Boolean.getBoolean(SKIP_SQ_RELATION);
+        return getFlag(SKIP_SQ_RELATION);
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportBedHeightEpoch.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportBedHeightEpoch.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,14 +1,12 @@
 package de.intevation.flys.importer;
 
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 
-import java.sql.SQLException;
-
 import org.apache.log4j.Logger;
-
+import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.Query;
 import org.hibernate.exception.ConstraintViolationException;
 
 import de.intevation.flys.model.BedHeightEpoch;
@@ -18,15 +16,19 @@
 import de.intevation.flys.model.TimeInterval;
 
 
-public class ImportBedHeightEpoch implements ImportBedHeight
-{
+/** Import Bed Height Data, 'epoch' type from csv file. */
+public class ImportBedHeightEpoch implements ImportBedHeight {
+
+    /** Private logger. */
     private static Logger log = Logger.getLogger(ImportBedHeightEpoch.class);
 
     protected String evaluationBy;
+
+    /** De facto the file name. */
     protected String description;
 
-    protected ImportTimeInterval   timeInterval;
-    protected ImportRange          range;
+    protected ImportTimeInterval timeInterval;
+    protected ImportRange range;
     protected ImportElevationModel curElevationModel;
     protected ImportElevationModel oldElevationModel;
 
@@ -34,18 +36,15 @@
 
     protected BedHeightEpoch peer;
 
-
     public ImportBedHeightEpoch(String description) {
         this.description = description;
-        this.values      = new ArrayList<ImportBedHeightEpochValue>();
+        this.values = new ArrayList<ImportBedHeightEpochValue>();
     }
 
-
     public String getDescription() {
         return description;
     }
 
-
     public int getValueCount() {
         return values.size();
     }
@@ -54,7 +53,6 @@
         this.timeInterval = timeInterval;
     }
 
-
     public void setEvaluationBy(String evaluationBy) {
         this.evaluationBy = evaluationBy;
     }
@@ -75,18 +73,24 @@
         this.oldElevationModel = oldElevationModel;
     }
 
+    /** Does nothing. */
     public void setYear(int year) {
         // do nothing
     }
 
+    /** Does nothing. */
     public void setSoundingWidth(int soundingWidth) {
         // do nothing
     }
 
+
+    /** Does nothing. */
     public void setLocationSystem(ImportLocationSystem locationSystem) {
         // do nothing
     }
 
+
+    /** Does nothing. */
     public void setType(ImportBedHeightType type) {
         // do nothing
     }
@@ -96,13 +100,13 @@
         values.add((ImportBedHeightEpochValue) value);
     }
 
-
     @Override
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.info("Store dependencies for epoch: '" + getDescription() + "'");
 
+        BedHeightEpoch peer = getPeer(river);
+
         if (curElevationModel != null) {
             curElevationModel.storeDependencies();
         }
@@ -111,57 +115,62 @@
             oldElevationModel.storeDependencies();
         }
 
-        BedHeightEpoch peer = getPeer(river);
+        if (peer != null) {
+            log.debug("store values now...");
 
-        log.debug("store values now...");
-
-        for (ImportBedHeightEpochValue value: values) {
-            value.storeDependencies(peer);
+            for (ImportBedHeightEpochValue value : values) {
+                value.storeDependencies(peer);
+            }
         }
 
         Session session = ImporterSession.getInstance().getDatabaseSession();
         session.flush();
     }
 
-
+    /**
+     * Asserts all dependent entities (ElevationModel, TimeInterval, Range,
+     * BedHeighEpoch) are in db and returns bound (either newly created or
+     * freshly fetched) BedHeightEpoch.
+     */
     @Override
     public BedHeightEpoch getPeer(River river) {
         if (peer == null) {
-            ElevationModel theCurModel = curElevationModel != null
-                ? curElevationModel.getPeer()
-                : null;
+            ElevationModel theCurModel = null;
+            if (curElevationModel != null) {
+                curElevationModel.storeDependencies();
+                theCurModel = curElevationModel.getPeer();
+            }
 
             if (theCurModel == null) {
-                log.warn("Skip file - invalid current elevation model.");
+                log.warn("BHE: Skip file - invalid current elevation model.");
                 return null;
             }
 
-            TimeInterval theTime = timeInterval != null
-                ? timeInterval.getPeer()
-                : null;
+            TimeInterval theTime = null;
+            if (timeInterval != null) {
+                theTime = timeInterval.getPeer();
+            }
 
             if (theTime == null) {
-                log.warn("Skip file - invalid time range.");
+                log.warn("BHE: Skip file - invalid time range.");
                 return null;
             }
 
             Range theRange = range != null ? range.getPeer(river) : null;
 
             if (theRange == null) {
-                log.warn("Skip file - invalid km range.");
+                log.warn("BHE: Skip file - invalid km range.");
                 return null;
             }
 
-            Session session = ImporterSession.getInstance().getDatabaseSession();
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
 
-            Query query = session.createQuery(
-                "from BedHeightEpoch where " +
-                "   river=:river and " +
-                "   timeInterval=:timeInterval and " +
-                "   curElevationModel=:curElevationModel and " +
-                "   range=:range and " +
-                "   evaluationBy=:evaluationBy and " +
-                "   description=:description");
+            Query query = session.createQuery("from BedHeightEpoch where "
+                + "   river=:river and " + "   timeInterval=:timeInterval and "
+                + "   curElevationModel=:curElevationModel and "
+                + "   range=:range and " + "   evaluationBy=:evaluationBy and "
+                + "   description=:description");
 
             query.setParameter("river", river);
             query.setParameter("timeInterval", theTime);
@@ -175,15 +184,10 @@
             if (bedHeights.isEmpty()) {
                 log.info("Create new BedHeightEpoch DB instance.");
 
-                peer = new BedHeightEpoch(
-                    river,
-                    theTime,
-                    theRange,
+                peer = new BedHeightEpoch(river, theTime, theRange,
                     theCurModel,
-                    oldElevationModel != null ? oldElevationModel.getPeer() : null,
-                    evaluationBy,
-                    description
-                );
+                    oldElevationModel != null ? oldElevationModel.getPeer()
+                        : null, evaluationBy, description);
 
                 session.save(peer);
             }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportBedHeightSingle.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportBedHeightSingle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -123,8 +123,10 @@
 
         BedHeightSingle peer = getPeer(river);
 
-        for (ImportBedHeightSingleValue value: values) {
-            value.storeDependencies(peer);
+        if (peer != null) {
+            for (ImportBedHeightSingleValue value: values) {
+                value.storeDependencies(peer);
+            }
         }
 
         Session session = ImporterSession.getInstance().getDatabaseSession();
@@ -139,7 +141,7 @@
             Range          theRange    = range != null ? range.getPeer(river) : null;
 
             if (theType == null || theCurModel == null || theRange == null) {
-                log.warn("Skip invalid file '" + description + "'");
+                log.warn("BHS: Skip invalid file '" + description + "'");
                 return null;
             }
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportBedHeightSingleValue.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportBedHeightSingleValue.java	Fri Sep 28 12:15:40 2012 +0200
@@ -55,6 +55,10 @@
     }
 
 
+    /**
+     * Add this value to database or return database bound Value, assuring
+     * that the BedHeightSingle exists in db already.
+     */
     public BedHeightSingleValue getPeer(BedHeightSingle bedHeight) {
         if (peer == null) {
             Session session = ImporterSession.getInstance().getDatabaseSession();
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportElevationModel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportElevationModel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -33,6 +33,11 @@
     }
 
     public ElevationModel getPeer() {
+        if (unit == null) {
+            log.warn("No elevation model specified.");
+            return null;
+        }
+
         if (peer == null) {
             Session session = ImporterSession.getInstance().getDatabaseSession();
             Query query = session.createQuery(
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportFlowVelocityMeasurement.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportFlowVelocityMeasurement.java	Fri Sep 28 12:15:40 2012 +0200
@@ -16,9 +16,8 @@
 
 public class ImportFlowVelocityMeasurement {
 
-    private static final Logger log =
-        Logger.getLogger(ImportFlowVelocityMeasurement.class);
-
+    private static final Logger log = Logger
+        .getLogger(ImportFlowVelocityMeasurement.class);
 
     private String description;
 
@@ -26,50 +25,44 @@
 
     private FlowVelocityMeasurement peer;
 
-
     public ImportFlowVelocityMeasurement() {
         this(null);
     }
 
-
     public ImportFlowVelocityMeasurement(String description) {
         this.description = description;
-        this.values      = new ArrayList<ImportFlowVelocityMeasurementValue>();
+        this.values = new ArrayList<ImportFlowVelocityMeasurementValue>();
     }
 
-
     public void setDescription(String description) {
         this.description = description;
     }
 
-
     public void addValue(ImportFlowVelocityMeasurementValue value) {
         this.values.add(value);
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.debug("store dependencies");
 
         FlowVelocityMeasurement peer = getPeer(river);
 
-        for (ImportFlowVelocityMeasurementValue value: values) {
-            value.storeDependencies(peer);
+        if (peer != null) {
+            for (ImportFlowVelocityMeasurementValue value : values) {
+                value.storeDependencies(peer);
+            }
         }
     }
 
-
     public FlowVelocityMeasurement getPeer(River river) {
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
 
-            Query query = session.createQuery(
-                "from FlowVelocityMeasurement where " +
-                "   river=:river and " +
-                "   description=:description"
-            );
+            Query query = session
+                .createQuery("from FlowVelocityMeasurement where "
+                    + "   river=:river and " + "   description=:description");
 
             query.setParameter("river", river);
             query.setParameter("description", description);
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportFlowVelocityModel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportFlowVelocityModel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -17,9 +17,8 @@
 
 public class ImportFlowVelocityModel {
 
-    private static final Logger log =
-        Logger.getLogger(ImportFlowVelocityModel.class);
-
+    private static final Logger log = Logger
+        .getLogger(ImportFlowVelocityModel.class);
 
     private String description;
 
@@ -29,41 +28,32 @@
 
     private FlowVelocityModel peer;
 
-
     public ImportFlowVelocityModel() {
         values = new ArrayList<ImportFlowVelocityModelValue>();
     }
 
-
-    public ImportFlowVelocityModel(
-        ImportDischargeZone dischargeZone,
-        String              description
-    ) {
+    public ImportFlowVelocityModel(ImportDischargeZone dischargeZone,
+        String description) {
         this();
 
         this.dischargeZone = dischargeZone;
-        this.description   = description;
+        this.description = description;
     }
 
-
     public void setDischargeZone(ImportDischargeZone dischargeZone) {
         this.dischargeZone = dischargeZone;
     }
 
-
     public void setDescription(String description) {
         this.description = description;
     }
 
-
     public void addValue(ImportFlowVelocityModelValue value) {
         this.values.add(value);
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.debug("store dependencies");
 
         if (dischargeZone == null) {
@@ -75,28 +65,27 @@
 
         FlowVelocityModel peer = getPeer(river);
 
-        int i = 0;
+        if (peer != null) {
+            int i = 0;
 
-        for (ImportFlowVelocityModelValue value: values) {
-            value.storeDependencies(peer);
-            i++;
+            for (ImportFlowVelocityModelValue value : values) {
+                value.storeDependencies(peer);
+                i++;
+            }
+
+            log.info("stored " + i + " flow velocity model values.");
         }
-
-        log.info("stored " + i + " flow velocity model values.");
     }
 
-
     public FlowVelocityModel getPeer(River river) {
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
 
             DischargeZone zone = dischargeZone.getPeer(river);
 
-            Query query = session.createQuery(
-                "from FlowVelocityModel where " +
-                "   river=:river and " +
-                "   dischargeZone=:dischargeZone"
-            );
+            Query query = session.createQuery("from FlowVelocityModel where "
+                + "   river=:river and " + "   dischargeZone=:dischargeZone");
 
             query.setParameter("river", river);
             query.setParameter("dischargeZone", zone);
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportMorphWidth.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportMorphWidth.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,14 +1,12 @@
 package de.intevation.flys.importer;
 
 import java.sql.SQLException;
-
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
-
+import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.Query;
 import org.hibernate.exception.ConstraintViolationException;
 
 import de.intevation.flys.model.MorphologicalWidth;
@@ -19,54 +17,48 @@
 
     private static Logger log = Logger.getLogger(ImportMorphWidth.class);
 
-
     protected MorphologicalWidth peer;
 
     protected ImportUnit unit;
 
     protected List<ImportMorphWidthValue> values;
 
-
     public ImportMorphWidth() {
         this.values = new ArrayList<ImportMorphWidthValue>();
     }
 
-
     public void addValue(ImportMorphWidthValue value) {
         this.values.add(value);
     }
 
-
     public void setUnit(ImportUnit unit) {
         this.unit = unit;
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.info("store dependencies");
 
         MorphologicalWidth peer = getPeer(river);
 
-        log.info("store morphological width values");
+        if (peer != null) {
+            log.info("store morphological width values");
 
-        for (ImportMorphWidthValue value: values) {
-            value.storeDependencies(peer);
+            for (ImportMorphWidthValue value : values) {
+                value.storeDependencies(peer);
+            }
         }
     }
 
-
     public MorphologicalWidth getPeer(River river) {
         log.info("get peer");
 
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
 
-            Query query = session.createQuery(
-                "from MorphologicalWidth where " +
-                "   river=:river and " +
-                "   unit=:unit");
+            Query query = session.createQuery("from MorphologicalWidth where "
+                + "   river=:river and " + "   unit=:unit");
 
             query.setParameter("river", river);
             query.setParameter("unit", unit.getPeer());
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportRiver.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportRiver.java	Fri Sep 28 12:15:40 2012 +0200
@@ -322,7 +322,7 @@
         File[] files = sediment.listFiles();
 
         if (files == null) {
-            log.warn("Cannot parse directory '" + sediment + "'");
+            log.warn("Cannot read directory '" + sediment + "'");
             return;
         }
 
@@ -352,7 +352,7 @@
         File[] files = morphDir.listFiles();
 
         if (files == null) {
-            log.warn("Cannot parse directory '" + morphDir + "'");
+            log.warn("Cannot read directory '" + morphDir + "'");
             return;
         }
 
@@ -385,7 +385,7 @@
         File[] measureFiles = measureDir.listFiles();
 
         if (modelFiles == null) {
-            log.warn("Cannot parse directory '" + modelDir + "'");
+            log.warn("Cannot read directory '" + modelDir + "'");
         }
         else {
             FlowVelocityModelParser parser = new FlowVelocityModelParser();
@@ -399,7 +399,7 @@
         }
 
         if (measureFiles == null) {
-            log.warn("Cannot parse directory '" + measureDir + "'");
+            log.warn("Cannot read directory '" + measureDir + "'");
         }
         else {
             FlowVelocityMeasurementParser parser =
@@ -435,7 +435,7 @@
         SedimentYieldParser parser = new SedimentYieldParser();
 
         if (singles == null || singles.length == 0) {
-            log.warn("Cannot parse directory '" + singleDir + "'");
+            log.warn("Cannot read directory '" + singleDir + "'");
         }
         else {
             for (File file: singles) {
@@ -451,7 +451,7 @@
         }
 
         if (epochs == null || epochs.length == 0) {
-            log.warn("Cannot parse directory '" + epochDir + "'");
+            log.warn("Cannot read directory '" + epochDir + "'");
         }
         else {
             for (File file: epochs) {
@@ -564,7 +564,7 @@
         File[] files = dir.listFiles();
 
         if (files == null) {
-            log.warn("Cannot parse directory '" + dir + "'");
+            log.warn("Cannot read directory '" + dir + "'");
             return;
         }
 
@@ -584,7 +584,7 @@
         File[] files = dir.listFiles();
 
         if (files == null) {
-            log.warn("Cannot parse directory '" + dir + "'");
+            log.warn("Cannot read directory '" + dir + "'");
             return;
         }
 
@@ -1127,10 +1127,10 @@
                     width.storeDependencies(river);
                 }
                 catch (SQLException sqle) {
-                    log.error("Error while parsing file for morph. width.");
+                    log.error("Error while parsing file for morph. width.", sqle);
                 }
                 catch (ConstraintViolationException cve) {
-                    log.error("Error while parsing file for morph. width.");
+                    log.error("Error while parsing file for morph. width.", cve);
                 }
             }
         }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportSQRelation.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportSQRelation.java	Fri Sep 28 12:15:40 2012 +0200
@@ -19,7 +19,6 @@
 
     private static Logger log = Logger.getLogger(ImportSQRelation.class);
 
-
     private ImportTimeInterval timeInterval;
 
     private String description;
@@ -28,40 +27,38 @@
 
     private SQRelation peer;
 
-
     public ImportSQRelation() {
         this.values = new ArrayList<ImportSQRelationValue>();
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.info("store dependencies");
 
         SQRelation peer = getPeer(river);
 
         timeInterval.getPeer();
 
-        int count = 0;
+        if (peer != null) {
+            int count = 0;
 
-        for (ImportSQRelationValue value: values) {
-            try {
-                value.storeDependencies(peer);
-                count++;
+            for (ImportSQRelationValue value : values) {
+                try {
+                    value.storeDependencies(peer);
+                    count++;
+                }
+                catch (SQLException sqle) {
+                    log.warn("ISQ: Unable to store sq relation value.", sqle);
+                }
+                catch (ConstraintViolationException cve) {
+                    log.warn("ISQ: Unable to store sq relation value.", cve);
+                }
             }
-            catch (SQLException sqle) {
-                log.warn("Unable to store sq relation value.", sqle);
-            }
-            catch (ConstraintViolationException cve) {
-                log.warn("Unable to store sq relation value.", cve);
-            }
+
+            log.info("stored " + count + " sq relation values.");
         }
-
-        log.info("stored " + count + " sq relation values.");
     }
 
-
     public SQRelation getPeer(River river) {
         log.debug("getPeer()");
 
@@ -69,15 +66,15 @@
             TimeInterval timeInter = timeInterval.getPeer();
 
             if (timeInter == null) {
-                log.warn("Cannot determine sq relation without time interval");
+                log.warn("ISQ: Cannot determine sq relation without time interval");
                 return null;
             }
 
-            Session session = ImporterSession.getInstance().getDatabaseSession();
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
 
-            Query query = session.createQuery(
-                "FROM SQRelation WHERE river=:river AND timeInterval=:timeInter"
-            );
+            Query query = session
+                .createQuery("FROM SQRelation WHERE river=:river AND timeInterval=:timeInter");
 
             query.setParameter("river", river);
             query.setParameter("timeInter", timeInter);
@@ -87,11 +84,7 @@
             if (sq.isEmpty()) {
                 log.info("create new SQ relation '" + description + "'");
 
-                peer = new SQRelation(
-                    river,
-                    timeInter,
-                    description
-                );
+                peer = new SQRelation(river, timeInter, description);
                 session.save(peer);
             }
             else {
@@ -102,17 +95,14 @@
         return peer;
     }
 
-
     public void setDescription(String description) {
         this.description = description;
     }
 
-
     public void setTimeInterval(ImportTimeInterval timeInterval) {
         this.timeInterval = timeInterval;
     }
 
-
     public void addValue(ImportSQRelationValue value) {
         if (value != null) {
             this.values.add(value);
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportSedimentDensity.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportSedimentDensity.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,14 +1,12 @@
 package de.intevation.flys.importer;
 
 import java.sql.SQLException;
-
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
-
+import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.Query;
 import org.hibernate.exception.ConstraintViolationException;
 
 import de.intevation.flys.model.River;
@@ -19,7 +17,6 @@
 
     private static Logger log = Logger.getLogger(ImportSedimentDensity.class);
 
-
     protected SedimentDensity peer;
 
     protected ImportDepth depth;
@@ -30,63 +27,67 @@
 
     protected List<ImportSedimentDensityValue> values;
 
-
     public ImportSedimentDensity(String description) {
         this.description = description;
-        this.values      = new ArrayList<ImportSedimentDensityValue>();
+        this.values = new ArrayList<ImportSedimentDensityValue>();
     }
 
-
     public String getDescription() {
         return description;
     }
 
-
     public void setDepth(ImportDepth depth) {
         this.depth = depth;
     }
 
-
     public void setUnit(ImportUnit unit) {
         this.unit = unit;
     }
 
-
     public void addValue(ImportSedimentDensityValue value) {
         values.add(value);
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.info("store dependencies");
 
         if (depth != null) {
             depth.storeDependencies();
         }
 
-        log.info("store sediment density values.");
-
         SedimentDensity peer = getPeer(river);
 
-        for (ImportSedimentDensityValue value: values) {
-            value.storeDependencies(peer);
+        if (peer != null) {
+            log.info("store sediment density values.");
+            for (ImportSedimentDensityValue value : values) {
+                value.storeDependencies(peer);
+            }
         }
     }
 
-
     public SedimentDensity getPeer(River river) {
         log.info("get peer");
 
-        if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
+        if (depth == null) {
+            log.warn("cannot store sediment density '" + description
+                + "': no depth");
+            return null;
+        }
 
-            Query query = session.createQuery(
-                "from SedimentDensity where " +
-                "   river=:river and " +
-                "   depth=:depth and " +
-                "   unit=:unit");
+        if (unit == null) {
+            log.warn("cannot store sediment density '" + description
+                + "': no unit");
+            return null;
+        }
+
+        if (peer == null) {
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
+
+            Query query = session.createQuery("from SedimentDensity where "
+                + "   river=:river and " + "   depth=:depth and "
+                + "   unit=:unit");
 
             query.setParameter("river", river);
             query.setParameter("depth", depth.getPeer());
@@ -97,11 +98,8 @@
             if (density.isEmpty()) {
                 log.debug("Create new SedimentDensity DB instance.");
 
-                peer = new SedimentDensity(
-                    river,
-                    depth.getPeer(),
-                    unit.getPeer(),
-                    description);
+                peer = new SedimentDensity(river, depth.getPeer(),
+                    unit.getPeer(), description);
 
                 session.save(peer);
             }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportSedimentYield.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportSedimentYield.java	Fri Sep 28 12:15:40 2012 +0200
@@ -33,36 +33,29 @@
 
     private SedimentYield peer;
 
-
     public ImportSedimentYield(String description) {
-        this.values      = new ArrayList<ImportSedimentYieldValue>();
+        this.values = new ArrayList<ImportSedimentYieldValue>();
         this.description = description;
     }
 
-
     public void setTimeInterval(ImportTimeInterval timeInterval) {
         this.timeInterval = timeInterval;
     }
 
-
     public void setUnit(ImportUnit unit) {
         this.unit = unit;
     }
 
-
     public void setGrainFraction(ImportGrainFraction grainFraction) {
         this.grainFraction = grainFraction;
     }
 
-
     public void addValue(ImportSedimentYieldValue value) {
         this.values.add(value);
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.debug("store dependencies");
 
         if (grainFraction != null) {
@@ -71,22 +64,22 @@
 
         SedimentYield peer = getPeer(river);
 
-        int i = 0;
+        if (peer != null) {
+            int i = 0;
 
-        for (ImportSedimentYieldValue value: values) {
-            value.storeDependencies(peer);
-            i++;
+            for (ImportSedimentYieldValue value : values) {
+                value.storeDependencies(peer);
+                i++;
+            }
+
+            log.info("stored " + i + " sediment yield values.");
         }
-
-        log.info("stored " + i + " sediment yield values.");
     }
 
-
     public SedimentYield getPeer(River river) {
         log.debug("get peer");
 
-        GrainFraction gf = grainFraction != null
-            ? grainFraction.getPeer()
+        GrainFraction gf = grainFraction != null ? grainFraction.getPeer()
             : null;
 
         Unit u = unit != null ? unit.getPeer() : null;
@@ -99,15 +92,13 @@
         }
 
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
-            Query query = session.createQuery(
-                "from SedimentYield where " +
-                "   river=:river and " +
-                "   grainFraction=:grainFraction and " +
-                "   unit=:unit and " +
-                "   timeInterval=:timeInterval and " +
-                "   description=:description"
-            );
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
+            Query query = session.createQuery("from SedimentYield where "
+                + "   river=:river and "
+                + "   grainFraction=:grainFraction and " + "   unit=:unit and "
+                + "   timeInterval=:timeInterval and "
+                + "   description=:description");
 
             query.setParameter("river", river);
             query.setParameter("grainFraction", gf);
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportWaterlevel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWaterlevel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -17,7 +17,6 @@
 
     private static final Logger log = Logger.getLogger(ImportWaterlevel.class);
 
-
     private ImportUnit unit;
 
     private String description;
@@ -26,40 +25,37 @@
 
     private Waterlevel peer;
 
-
     public ImportWaterlevel(String description) {
         this.qRanges = new ArrayList<ImportWaterlevelQRange>();
 
         this.description = description;
     }
 
-
     public void setUnit(ImportUnit unit) {
         this.unit = unit;
     }
 
-
     public void addValue(ImportWaterlevelQRange qRange) {
         this.qRanges.add(qRange);
     }
 
-
     public void storeDependencies(River river) {
         log.info("store dependencies");
 
         Waterlevel peer = getPeer(river);
 
-        int i = 0;
+        if (peer != null) {
+            int i = 0;
 
-        for (ImportWaterlevelQRange qRange: qRanges) {
-            qRange.storeDependencies(peer);
-            i++;
+            for (ImportWaterlevelQRange qRange : qRanges) {
+                qRange.storeDependencies(peer);
+                i++;
+            }
+
+            log.info("stored " + i + " waterlevel q ranges");
         }
-
-        log.info("stored " + i + " waterlevel q ranges");
     }
 
-
     public Waterlevel getPeer(River river) {
         Unit u = unit != null ? unit.getPeer() : null;
         if (u == null) {
@@ -68,13 +64,11 @@
         }
 
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
-            Query query = session.createQuery(
-                "from Waterlevel where " +
-                "   river=:river and " +
-                "   unit=:unit and " +
-                "   description=:description"
-            );
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
+            Query query = session.createQuery("from Waterlevel where "
+                + "   river=:river and " + "   unit=:unit and "
+                + "   description=:description");
 
             query.setParameter("river", river);
             query.setParameter("unit", u);
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportWaterlevelDifference.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWaterlevelDifference.java	Fri Sep 28 12:15:40 2012 +0200
@@ -17,9 +17,8 @@
 
 public class ImportWaterlevelDifference {
 
-    private static final Logger log =
-        Logger.getLogger(ImportWaterlevelDifference.class);
-
+    private static final Logger log = Logger
+        .getLogger(ImportWaterlevelDifference.class);
 
     private ImportUnit unit;
 
@@ -29,57 +28,52 @@
 
     private WaterlevelDifference peer;
 
-
     public ImportWaterlevelDifference(String description) {
         this.columns = new ArrayList<ImportWaterlevelDifferenceColumn>();
 
         this.description = description;
     }
 
-
     public void setUnit(ImportUnit unit) {
         this.unit = unit;
     }
 
-
     public void addValue(ImportWaterlevelDifferenceColumn column) {
         this.columns.add(column);
     }
 
-
-    public void storeDependencies(River river)
-    throws SQLException, ConstraintViolationException
-    {
+    public void storeDependencies(River river) throws SQLException,
+        ConstraintViolationException {
         log.info("store dependencies");
 
         WaterlevelDifference peer = getPeer(river);
 
-        int i = 0;
+        if (peer != null) {
+            int i = 0;
 
-        for (ImportWaterlevelDifferenceColumn column: columns) {
-            column.storeDependencies(peer);
-            i++;
+            for (ImportWaterlevelDifferenceColumn column : columns) {
+                column.storeDependencies(peer);
+                i++;
+            }
+
+            log.info("stored " + i + " waterlevel difference columns");
         }
-
-        log.info("stored " + i + " waterlevel difference columns");
     }
 
-
     public WaterlevelDifference getPeer(River river) {
         Unit u = unit != null ? unit.getPeer() : null;
         if (u == null) {
-            log.warn("skip invalid waterlevel difference - no unit set!");
+            log.warn("IWD: skip invalid waterlevel difference - no unit set!");
             return null;
         }
 
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
-            Query query = session.createQuery(
-                "from WaterlevelDifference where " +
-                "   river=:river and " +
-                "   unit=:unit and " +
-                "   description=:description"
-            );
+            Session session = ImporterSession.getInstance()
+                .getDatabaseSession();
+            Query query = session
+                .createQuery("from WaterlevelDifference where "
+                    + "   river=:river and " + "   unit=:unit and "
+                    + "   description=:description");
 
             query.setParameter("river", river);
             query.setParameter("unit", u);
--- a/flys-backend/src/main/java/de/intevation/flys/importer/Importer.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/Importer.java	Fri Sep 28 12:15:40 2012 +0200
@@ -123,7 +123,7 @@
                 infoGewParser.parse(new File(gew));
             }
             catch (IOException ioe) {
-                log.error("cannot while parsing: " + gew);
+                log.error("error while parsing gew: " + gew);
             }
         }
 
@@ -134,7 +134,7 @@
                 infoGewParser.parse(new File(gew));
             }
             catch (IOException ioe) {
-                log.error("cannot parse file: " + gew);
+                log.error("error while parsing gew: " + gew);
             }
         }
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/AnnotationClassifier.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/AnnotationClassifier.java	Fri Sep 28 12:15:40 2012 +0200
@@ -92,7 +92,7 @@
             Element typeElement = (Element)typeList.item(i);
             String name = typeElement.getAttribute("name");
             if (name.length() == 0) {
-                log.warn("rule has no name");
+                log.warn("ANNCLASS: rule has no name");
                 continue;
             }
 
@@ -155,19 +155,19 @@
         String type    = element.getAttribute("type");
 
         if (pattern.length() == 0) {
-            log.warn("pattern has no 'pattern' attribute.");
+            log.warn("ANNCLASS: pattern has no 'pattern' attribute.");
             return null;
         }
 
         if (type.length() == 0) {
-            log.warn("pattern has no 'type' attribute.");
+            log.warn("ANNCLASS: pattern has no 'type' attribute.");
             return null;
         }
 
         ImportAnnotationType annType = types.get(type);
 
         if (annType == null) {
-            log.warn("pattern has unknown type '" + type + "'");
+            log.warn("ANNCLASS: pattern has unknown type '" + type + "'");
             return null;
         }
 
@@ -178,7 +178,7 @@
                     Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE);
         }
         catch (IllegalArgumentException iae) {
-            log.warn("pattern '" + pattern + "' is invalid.", iae);
+            log.warn("ANNCLASS: pattern '" + pattern + "' is invalid.", iae);
             return null;
         }
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/AnnotationsParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/AnnotationsParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -81,7 +81,7 @@
                 String [] parts = line.split("\\s*;\\s*");
 
                 if (parts.length < 3) {
-                    log.warn("not enough columns in line "
+                    log.warn("ANN: not enough columns in line "
                         + in.getLineNumber());
                     continue;
                 }
@@ -110,7 +110,7 @@
                     }
                 }
                 catch (NumberFormatException nfe) {
-                    log.warn("invalid number in line " + in.getLineNumber());
+                    log.warn("ANN: invalid number in line " + in.getLineNumber());
                     continue;
                 }
 
@@ -123,7 +123,7 @@
                             new BigDecimal(parts[3].trim().replace(',', '.')));
                     }
                     catch (NumberFormatException nfe) {
-                        log.warn("cannot parse 'Unterkante' in line " +
+                        log.warn("ANN: cannot parse 'Unterkante' in line " +
                             in.getLineNumber());
                     }
                 }
@@ -141,7 +141,7 @@
                     }
                     catch (NumberFormatException nfe) {
                         log.warn(
-                            "cannot parse 'Unterkante' or 'Oberkante' in line "
+                            "ANN: cannot parse 'Unterkante' or 'Oberkante' in line "
                             + in.getLineNumber());
                     }
                 }
@@ -156,7 +156,7 @@
                     attribute, position, range, edge, type);
 
                 if (!annotations.add(annotation)) {
-                    log.warn("duplicated annotation '" + parts[0] +
+                    log.warn("ANN: duplicated annotation '" + parts[0] +
                         "' in line " + in.getLineNumber());
                 }
             }
@@ -173,12 +173,12 @@
         for (String toScan: TO_SCAN) {
             File directory = FileTools.repair(new File(root, toScan));
             if (!directory.isDirectory()) {
-                log.warn("'" + directory + "' is not a directory.");
+                log.warn("ANN: '" + directory + "' is not a directory.");
                 continue;
             }
             File [] files = directory.listFiles();
             if (files == null) {
-                log.warn("cannot list directory '" + directory + "'");
+                log.warn("ANN: cannot list directory '" + directory + "'");
                 continue;
             }
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/AtFileParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/AtFileParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -132,7 +132,7 @@
             }
         }
         catch (NumberFormatException pe) {
-            logger.warn(pe.getMessage());
+            logger.warn("AT: invalid number " + pe.getMessage());
         }
         finally {
             if (br != null) {
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/BedHeightEpochParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/BedHeightEpochParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,12 +1,9 @@
 package de.intevation.flys.importer.parsers;
 
-
 import java.math.BigDecimal;
 
 import java.text.ParseException;
 
-
-
 import org.apache.log4j.Logger;
 
 import de.intevation.flys.importer.ImportBedHeight;
@@ -14,31 +11,59 @@
 import de.intevation.flys.importer.ImportBedHeightEpochValue;
 
 
+/** Parses BedHeightEpochs from csv file. */
 public class BedHeightEpochParser extends BedHeightParser {
 
+    /** Our own logger. */
     private static final Logger log =
         Logger.getLogger(BedHeightEpochParser.class);
 
 
-
     @Override
     protected ImportBedHeight newImportBedHeight(String description) {
         return new ImportBedHeightEpoch(description);
     }
 
 
+    /**
+     * Handle a non-comment, none-Metadata line of csv file, adding
+     * ImportBedHeightEpochValues to the given ImportBedHeight object.
+     */
     @Override
     protected void handleDataLine(ImportBedHeight obj, String line) {
         String[] values = line.split(SEPERATOR_CHAR);
 
-        if (values == null || values.length < 2 || values[0].length() == 0 || values[1].length() == 0) {
+        if (values == null || values.length == 0 || values[0].length() == 0) {
+            // There might be quite some ";" found.
             //log.warn("Skip invalid data line: " + line);
             return;
         }
 
+        BigDecimal km;
+
+        try {
+            km = new BigDecimal(nf.parse(values[0]).doubleValue());
+        }
+        catch (ParseException e) {
+            log.warn("Error while parsing number from data row: " + line);
+            return;
+        }
+
+
+        // Handle "gap" lines like '255,0;'
+        if (values.length < 2) {
+            ImportBedHeightEpochValue value = new ImportBedHeightEpochValue(
+                km,
+                null
+            );
+
+            obj.addValue(value);
+            return;
+        }
+
         try {
             ImportBedHeightEpochValue value = new ImportBedHeightEpochValue(
-                new BigDecimal(nf.parse(values[0]).doubleValue()),
+                km,
                 new BigDecimal(nf.parse(values[1]).doubleValue())
             );
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/BedHeightParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -46,7 +46,7 @@
     public static final String SEPERATOR_CHAR  = ";";
 
     public static final Pattern META_YEAR =
-        Pattern.compile("^Jahr: (\\d*).*");
+        Pattern.compile("^Jahr: [^0-9]*(\\d*).*");
 
     public static final Pattern META_TIMEINTERVAL =
         Pattern.compile("^Zeitraum: Epoche (\\d*)-(\\d*).*");
@@ -84,6 +84,7 @@
 
     protected abstract ImportBedHeight newImportBedHeight(String description);
 
+    /** Handle a line of file that contains data (in contrast to comments, meta). */
     protected abstract void handleDataLine(
         ImportBedHeight importBedHeight,
         String          line
@@ -192,7 +193,7 @@
             return;
         }
         else {
-            log.warn("Meta line did not match any known type: " + line);
+            log.warn("BHP: Meta line did not match any known type: " + line);
         }
     }
 
@@ -208,7 +209,7 @@
                 return true;
             }
             catch (NumberFormatException e) {
-                log.warn("Error while parsing year!", e);
+                log.warn("BHP: Error while parsing year!", e);
             }
         }
 
@@ -235,7 +236,7 @@
                 obj.setTimeInterval(new ImportTimeInterval(fromYear, toYear));
             }
             catch (NumberFormatException e) {
-                log.warn("Error while parsing timeinterval!", e);
+                log.warn("BHP: Error while parsing timeinterval!", e);
             }
 
             return true;
@@ -256,8 +257,10 @@
                 return true;
             }
             catch (NumberFormatException e) {
-                log.warn("Error while parsing sounding width!", e);
+                log.warn("BHP: Error while parsing sounding width: " + line, e);
+                log.warn("-> Set default value '0'");
             }
+            obj.setSoundingWidth(0);
         }
 
         return false;
@@ -314,7 +317,7 @@
                 return true;
             }
             catch (ParseException e) {
-                log.warn("Error while parsing range!", e);
+                log.warn("BHP: Error while parsing range!", e);
             }
         }
 
@@ -328,11 +331,15 @@
         if (m.matches()) {
             String tmp = m.group(1).replace(";", "");
 
-            obj.setType(new ImportBedHeightType(
-                BedHeightType.getBedHeightName(tmp),
-                tmp));
+            String name = BedHeightType.getBedHeightName(tmp);
 
-            return true;
+            if (name != null) {
+                obj.setType(new ImportBedHeightType(name, tmp));
+                return true;
+            }
+            else {
+                log.warn("Unknown bed height type: '" + tmp + "'");
+            }
         }
 
         return false;
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/BedHeightSingleParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/BedHeightSingleParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,13 +1,9 @@
 package de.intevation.flys.importer.parsers;
 
-
 import java.math.BigDecimal;
 
 import java.text.ParseException;
 
-
-
-
 import org.apache.log4j.Logger;
 
 import de.intevation.flys.importer.ImportBedHeight;
@@ -29,19 +25,53 @@
 
 
 
+    /**
+     * Create ImportBedHeightSingleValue from a line of csv file, add
+     * it to the ImportBedHeight.
+     */
     @Override
     protected void handleDataLine(ImportBedHeight obj, String line) {
         String[] values = line.split(SEPERATOR_CHAR);
 
-        if (values == null || values.length < 6) {
-            //log.warn("Error while parsing data line: '" + line + "'");
+        if (values == null || (values.length != 1 && values.length < 6)) {
+            //log.warn("BSP: Error while parsing data line: '" + line + "'");
+            return;
+        }
+
+        BigDecimal km;
+
+        try {
+            km = new BigDecimal(nf.parse(values[0]).doubleValue());
+        }
+        catch (ParseException e) {
+            // We expect a lot of ";;;;;;" lines.
+            //log.warn("BSP: Error while parsing km of data row.", e);
+            return;
+        }
+
+        // Handle gaps like "10,0;;;;;".
+        if (values.length == 1) {
+            ImportBedHeightSingleValue value = new ImportBedHeightSingleValue(
+                (ImportBedHeightSingle) obj,
+                km,
+                null, null, null, null, null);
+            obj.addValue(value);
+            return;
+        }
+
+        // Because we cannot enforce consistency of values with complete data
+        // via null constraints in the database (as there are "gap" values),
+        // do this checks manually.
+        if (values[3].length() == 0 || values[4].length() == 0
+            || values[5].length() == 0) {
+            //log.warn("BSP: Error while parsing data row (manual null constraint violated).");
             return;
         }
 
         try {
             ImportBedHeightSingleValue value = new ImportBedHeightSingleValue(
                 (ImportBedHeightSingle) obj,
-                new BigDecimal(nf.parse(values[0]).doubleValue()),
+                km,
                 new BigDecimal(nf.parse(values[1]).doubleValue()),
                 new BigDecimal(nf.parse(values[2]).doubleValue()),
                 new BigDecimal(nf.parse(values[3]).doubleValue()),
@@ -52,7 +82,7 @@
             obj.addValue(value);
         }
         catch (ParseException e) {
-            log.warn("Error while parsing data row.", e);
+            log.warn("BSP: Error while parsing data row.", e);
         }
     }
 }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/HYKParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/HYKParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -124,7 +124,7 @@
                 switch (state) {
                     case LINE_1:
                         if (parts.length < 2) {
-                            log.error("1: not enough elements in line " +
+                            log.error("HYK 1: not enough elements in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -163,7 +163,7 @@
 
                     case LINE_2:
                         if (parts.length < 3) {
-                            log.error("2: not enough elements in line " +
+                            log.error("HYK 2: not enough elements in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -174,7 +174,7 @@
                         }
                         catch (NumberFormatException nfe) {
                             log.error(
-                                "parsing num zones, bottom or top height " +
+                                "HYK: parsing num zones, bottom or top height " +
                                 "failed in line " + in.getLineNumber());
                             return false;
                         }
@@ -189,7 +189,7 @@
                     case LINE_3:
                         if (parts.length != numZones) {
                             log.error(
-                                "number of flow zones mismatches " +
+                                "HYK: number of flow zones mismatches " +
                                 "in line " + in.getLineNumber());
                             return false;
                         }
@@ -211,7 +211,7 @@
                             }
                         }
                         catch (NumberFormatException nfe) {
-                            log.error("cannot parse number in line " +
+                            log.error("HYK: cannot parse number in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -220,7 +220,7 @@
 
                     case LINE_5:
                         if (parts.length + coordPos < coords.length) {
-                            log.error("5: not enough elements in line " +
+                            log.error("HYK 5: not enough elements in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -233,7 +233,7 @@
                             }
                         }
                         catch (NumberFormatException nfe) {
-                            log.error("cannot parse number in line " +
+                            log.error("HYK: cannot parse number in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -241,7 +241,7 @@
                             BigDecimal a = coords[i];
                             BigDecimal b = coords[i == coords.length-1 ? i : i+1];
                             if (a.compareTo(b) > 0) {
-                                log.warn("zone coordinates swapped in line " +
+                                log.warn("HYK: zone coordinates swapped in line " +
                                     in.getLineNumber());
                                 BigDecimal c = a; a = b; b = c;
                             }
@@ -254,7 +254,7 @@
 
                     case LINE_6:
                         if (parts.length < 3) {
-                            log.error("6: not enough elements in line " +
+                            log.error("HYK 6: not enough elements in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -264,7 +264,7 @@
                             distanceVR = new BigDecimal(parts[2]);
                         }
                         catch (NumberFormatException nfe) {
-                            log.error("cannot parse number in line " +
+                            log.error("HYK: cannot parse number in line " +
                                 in.getLineNumber());
                             return false;
                         }
@@ -281,7 +281,7 @@
             }
         }
         catch (IOException ioe) {
-            log.error(ioe);
+            log.error("HYK: Error reading file.", ioe);
             return false;
         }
         finally {
@@ -290,7 +290,7 @@
                     in.close();
                 }
                 catch (IOException ioe) {
-                    log.error(ioe);
+                    log.error("HYK: Error closing file.", ioe);
                 }
             }
         }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/MorphologicalWidthParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/MorphologicalWidthParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -70,7 +70,7 @@
             return;
         }
         else {
-            log.warn("Unknown meta line: '" + line + "'");
+            log.warn("MWP: Unknown meta line: '" + line + "'");
         }
     }
 
@@ -94,7 +94,7 @@
         String[] vals = line.split(SEPERATOR_CHAR);
 
         if (vals == null || vals.length < 2) {
-            log.warn("skip invalid data line: '" + line + "'");
+            log.warn("MWP: skip invalid data line: '" + line + "'");
             return;
         }
 
@@ -111,7 +111,7 @@
             ));
         }
         catch (ParseException pe) {
-            log.warn("Error while parsing numbers in '" + line + "'");
+            log.warn("MWP: Error while parsing numbers in '" + line + "'");
         }
     }
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/PRFParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/PRFParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -234,7 +234,7 @@
     public boolean parse(File file) {
 
         if (!(file.isFile() && file.canRead())) {
-            log.warn("cannot open file '" + file + "'");
+            log.warn("PRF: cannot open file '" + file + "'");
             return false;
         }
 
@@ -267,14 +267,14 @@
             String line = in.readLine();
 
             if (line == null || (line = line.trim()).length() == 0) {
-                log.warn("file is empty.");
+                log.warn("PRF: file is empty.");
                 return false;
             }
 
             Matcher m = DATA_PATTERN.matcher(line);
 
             if (!m.matches()) {
-                log.warn("First line does not look like a PRF data pattern.");
+                log.warn("PRF: First line does not look like a PRF data pattern.");
                 return false;
             }
 
@@ -282,25 +282,25 @@
 
             if ((line = in.readLine()) == null
             || (line = line.trim()).length() == 0) {
-                log.warn("premature EOF. Expected integer in line 2");
+                log.warn("PRF: premature EOF. Expected integer in line 2");
                 return false;
             }
 
             try {
                 if (Integer.parseInt(line) != dataFormat.maxRepetitions) {
-                    log.warn("Expected " +
+                    log.warn("PRF: Expected " +
                         dataFormat.maxRepetitions + " in line 2");
                     return false;
                 }
             }
             catch (NumberFormatException nfe) {
-                log.warn("invalid integer in line 2", nfe);
+                log.warn("PRF: invalid integer in line 2", nfe);
                 return false;
             }
 
             if ((line = in.readLine()) == null) {
                 log.warn(
-                    "premature EOF. Expected pattern for km extraction");
+                    "PRF: premature EOF. Expected pattern for km extraction");
                 return false;
             }
 
@@ -308,7 +308,7 @@
 
             if (!m.matches()) {
                 log.warn(
-                    "line 4 does not look like a PRF km extraction pattern.");
+                    "PRF: line 4 does not look like a PRF km extraction pattern.");
                 return false;
             }
 
@@ -316,7 +316,7 @@
 
             if ((line = in.readLine()) == null
             || (line = line.trim()).length() == 0) {
-                log.warn("premature EOF. Expected skip row count.");
+                log.warn("PRF: premature EOF. Expected skip row count.");
                 return false;
             }
 
@@ -328,7 +328,7 @@
             }
             catch (NumberFormatException nfe) {
                 log.warn(
-                    "line 5 is not an positive integer.");
+                    "PRF: line 5 is not an positive integer.");
                 return false;
             }
 
@@ -344,7 +344,7 @@
                     km = kmFormat.extractKm(line);
                 }
                 catch (NumberFormatException iae) {
-                    log.warn("cannot extract km in line + " + in.getLineNumber());
+                    log.warn("PRF: cannot extract km in line " + in.getLineNumber());
                     return false;
                 }
 
@@ -368,7 +368,7 @@
             sortLists();
         }
         catch (IOException ioe) {
-            log.error(ioe);
+            log.error("Error reading PRF file.", ioe);
             return false;
         }
         finally {
@@ -377,7 +377,7 @@
                     in.close();
                 }
                 catch (IOException ioe) {
-                    log.error(ioe);
+                    log.error("Error closing PRF file.", ioe);
                 }
             }
         }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/PegelGltParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/PegelGltParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -57,7 +57,7 @@
 
                 int kmPos = line.indexOf(KM);
                 if (kmPos < 0) {
-                    log.warn("no gauge found in line " + in.getLineNumber());
+                    log.warn("GLT: no gauge found in line " + in.getLineNumber());
                     continue;
                 }
 
@@ -68,8 +68,8 @@
 
                 String [] parts = line.split("\\s+");
                 if (parts.length < 4) {
-                    log.warn("line " + in.getLineNumber()
-                        + " has not enough columns");
+                    log.warn("GLT: line " + in.getLineNumber()
+                        + " has not enough columns.");
                     continue;
                 }
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/SedimentDensityParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/SedimentDensityParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -118,6 +118,8 @@
             String up   = m.group(2);
             String unit = m.group(4);
 
+            log.info("Found sediment density depth: " + lo + " - " + up + " " + unit);
+
             try {
                 ImportDepth depth = new ImportDepth(
                     new BigDecimal(nf.parse(lo).doubleValue()),
@@ -133,6 +135,9 @@
                 log.warn("Error while parsing numbers in: '" + line + "'");
             }
         }
+        else {
+            log.debug("Meta line doesn't contain depth information: " + line);
+        }
 
         return false;
     }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/SedimentYieldParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/SedimentYieldParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -50,6 +50,9 @@
     public static final String FRACTION_SUSPENDED_SEDIMENT =
         "_Schwebstoff.csv";
 
+    public static final String FRACTION_TOTAL =
+        "_gesamt.csv";
+
 
     public static final Pattern TIMEINTERVAL_SINGLE =
         Pattern.compile("\\D*([0-9]+?)\\D*");
@@ -144,7 +147,7 @@
             return;
         }
         else {
-            log.warn("Unknown meta line: '" + line + "'");
+            log.warn("SYP: Unknown meta line: '" + line + "'");
         }
     }
 
@@ -204,7 +207,7 @@
         String[] vals = line.split(SEPERATOR_CHAR);
 
         if (vals == null || vals.length < columnNames.length-1) {
-            log.warn("skip invalid data line: '" + line + "'");
+            log.warn("SYP: skip invalid data line: '" + line + "'");
             return;
         }
 
@@ -222,7 +225,7 @@
             }
         }
         catch (ParseException pe) {
-            log.warn("Error while parsing numbers in '" + line + "':", pe);
+            log.warn("SYP: Error while parsing numbers in '" + line + "':", pe);
         }
     }
 
@@ -260,10 +263,10 @@
                 return new ImportTimeInterval(getDateFromYear(year));
             }
 
-            log.warn("Unknown time interval string: '" + column + "'");
+            log.warn("SYP: Unknown time interval string: '" + column + "'");
         }
         catch (ParseException pe) {
-            log.warn("Error while parsing years: " + column, pe);
+            log.warn("SYP: Error while parsing years: " + column, pe);
         }
 
         return null;
@@ -292,7 +295,7 @@
                 );
             }
             catch (ParseException pe) {
-                log.warn("Error while parsing ranges of: '" + gfStr + "'");
+                log.warn("SYP: Error while parsing ranges of: '" + gfStr + "'");
             }
         }
 
@@ -316,7 +319,7 @@
                 );
             }
             catch (ParseException pe) {
-                log.warn("Error while parsing ranges of: '" + gfStr + "'");
+                log.warn("SYP: Error while parsing ranges of: '" + gfStr + "'");
             }
         }
 
@@ -347,11 +350,11 @@
                 }
             }
             catch (ParseException pe) {
-                log.warn("Error while parsing ranges of: '" + gfStr + "'");
+                log.warn("SYP: Error while parsing ranges of: '" + gfStr + "'");
             }
         }
 
-        log.warn("Unknow grain fraction: '" + gfStr + "'");
+        log.warn("SYP: Unknow grain fraction: '" + gfStr + "'");
 
         return null;
     }
@@ -376,8 +379,11 @@
         else if (filename.endsWith(FRACTION_SUSPENDED_SEDIMENT)) {
             return GrainFraction.SUSPENDED_SEDIMENT;
         }
+        else if (filename.endsWith(FRACTION_TOTAL)) {
+            return GrainFraction.TOTAL;
+        }
         else {
-            log.warn("Unknown grain fraction type: '" + filename + "'");
+            log.warn("SYP: Unknown grain fraction '" + filename + "'");
             return "unknown";
         }
     }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/StaFileParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/StaFileParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -60,7 +60,7 @@
             }
 
             if (line.length() < 37) {
-                log.warn("first line in STA file is too short.");
+                log.warn("First line in STA file is too short.");
                 return false;
             }
 
@@ -75,7 +75,7 @@
                     gaugeNumber = Long.parseLong(gaugeNumberString);
                 }
                 catch (NumberFormatException nfe) {
-                    log.warn("'" + gaugeNumberString +
+                    log.warn("STA: '" + gaugeNumberString +
                         "' is not a valid long number.");
                 }
             }
@@ -91,14 +91,14 @@
             String [] values = line.substring(38).trim().split("\\s+", 2);
 
             if (values.length < 2) {
-                log.warn("Not enough columns for aeo and datum");
+                log.warn("STA: Not enough columns for aeo and datum.");
             }
             try {
                 gauge.setAeo(new BigDecimal(values[0].replace(",", ".")));
                 gauge.setDatum(new BigDecimal(values[1].replace(",", ".")));
             }
             catch (NumberFormatException nfe) {
-                log.warn("cannot parse aeo or datum");
+                log.warn("STA: cannot parse aeo or datum.");
                 return false;
             }
 
@@ -110,7 +110,7 @@
             }
 
             if (line.length() < 36) {
-                log.warn("second line is too short");
+                log.warn("STA: second line is too short");
                 return false;
             }
 
@@ -119,7 +119,7 @@
                     new BigDecimal(line.substring(29, 36).trim()));
             }
             catch (NumberFormatException nfe) {
-                log.warn("parsing of the datum of the gauge failed");
+                log.warn("STA: parsing of the datum of the gauge failed");
                 return false;
             }
 
@@ -148,7 +148,7 @@
                         value = new BigDecimal(m.group(2).replace(",", "."));
                     }
                     catch (NumberFormatException nfe) {
-                        log.warn("value not parseable in line "
+                        log.warn("STA: value not parseable in line "
                             + in.getLineNumber());
                         continue;
                     }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/WaterlevelDifferencesParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/WaterlevelDifferencesParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -153,7 +153,14 @@
             Double station = nf.parse(cols[0]).doubleValue();
 
             for (int i = 0; i < columns.length; i++) {
-                String value = cols[i+1];
+                int idx = i+1;
+
+                if (idx >= cols.length) {
+                    log.warn("Insufficient column numbers: " + line);
+                    continue;
+                }
+
+                String value = cols[idx];
 
                 try {
                     columns[i].addValue(new ImportWaterlevelDifferenceValue(
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/WstParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/WstParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -132,7 +132,7 @@
                         lsBezeichner = new String[columnCount];
                     }
                     catch (NumberFormatException nfe) {
-                        log.warn(nfe);
+                        log.warn("WST: invalid number.", nfe);
                         continue;
                     }
                     first = false;
@@ -267,7 +267,7 @@
 
                     if (!kms.add(kaem)) {
                         log.warn(
-                            "km " + kaem +
+                            "WST: km " + kaem +
                             " (line " + in.getLineNumber() +
                             ") found more than once. -> ignored");
                         continue;
--- a/flys-backend/src/main/java/de/intevation/flys/model/BedHeightEpoch.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/BedHeightEpoch.java	Fri Sep 28 12:15:40 2012 +0200
@@ -180,8 +180,7 @@
         List<BedHeightEpoch> epochs = query.list();
         List<BedHeightEpoch> good   = new ArrayList<BedHeightEpoch>();
 
-        for (BedHeightEpoch e: epochs) {
-            OUTER:
+        OUTER: for (BedHeightEpoch e: epochs) {
             for (BedHeightEpochValue value: e.getValues()) {
                 double station = value.getStation().doubleValue();
 
--- a/flys-backend/src/main/java/de/intevation/flys/model/BedHeightSingle.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/BedHeightSingle.java	Fri Sep 28 12:15:40 2012 +0200
@@ -242,13 +242,12 @@
         List<BedHeightSingle> good    = new ArrayList<BedHeightSingle>();
 
         for (BedHeightSingle s: singles) {
-            OUTER:
             for (BedHeightSingleValue value: s.getValues()) {
                 double station = value.getStation().doubleValue();
 
                 if (station >= kmLo && station <= kmHi) {
                     good.add(s);
-                    continue OUTER;
+                    break;
                 }
             }
         }
--- a/flys-backend/src/main/java/de/intevation/flys/model/BedHeightType.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/BedHeightType.java	Fri Sep 28 12:15:40 2012 +0200
@@ -76,6 +76,9 @@
         else if ("Querprofile".equals(description)) {
             return "QP";
         }
+        else if ("Querprofil".equals(description)) {
+            return "QP";
+        }
         else if ("TIN".equals(description)) {
             return "TIN";
         }
--- a/flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java	Fri Sep 28 12:15:40 2012 +0200
@@ -32,7 +32,7 @@
     public static final double EPSILON   = 1e-4;
 
     public static final double TOO_SMALL = 0.2;
-    public static final double TOO_BIG   = 500;
+    public static final double TOO_BIG   = 2500;
 
     private Integer                 id;
     private Double              km;
--- a/flys-backend/src/main/java/de/intevation/flys/model/FastAnnotations.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/FastAnnotations.java	Fri Sep 28 12:15:40 2012 +0200
@@ -134,6 +134,14 @@
         public double getBottom() {
             return bottom;
         }
+
+        @Override
+        public String toString() {
+            return "[a=" + a + ";b=" + b +
+                ";pos=" + position + ";attr=" + attribute +
+                ";name=" + name + ";top=" + top +
+                ";bot=" + bottom + "]";
+        }
     } // class Annotation
 
     public interface Filter {
--- a/flys-backend/src/main/java/de/intevation/flys/model/Gauge.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/Gauge.java	Fri Sep 28 12:15:40 2012 +0200
@@ -241,5 +241,89 @@
 
         return null;
     }
+
+    /**
+     * Returns an array of [days, qs] necessary to create duration curves.
+     *
+     * @return a 2dim array of [days, qs] where days is an int[] and qs is
+     * an double[].
+     */
+    public Object[] fetchDurationCurveData() {
+        Session session = SessionHolder.HOLDER.get();
+
+        Query query = session.createQuery(
+            "select cast(nmv.name as integer) as days, mv.value as q " +
+            "from MainValue as mv " +
+            "join mv.mainValue as nmv " +
+            "join nmv.type mvt " +
+            "where mvt.name = 'D' and mv.gauge.id = :gauge_id " +
+            "order by days");
+
+        query.setParameter("gauge_id", getId());
+
+        List<Object> results = query.list();
+        int[]        days    = new int[results.size()];
+        double[]     qs      = new double[results.size()];
+
+        int idx = 0;
+
+        for (Object obj: results) {
+            Object[] arr = (Object[]) obj;
+
+            try {
+                int  day = ((Integer)    arr[0]).intValue();
+                double q = ((BigDecimal) arr[1]).doubleValue();
+
+                days[idx] = day;
+                qs[idx++] = q;
+            }
+            catch (NumberFormatException nfe) {
+            }
+        }
+
+        return new Object[] { days, qs };
+    }
+
+    /**
+     * Calculates the maximum and minimum W and Q values
+     *
+     * @return the MaxMinWQ object representing the calculated values
+     */
+    public MinMaxWQ fetchMaxMinWQ() {
+        Session session = SessionHolder.HOLDER.get();
+
+        Query query = session.createQuery(
+            "select max(mv.value) as max, min(mv.value) as min " +
+            "from MainValue as mv " +
+            "join mv.mainValue as nmv " +
+            "join nmv.type mvt " +
+            "where mvt.name in ('W', 'Q') " +
+            "and mv.gauge.id = :gauge_id " +
+            "group by mvt.name order by mvt.name"
+            );
+
+        query.setParameter("gauge_id", getId());
+
+        List<Object> results = query.list();
+        if (results.isEmpty()) {
+            // No values found
+            return new MinMaxWQ();
+        }
+
+        Object[] arr = (Object[]) results.get(0);
+        BigDecimal maxw = (BigDecimal)arr[0];
+        BigDecimal minw = (BigDecimal)arr[1];
+        BigDecimal maxq = null;
+        BigDecimal minq = null;
+
+
+        if (results.size() > 1) {
+            arr = (Object[]) results.get(1);
+            maxq = (BigDecimal)arr[0];
+            minq = (BigDecimal)arr[1];
+        }
+
+        return new MinMaxWQ(minw, maxw, minq, maxq);
+    }
 }
 // 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-backend/src/main/java/de/intevation/flys/model/MinMaxWQ.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,58 @@
+package de.intevation.flys.model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * Represents minmimum and maximum values for W and Q
+ */
+public class MinMaxWQ implements Serializable {
+
+    private BigDecimal minw;
+    private BigDecimal maxw;
+    private BigDecimal minq;
+    private BigDecimal maxq;
+
+    /**
+     * Default constuctor to indecate that no min and max w and q values
+     * are available
+     */
+    public MinMaxWQ() {
+    }
+
+    /**
+     * Constructor for a new MinMaxWQ value
+     *
+     * @param minw Mimimim W
+     * @param maxw Maximum W
+     * @param minq Mimimim Q
+     * @param maxq Maximum Q
+     */
+    public MinMaxWQ(
+            BigDecimal minw,
+            BigDecimal maxw,
+            BigDecimal minq,
+            BigDecimal maxq)
+    {
+        this.minw = minw;
+        this.maxw = maxw;
+        this.minq = minq;
+        this.maxq = maxq;
+    }
+
+    public BigDecimal getMinW() {
+        return this.minw;
+    }
+
+    public BigDecimal getMaxW() {
+        return this.maxw;
+    }
+
+    public BigDecimal getMinQ() {
+        return this.minq;
+    }
+
+    public BigDecimal getMaxQ() {
+        return this.maxq;
+    }
+}
--- a/flys-backend/src/main/java/de/intevation/flys/model/River.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/River.java	Fri Sep 28 12:15:40 2012 +0200
@@ -48,6 +48,8 @@
 
     private Integer id;
 
+    private Long    officialNumber;
+
     private String  name;
 
     private boolean kmUp;
@@ -73,6 +75,15 @@
         this.id = id;
     }
 
+    @Column(name = "official_number")
+    public Long getOfficialNumber() {
+        return officialNumber;
+    }
+
+    public void setOfficialNumber(Long officialNumber) {
+        this.officialNumber = officialNumber;
+    }
+
     @Column(name = "name")
     public String getName() {
         return name;
@@ -220,6 +231,34 @@
         return gauges.isEmpty() ? null : gauges.get(0);
     }
 
+    public double[] determineMinMaxQ() {
+        Session session = SessionHolder.HOLDER.get();
+
+        Query query = session.createQuery(
+            "select min(wqr.q) as min, max(wqr.q) as max " +
+            "from Wst as w " +
+            "join w.columns as wc " +
+            "join wc.columnQRanges as wcqr " +
+            "join wcqr.wstQRange as wqr " +
+            "where w.kind = 0 and river_id = :river");
+
+        query.setParameter("river", getId());
+
+        double minmax[] = new double[] { Double.MAX_VALUE, Double.MIN_VALUE };
+
+        List<Object> results = query.list();
+
+        if (!results.isEmpty()) {
+            Object[] arr = (Object[]) results.get(0);
+            BigDecimal minq = (BigDecimal)arr[0];
+            BigDecimal maxq = (BigDecimal)arr[1];
+            minmax[0] = minq.doubleValue();
+            minmax[1] = maxq.doubleValue();
+        }
+
+        return minmax;
+    }
+
 
     /**
      * This method returns the first gauge that is intersected by <i>a</i> and
@@ -288,5 +327,6 @@
 
         return result;
     }
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-backend/src/main/java/de/intevation/flys/model/RiverAxis.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/model/RiverAxis.java	Fri Sep 28 12:15:40 2012 +0200
@@ -35,6 +35,11 @@
     private Integer    kind;
     private River      river;
     private LineString geom;
+    
+    public static final int DEFAULT_KIND = 0;
+    
+    public static final int KIND_OFFICIAL = 1;
+    public static final int KIND_OUTSOURCED = 2;
 
     public RiverAxis() {
     }
@@ -88,11 +93,16 @@
 
 
     public static List<RiverAxis> getRiverAxis(String river) {
+        return getRiverAxis(river, DEFAULT_KIND);
+    }
+    
+    public static List<RiverAxis> getRiverAxis(String river, int kind) {
         Session session = SessionHolder.HOLDER.get();
 
         Query query = session.createQuery(
-            "from RiverAxis where river.name =:river");
+            "from RiverAxis where river.name =:river AND kind =:kind");
         query.setParameter("river", river);
+        query.setParameter("kind", kind);
 
         List<RiverAxis> list = query.list();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/utils/DgmSqlConverter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,483 @@
+package de.intevation.flys.utils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+import au.com.bytecode.opencsv.CSVReader;
+
+
+/**
+ * A converter for CSV files with DGM information. The result of a conversion
+ * is an SQL file with "INSERT INTO dem ..." statements.
+ * <br>
+ * To start the converter, at least the following three system properties are
+ * required:
+ * <br>
+ * <ul>
+ * <ol><b>gew.dir</b>: This property must point to the directory where all
+ * rivers are stored.</ol>
+ * <ol><b>csv</b>: This property must point to the CSV file that contains the
+ * DGM information.</ol>
+ * <ol><b>sql</b>: This property must point to a (not yet existing) file that
+ * will be generated by this converter.</ol>
+ * </ul>
+ * <br>
+ * In addiation, the following properties are accepted to modify log messages,
+ * etc.
+ * <ul>
+ * <ol><b>verbose</b>: Accepts integer values (0, 1, 2, 3) to modify the log
+ * messages. The higher the value the more log messages are printed to STDOUT.
+ * </ol>
+ * <ol><b>full</b>: Accepts true|false values. If true is set, all rivers
+ * included in the CSV file are taken into account while parsing. Otherwise,
+ * the converter reads information for 'Saar', 'Mosel' and 'Eble' only.</ol>
+ * </ul>
+ *
+ * @author Ingo Weinzierl <a href="mailto:ingo.weinzierl@intevation.de">
+ * ingo.weinzierl@intevation.de</a>
+ *
+ */
+public class DgmSqlConverter {
+
+    public static final String SQL_INSERT = "INSERT INTO dem (river_id, name, lower, upper, year_from, year_to,"
+        + "projection, elevation_state, format, border_break, resolution, description, path) VALUES ("
+        + "%s, '%s', %s, %s, %s, %s, '%s', '%s', '%s', %s, '%s', '%s', '%s');";
+
+    public static final String SQL_SELECT_RIVER = "(SELECT id from rivers WHERE name = '%s')";
+
+    public static final char DEFAULT_SEPERATOR = ',';
+    public static final char DEFAULT_QUOTE = '"';
+    public static final int DEFAULT_LOG_LEVEL = 2;
+
+    public static final boolean FULL_MODE = Boolean.getBoolean("full");
+    public static final String GEW_DIR = System.getProperty("gew.dir", null);
+    public static final String CSV_FILE = System.getProperty("csv");
+    public static final String SQL_FILE = System.getProperty("sql");
+    public static final int LOG_LEVEL = Integer.getInteger("verbose",
+        DEFAULT_LOG_LEVEL);
+
+    public static final int MIN_COLUMN_COUNT = 15;
+
+    public static final int IDX_RIVERNAME = 0;
+    public static final int IDX_NAME = 12;
+    public static final int IDX_LOWER = 1;
+    public static final int IDX_UPPER = 2;
+    public static final int IDX_YEAR_FROM = 3;
+    public static final int IDX_YEAR_TO = 4;
+    public static final int IDX_PROJECTION = 7;
+    public static final int IDX_ELEVATION_STATE = 8;
+    public static final int IDX_FORMAT = 9;
+    public static final int IDX_BORDER_BREAK = 10;
+    public static final int IDX_RESOLUTION = 11;
+    public static final int IDX_DESCRIPTION = 14;
+    public static final int IDX_FILE_NAME = 5;
+    public static final int IDX_FILE_PATH = 6;
+
+    private class DGM {
+
+        public String river;
+        public String name;
+        public String projection;
+        public String elevationState;
+        public String format;
+        public String resolution;
+        public String description;
+        public String path;
+
+        public double lower;
+        public double upper;
+        public Integer yearFrom;
+        public Integer yearTo;
+
+        public boolean borderBreak;
+
+        public DGM() {
+            borderBreak = false;
+        }
+
+        public String toSQL() {
+            String riverId = String.format(SQL_SELECT_RIVER, river);
+            String lower = String.valueOf(this.lower);
+            String upper = String.valueOf(this.upper);
+            String yearFrom = this.yearFrom != null ? String
+                .valueOf(this.yearFrom) : "";
+            String yearTo = this.yearTo != null ? String.valueOf(this.yearTo)
+                : "";
+
+            return String.format(SQL_INSERT, riverId, name, lower, upper,
+                yearFrom, yearTo, projection, elevationState, format,
+                borderBreak, resolution, description, path);
+        }
+    }
+
+    private File riverDir;
+    private File csv;
+    private File sql;
+
+    private List<DGM> dgms;
+
+    public static void debug(String msg) {
+        if (LOG_LEVEL >= 3) {
+            System.out.println("DEBUG: " + msg);
+        }
+    }
+
+    public static void info(String msg) {
+        if (LOG_LEVEL >= 2) {
+            System.out.println("INFO: " + msg);
+        }
+    }
+
+    public static void warn(String msg) {
+        if (LOG_LEVEL >= 1) {
+            System.out.println("WARN: " + msg);
+        }
+    }
+
+    public static void error(String msg) {
+        System.out.println("ERROR: " + msg);
+    }
+
+    public static File getRiverDir(String[] args) {
+        if (GEW_DIR != null && GEW_DIR.length() > 0) {
+            return new File(GEW_DIR);
+        }
+        else if (args != null && args.length > 0) {
+            return new File(args[0]);
+        }
+
+        return null;
+    }
+
+    public static File getCSVFile(String[] args) {
+        if (CSV_FILE != null && CSV_FILE.length() > 0) {
+            return new File(CSV_FILE);
+        }
+        else if (args != null && args.length > 1) {
+            return new File(args[1]);
+        }
+
+        return null;
+    }
+
+    public static File getSQLFile(String[] args) {
+        if (SQL_FILE != null && SQL_FILE.length() > 0) {
+            return new File(SQL_FILE);
+        }
+        else if (args != null && args.length > 2) {
+            return new File(args[2]);
+        }
+
+        return null;
+    }
+
+    public static void main(String[] args) {
+        info("Start convering CSV -> SQL statements");
+
+        if (!FULL_MODE) {
+            info("You are running in DEMO mode; other rivers than 'Saar', 'Mosel' and 'Elbe' are ignored.");
+        }
+
+        File riverDir = getRiverDir(args);
+
+        if (riverDir == null) {
+            warn("No rivers directory specified!");
+            return;
+        }
+        else if (!riverDir.isDirectory()) {
+            warn("Specified rivers directory is not a directory!");
+            return;
+        }
+        else if (!riverDir.canRead()) {
+            warn("Unable to read '" + riverDir.toString() + "'");
+            return;
+        }
+
+        File csv = getCSVFile(args);
+
+        if (csv == null) {
+            warn("No CSV file specified!");
+            return;
+        }
+        else if (csv.isDirectory()) {
+            warn("Specified CSV file is a directory!");
+            return;
+        }
+        else if (!csv.canRead()) {
+            warn("Unable to read '" + csv.toString() + "'");
+            return;
+        }
+
+        File sql = getSQLFile(args);
+
+        if (sql == null) {
+            warn("No destination file specified!");
+            return;
+        }
+        else if (sql.isDirectory()) {
+            warn("Specified destination file is a directory!");
+            return;
+        }
+        else if (sql.exists() && !sql.canWrite()) {
+            warn("Unable to write to '" + sql.toString() + "'");
+            return;
+        }
+        else if (!sql.exists()) {
+            try {
+                sql.createNewFile();
+            }
+            catch (IOException ioe) {
+                warn("Unable to write to '" + sql.toString() + "'");
+                return;
+            }
+        }
+
+        info("Start parsing CSV file '" + csv.toString() + "'");
+
+        try {
+            DgmSqlConverter parser = new DgmSqlConverter(riverDir, csv, sql);
+            parser.read();
+            parser.write();
+        }
+        catch (Exception e) {
+            error("Unexpected error: " + e.getMessage());
+            e.printStackTrace();
+        }
+
+        info("Finished converting CSV -> SQL regularly.");
+    }
+
+    public DgmSqlConverter(File riverDir, File csv, File sql) {
+        this.riverDir = riverDir;
+        this.csv = csv;
+        this.sql = sql;
+        this.dgms = new ArrayList<DGM>();
+    }
+
+    public void read() {
+        info("Read DGM information from CSV file: " + csv.getAbsolutePath());
+
+        InputStream in = null;
+
+        try {
+            in = new BufferedInputStream(new FileInputStream(csv));
+        }
+        catch (FileNotFoundException e) {
+            error("File not found: " + e.getMessage());
+            return;
+        }
+
+        Reader reader = new InputStreamReader(in);
+        CSVReader csvReader = new CSVReader(reader, DEFAULT_SEPERATOR,
+            DEFAULT_QUOTE);
+
+        List<String[]> rows = new ArrayList<String[]>();
+
+        int success = 0;
+
+        try {
+            rows = csvReader.readAll();
+
+            for (int idx = 0; idx < rows.size(); idx++) {
+                String[] row = rows.get(idx);
+                if (readRow(row)) {
+                    success++;
+                }
+                else {
+                    warn("Unable to parse row " + (idx + 1));
+                }
+            }
+        }
+        catch (IOException e) {
+            error("Error while parsing CSV: " + e.getMessage());
+            return;
+        }
+
+        info("Parsed CSV file: " + rows.size() + " lines.");
+        info("Parsed " + success + " line successful");
+    }
+
+    private boolean readRow(String[] row) {
+        if (row == null) {
+            warn("Row is null!");
+            return false;
+        }
+
+        if (row.length < MIN_COLUMN_COUNT) {
+            warn("invalid column count: " + row.length);
+            return false;
+        }
+
+        StringBuffer rowBuffer = new StringBuffer();
+        for (String col : row) {
+            rowBuffer.append(col);
+            rowBuffer.append(" | ");
+        }
+        debug(rowBuffer.toString());
+
+        try {
+            DGM dgm = new DGM();
+            dgm.river = readRiver(row[IDX_RIVERNAME]);
+            dgm.name = row[IDX_NAME];
+            dgm.projection = row[IDX_PROJECTION];
+            dgm.elevationState = row[IDX_ELEVATION_STATE];
+            dgm.format = row[IDX_FORMAT];
+            dgm.resolution = row[IDX_RESOLUTION];
+            dgm.description = row[IDX_DESCRIPTION];
+            dgm.lower = readLower(row[IDX_LOWER]);
+            dgm.upper = readUpper(row[IDX_UPPER]);
+            dgm.yearFrom = readFromYear(row[IDX_YEAR_FROM]);
+            dgm.yearTo = readToYear(row[IDX_YEAR_TO]);
+            dgm.borderBreak = readBorderBreak(row[IDX_BORDER_BREAK]);
+            dgm.path = readPath(dgm.river, row[IDX_FILE_PATH],
+                row[IDX_FILE_NAME]);
+
+            dgms.add(dgm);
+
+            return true;
+        }
+        catch (IllegalArgumentException iae) {
+            warn(iae.getMessage());
+        }
+
+        return false;
+    }
+
+    private String readRiver(String rivername) throws IllegalArgumentException {
+        if (rivername == null || rivername.length() == 0) {
+            throw new IllegalAccessError("Invalid rivername: " + rivername);
+        }
+
+        if (!FULL_MODE
+            && !(rivername.equals("Saar") || rivername.equals("Mosel") || rivername
+                .equals("Elbe"))) {
+            throw new IllegalArgumentException("In DEMO mode; skip river: "
+                + rivername);
+        }
+
+        return rivername;
+    }
+
+    private Double readLower(String lower) throws IllegalArgumentException {
+        try {
+            return Double.valueOf(lower);
+        }
+        catch (NumberFormatException nfe) {
+        }
+
+        throw new IllegalArgumentException("Attribute 'lower' invalid: "
+            + lower);
+    }
+
+    private Double readUpper(String upper) throws IllegalArgumentException {
+        try {
+            return Double.valueOf(upper);
+        }
+        catch (NumberFormatException nfe) {
+        }
+
+        throw new IllegalArgumentException("Attribute 'upper' invalid: "
+            + upper);
+    }
+
+    private Integer readFromYear(String from) throws IllegalArgumentException {
+        try {
+            return Integer.valueOf(from);
+        }
+        catch (NumberFormatException nfe) {
+        }
+
+        return null;
+    }
+
+    private Integer readToYear(String to) throws IllegalArgumentException {
+        try {
+            return Integer.valueOf(to);
+        }
+        catch (NumberFormatException nfe) {
+        }
+
+        return null;
+    }
+
+    private String readPath(String rivername, String dir, String filename)
+        throws IllegalArgumentException {
+        File riverDir = new File(this.riverDir, rivername);
+        File dgmDir = new File(riverDir, dir);
+        File dgmFile = new File(dgmDir, filename);
+
+        try {
+            debug("Path of DGM = " + dgmFile.getAbsolutePath());
+
+            if (dgmFile == null || !dgmFile.exists()) {
+                throw new IllegalAccessError(
+                    "Specified DGM file does not exist: "
+                        + dgmFile.getAbsolutePath());
+            }
+
+            if (!dgmFile.isFile()) {
+                throw new IllegalArgumentException(
+                    "Specified DGM file is no file: "
+                        + dgmFile.getAbsolutePath());
+            }
+        }
+        catch (IllegalAccessError iae) {
+            throw new IllegalArgumentException("Cannot find DGM file (river="
+                + rivername + " | directory=" + dir + " | filename=" + filename
+                + ")");
+        }
+
+        return dgmFile.getAbsolutePath();
+    }
+
+    private boolean readBorderBreak(String borderBreak) {
+        if (borderBreak == null || borderBreak.length() == 0) {
+            return true;
+        }
+        else if (borderBreak.toLowerCase().equals("ja")) {
+            return true;
+        }
+        else if (borderBreak.toLowerCase().equals("nein")) {
+            return false;
+        }
+        else {
+            return true;
+        }
+    }
+
+    public void write() {
+        info("Write DEM information to SQL file: " + sql.getAbsolutePath());
+
+        BufferedWriter bufferedWriter = null;
+        try {
+            bufferedWriter = new BufferedWriter(new FileWriter(sql));
+
+            for (DGM dgm : dgms) {
+                bufferedWriter.write(dgm.toSQL());
+                bufferedWriter.newLine();
+            }
+        }
+        catch (IOException ioe) {
+            error(ioe.getMessage());
+        }
+        finally {
+            if (bufferedWriter != null) {
+                try {
+                    bufferedWriter.close();
+                }
+                catch (IOException ioe) {
+                }
+            }
+        }
+    }
+}
--- a/flys-backend/src/main/java/de/intevation/flys/utils/StringUtil.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-backend/src/main/java/de/intevation/flys/utils/StringUtil.java	Fri Sep 28 12:15:40 2012 +0200
@@ -517,7 +517,7 @@
     }
 
     /**
-     * Gibt den Dateinamen in S ohne Dateiendung zurück.
+     * Returns the file name without extension.
      */
     public static final String cutExtension(String s) {
         if (s == null) {
--- a/flys-client/ChangeLog	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/ChangeLog	Fri Sep 28 12:15:40 2012 +0200
@@ -1,3 +1,1391 @@
+2012-09-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java,
+	  src/main/java/de/intevation/flys/client/server/ArtifactHelper.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeDischargeCurveArtifact.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactService.java,
+	  src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java,
+	  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.java,
+	  src/main/java/de/intevation/flys/client/client/FLYS.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java:
+	  Allow to create a discharge curve from a gauge info.
+	  Currently the dicharge curve will not be displayed.
+
+2012-09-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java:
+	  Add river name to the GaugeInfo
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Work on issue724 (i18n in minfo).
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties:
+	  Translate data export.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/ModuleServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixationPanel.java:
+	  Cosmetics, docs.
+
+2012-09-27	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java,
+	  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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Donate own error message when no users were found.
+
+2012-09-27	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DoubleProperty.java,
+	  src/main/java/de/intevation/flys/client/shared/model/PropertySetting.java,
+	  src/main/java/de/intevation/flys/client/shared/model/PropertyGroup.java:
+	  Add "Date" support for Manual Points editor (not finished yet).
+
+	* src/main/java/de/intevation/flys/client/shared/model/MapMode.java:
+	  Add comment.
+
+2012-09-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/MapMode.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterMatrix.java:
+	  Removed trailing whitespace.
+
+2012-09-27	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/webapp/WEB-INF/web.xml:
+	  Add servlet mapping for the GaugeOverviewInfoService
+
+2012-09-26  Ingo Weinzierl <ingo@intevation.de>
+
+	flys/issue897 (MissingResourceException: Cannot find constant '500 The call failed on the server; see server log for details')
+
+	* src/main/java/de/intevation/flys/client/shared/model/MapMode.java:
+	  Readded default constructor.
+
+2012-09-25	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixPeriodPanel.java:
+	  Default from and to dates are now shown with english locale, too (#854).
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java:
+	  Cosmetics.
+
+2012-09-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Improved fix for issue860 (minfo parameterization in helper pane).
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java
+	  (createWidget, createCheckBox): Renamed.
+	  Use smartgwt stuff to profit from scrollbars (yay!).
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java:
+	  Place ParameterMatrix in helper pane if too long.
+
+2012-09-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Attempt at issue860 (minfo parameterization in helper pane).
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java:
+	  Place ParameterMatrix in helper pane if too long.
+
+2012-09-24	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/widgets/KMSpinner.java:
+	  Issue #853:
+	  - Height is now normal again
+	  - "Junk" chars are now removed on change	
+
+2012-09-24	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	issue846 (GGInA: Auth mechanism ignores URL prefix)
+
+	* src/main/java/de/intevation/flys/client/server/LoginServlet.java,
+	  src/main/java/de/intevation/flys/client/server/GGInAFilter.java,
+	  src/main/webapp/login.jsp:
+	  Consider the Context Path variable when using urls in the GGInAFilter.
+
+2012-09-24	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	issue871 (parameterization of flowvelocity loo¿s a tiny bit messy).
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java:
+	  Show horizontal line between entries.
+
+2012-09-24	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RemoteServiceServlet.java,
+	  src/main/java/de/intevation/flys/client/shared/model/IntegerOptionsData.java:
+	  Cosmetics, docs.
+
+2012-09-24	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java:
+	  Finally store passed kmup value in member variable.
+
+2012-09-24	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultRiverInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/RiverInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java,
+	  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.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java:
+	  Use i18n to calculate the info urls for the gauge overview instead of
+	  fechting the urls from the artifact service.
+
+2012-09-22	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixFunctionSelect.java:
+	  Show full function instead of internal name (#873).
+
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added i18n strings for bedheight difference calculation.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java:
+	  Open fold for historicalq reference.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java:
+	  Add the official gauge number to the GaugeInfo class.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Refactor GaugeTree into its own java file. Due to the folding logic in the
+	  GaugeTree the code became quite lage. Therefore it is better preserved in
+	  its own file.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Additional refactoring to avoid code duplication and fixing reading double
+	  value from locations DataItem object. Also add another code path for
+	  location_distance winfo state.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Refactor to avoid code duplication
+
+2012-09-21	Björn Ricks	<bjoern.ricks@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.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Add html links to the additional gauge and river info pages.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultRiverInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/RiverInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java:
+	  Extend GaugeInfo and RiverInfo to store also the http url for additional
+	  info.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Open and close gauge tree folds that correspond to the selected WINFO
+	  calculation.
+
+2012-09-21	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java:
+	  Fix NullPointerException on not available list
+
+2012-09-20	Christian Lins	<christian.lins@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/ui/fixation/FixMultiPeriodPanel.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  i18n for FixMultiPeriodPanel (#872).
+
+2012-09-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Prevent AIOOB exception.
+
+2012-09-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Removed superfluous import.
+
+2012-09-19	Christian Lins	<christian.lins@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixGaugeSelectPanel.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  i18n (#858)
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Use the wstunit from the river as unit for the Pegelnullpunkt.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Don't display the GaugePanel if no river is selected.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java:
+	  Fix NullPointerException when going back in WINFO artifact to the river
+	  selection.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Add locale aware formatting of the gauge values.
+	  Don't reload the gauges if the river doesn't change.
+	  Correctly handle kmup of the river.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Improve handling of the GaugePanel and don't delete members of the
+	  GaugePanel.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java:
+	  Add station information to the gauges.
+
+2012-09-19	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/webapp/FLYS.css,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Get a working GaugeInfo solution with scrolling adjustments if gauge info
+	  elements are folded in an out.
+
+2012-09-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Removed trailing whitespace.
+
+2012-09-17  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged RELEASE 2.9.1
+
+2012-09-17  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.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added missing i18n strings for minfo state description.
+
+2012-09-16	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/widgets/KMSpinnerChangeListener.java (NEW),
+	  src/main/java/de/intevation/flys/client/client/widgets/KMSpinner.java (NEW),
+	  src/main/java/de/intevation/flys/client/client/ui/chart/CrossSectionChartThemePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java:
+	  Refactored some KMSpinner code. KMSpinner has now a human-readable size (#853).
+
+2012-09-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultRiverInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java,
+	  src/main/java/de/intevation/flys/client/client/services/GaugeOverviewInfoService.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Removed trailing whitespace and superfluous imports.
+
+2012-09-14	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java,
+	  src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java:
+	  Add first draft for the gauge overview info ui
+
+2012-09-14	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/GaugeOverviewInfoService.java,
+	  src/main/java/de/intevation/flys/client/client/services/GaugeOverviewInfoServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/RiverInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DefaultRiverInfo.java,
+	  src/main/java/de/intevation/flys/client/server/GaugeOverviewInfoServiceImpl.java:
+	  Implement a service to handle the gauge info
+
+2012-09-13	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/range/LocationsTable.java:
+	  Adding "from" and "to" in table columns with the green/red marker icons (#808).
+
+2012-09-13  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.properties:
+	  Translated german strings.
+
+2012-09-13  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.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added 'main_channel' and 'total_channel' strings.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java:
+	  Use the correct label for the UI.
+
+2012-09-13  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.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added strings for bed quality chart and export.
+
+2012-09-13	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Scrolling long Project lists is now more robust (#757), although
+	  the search box is now part of the scrolling pane.
+
+2012-09-13	Christian Lins	<christian.lins@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_en.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants.java:
+	  Adding string for error_no_modules_found (#855).
+
+2012-09-13	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java:
+	  Cosmetics.
+
+2012-09-12  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/minfo/BedCampaignChart.java,
+	  src/main/java/de/intevation/flys/client/client/ui/minfo/BedloadCampaignChart.java:
+	  New. Container for overview charts.
+
+	* src/main/java/de/intevation/flys/client/server/BedKMChartServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/BedloadKMChartServiceImpl.java:
+	  New. Services for overview charts.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterMatrix.java:
+	  Show i18n strings in column titles.
+
+	* src/main/java/de/intevation/flys/client/client/ui/minfo/BedMultiPeriodPanel.java:
+	  New. UI provider that allows multiple period input and displays the overview
+	  charts.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Added new ui provider.
+
+	* src/main/webapp/WEB-INF/web.xml:
+	  Added new services.
+
+	* 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:
+	  Added i18n strings.
+
+2012-09-12  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/StringOptionsData.java:
+	  Fixed constructor.
+
+2012-09-11	Christian Lins 	<christian.lins@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Fix for line label text in Delta W(t) chart (#837).
+
+2012-09-10	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java:
+	  Minimal fix for 'Transparency' combobox appearence (#840).
+
+2012-09-10	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* pom.xml: Java 1.5 -> 1.6
+
+2012-09-09	Christian Lins	<christian.lins@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Rename attribute 'alpha' to 'transparency' which now represents the 
+	  transparency percentage instead raw rgba alpha value. StyledEditorWindow
+	  can now handle this transparency attribute.
+
+2012-09-09	Christian Lins	<christian.lins@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Add 'error_update_collection_attribute' string (#843).
+
+2012-09-09	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java:
+	  Remove blank line.
+
+	* src/main/java/de/intevation/flys/client/client/FLYS.java:
+	  Catch MissingResourceException on unexpected server exceptions (#843).
+
+2012-09-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java:
+	  Reverted functional change from clins last commit.
+
+	* src/main/java/de/intevation/flys/client/server/LoginServlet.java,
+	  src/main/java/de/intevation/flys/client/server/auth/AuthenticationFactory.java,
+	  src/main/java/de/intevation/flys/client/server/auth/UserClient.java:
+	  Removed trailing whitespace.
+
+2012-09-08	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RemoteServiceServlet.java,
+	  src/main/java/de/intevation/flys/client/server/LoginServlet.java,
+	  src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java,
+	  src/main/java/de/intevation/flys/client/server/auth/AuthenticationFactory.java,
+	  src/main/java/de/intevation/flys/client/server/auth/UserClient.java,
+	  src/main/java/de/intevation/flys/client/client/FLYS.java:
+	  Cosmetics, add robustness checks etc.
+
+2012-09-07	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/auth/UserClient.java:
+	  Be more defensive about fetchimg users from session.
+
+2012-09-07	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Improved panning in TimeseriesCharts (issue715).
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java
+	  (computeZoom): Prevent confusion of scoped 'zoom' variable.
+	  (divide): Cast to double, we do not want long precision divisions.
+
+2012-09-07	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java,
+	  src/main/java/de/intevation/flys/client/client/FLYS.java,
+	  src/main/java/de/intevation/flys/client/client/ui/FLYSView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/MousePositionPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/OutputTab.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java,
+	  src/main/java/de/intevation/flys/client/client/ui/DatacagePairWidget.java:
+	  Cosmetics, docs.
+
+2012-09-04	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java:
+	  Refactor getCurrentUser to return the logged in user and not the first
+	  user from the artifact database.
+
+2012-09-04	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RemoteServiceServlet.java,
+	  src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/RemoteServiceServlet.java,
+	  src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java:
+	  Move RemoteServiceServlet to server package.
+
+2012-09-07  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged module as '2.9'.
+
+2012-09-04	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ThemePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Removed trailing whitespace.
+
+2012-09-04	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Fix for issue63.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LinkSelection.java:
+	  Place map image in helper section.
+
+2012-09-04	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java:
+	  Add some debug which file will be used for local user authentification
+
+2012-09-04	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/webapp/WEB-INF/features.xml:
+	  Add features for flys_wsa_schweinfurt role
+
+2012-09-04  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 808.
+
+	* src/main/java/de/intevation/flys/client/client/ui/wq/QDTable.java:
+	  Added new row for single selection and set field titles.
+
+	* src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Show the single selection row on init.
+
+	* src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Updated i18n strings.
+
+2012-09-04  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 664.
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Made old value an i18n formatted string.
+
+2012-09-04	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/RemoteServiceServlet.java:
+	  Add missing imports and fix package declaration.
+
+2012-09-04  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 791.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java:
+	  Do not allow the same values in reference and target location.
+
+	* 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:
+	  Added i18n strings.
+
+2012-09-04	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Partial fix for issue820.
+
+	* 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_de.properties:
+	  Change i18n (middle height -> middle depth).
+
+2012-09-03	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Do not show labels in logo selection combobox.
+
+2012-09-03	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+
+	Show logos in selectbox in chart properties such that user gets a
+	visual idea of what she selects.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Show icons in select box that displays the chosen logo.
+
+	* src/main/webapp/images/logo-intevation.png,
+	  src/main/webapp/images/logo-bfg.gif:
+	  Two exemplary logos (copies in flys-artifacts).
+
+2012-09-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java,
+	  src/main/java/de/intevation/flys/client/client/ui/minfo/CheckboxPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java:
+	  Removed superfluous imports.
+
+2012-09-01	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java:
+	  Overflow for Toolbars is now HIDDEN to avoid nasty scrollbars (#761).
+
+2012-09-01	Christian Lins	<christian.lins@intevation.de>
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/DatacagePairWidget.java,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Change button title in DatacagePairWidget (#746).
+
+2012-08-31	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ThemePanel.java:
+	  ThemePanels are now resizable (fix for #750).
+
+2012-08-31	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Maybe sqashing issue531, calling projectlists superclasses constructor.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Call super() constructor.
+
+2012-08-31	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Set the default value of the RadioGroupItem if a module is selected.
+
+2012-08-31	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/services/ModuleService.java:
+	  Load the list of modules from the flys artifact server. Also respect the
+	  selected attribute of a module.
+
+2012-08-31	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultModule.java,
+	  src/main/java/de/intevation/flys/client/client/services/ModuleService.java:
+	  Add isSelected method to Module classes.
+
+2012-08-31  Raimund Renkert <raimund.renkert@intevation.de>
+
+	MINFO: Added new UI provider for bed quality calculation.
+
+	* src/main/java/de/intevation/flys/client/client/ui/minfo/CheckboxPanel.java:
+	  New. UI provider for a list of checkboxes.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Added new UI provider.
+
+2012-08-31  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java:
+	  Use river data in all states not only winfo.
+
+2012-08-31  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ExportPanel.java:
+	  Hide the W/Q AT export button in fix analysis parameter tab.
+
+2012-08-31	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/UserClient.java:
+	  User xml namespace for XPath attribute query.
+
+2012-08-31	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/webapp/WEB-INF/web.xml:
+	  Add servlet settings for ModuleService
+
+2012-08-30	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java:
+	  New projects are now initially maximized to prevent IE-layout issue (#755).
+
+2012-08-30	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/map/GetFeatureInfoWindow.java:
+	  Workaround for #775 (manually set window size to 500x500 pixels)
+
+	* src/main/java/de/intevation/flys/client/client/ui/WspDatacagePanel.java:
+	  Prevent NPE
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java,
+	  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:
+	  i18n for logo placement.
+
+2012-08-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java:
+	  Load modules from the ModuleService instead of using hardcoded strings.
+
+2012-08-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java:
+	  Hardcode German translations for module names until real translations are
+	  available.
+
+2012-08-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/webapp/WEB-INF/features.xml:
+	  Add roles and features for GGinA
+
+2012-08-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/ModuleServiceAsync.java,
+	  src/main/java/de/intevation/flys/client/client/services/ModuleService.java,
+	  src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java:
+	  Added service to list available modules for a user.
+
+2012-08-29	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultModule.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Module.java:
+	  Added class representation of a module artifact.
+
+2012-08-29	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Special chart properties should trigger different ui (logo placement box).
+
+	* 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:
+	  Added i18n strings for split logo-placement properties in charts.
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Special chart properties should trigger different ui (logo placement box).
+
+	* 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:
+	  Added i18n strings for logo-placements in charts.
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Special chart properties should trigger different ui (logo select box).
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* 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:
+	  Added first i18n strings for logo-inclusion in charts.
+
+2012-08-28	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/CollectionHelper.java,
+	  src/main/java/de/intevation/flys/client/shared/model/StringProperty.java,
+	  src/main/java/de/intevation/flys/client/shared/model/OutputSettings.java,
+	  src/main/java/de/intevation/flys/client/shared/model/FacetRecord.java:
+	  Cosmetics.
+
+2012-08-28  Raimund Renkert <raimund.renkert@intevation.de>
+
+	MINFO: Added UI for minfo differences calculation.
+
+	* src/main/java/de/intevation/flys/client/client/ui/minfo,
+	  src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java:
+	  New. UI provider for states in minfo differences calculation.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Added new UI provider.
+
+	* 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:
+	  Added i18n strings.
+
+2012-08-24	Björn Ricks	<bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/UserClient.java:
+	  Use new find-user REST interface to check if a user already exists in the
+	  database or a new user must be created.
+
+2012-08-24	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/UserClient.java:
+	  Send account data to REST interface.
+
+2012-08-24	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/UserClient.java:
+	  Don't use XPath Query to get attribute of a XML Node
+
+2012-08-24	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/DefaultUser.java,
+	  src/main/java/de/intevation/flys/client/server/auth/was/Response.java,
+	  src/main/java/de/intevation/flys/client/server/auth/was/User.java,
+	  src/main/java/de/intevation/flys/client/server/auth/User.java:
+	  Add account information to client user classes. Use the WAS/GGInA
+	  assertion NameIdentifier element for the account name. For text
+	  authentication user username also as account name.
+
+2012-08-24	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/LoginServlet.java:
+	  Add debug output if a database user will be created.
+
+2012-08-23	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserServiceImpl.java:
+	  Avoid using XPath queries for getting attributes of a node.
+
+2012-08-22	Christian Lins	<christian.lins@intevation.de>
+
+	* 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/CollectionView.java:
+	  Delete empty project after closing the CollectionView (#785).
+
+2012-08-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ExportServiceImpl.java:
+	  Removed superfluous import. Removed some inner whitespace.
+	  Made debug output conditional.
+
+2012-08-17  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Added AT file export to FixAnalysis W/Q.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java:
+	  New image link for AT export in W/Q tab.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/NaviChartOutputTab.java:
+	  Update link url on km change.
+
+	* src/main/java/de/intevation/flys/client/server/ExportServiceImpl.java:
+	  Add the km to the request document.
+
+	* 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:
+	  Added i18n string for tooltip.
+
+2012-08-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ProxyServlet.java:
+	  Shortend lines to 80 chars. Made debug outout conditional.
+	  Use block copy instead of tight byte wise loop.
+
+2012-08-16	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ProxyServlet.java:
+	  Implement a ProxyServlet to be able to restrict the access to the
+	  mapserver too. All queries to the provided map services should go throught
+	  this new ProxyServlet. Currently the ProxyServlet can only handle HTTP GET
+	  requests.
+
+2012-08-16	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java:
+	  Replaced another attribute fetching XPath with a simple DOM
+	  getAttributeNS() call.
+
+2012-08-15	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java:
+	  Avoid NullPointerException if user authetication is deactivated. If user
+	  Authentication is deactivated all rivers are returned.
+
+2012-08-15  Raimund Renkert <raimund.renkert@intevation.de>
+
+	Issue 752. Location input label.
+
+	* src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java:
+	  Added getter for label string.
+
+	* 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_de.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties:
+	  Added i18n string for single location label.
+
+2012-08-15	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java:
+	Only return rivers that the user is allowed to see. Evaluate the allowed
+	features of the current logged in user and hide rivers which aren't
+	mentioned in the features list.
+
+2012-08-15	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/services/RemoteServiceServlet.java:
+	  Implement an extended GWT RemoteServiceServlet to be able to get the
+	  current logged in user easily.
+
+2012-08-13	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/DefaultUser.java,
+	  src/main/java/de/intevation/flys/client/server/features/XMLFileFeatures.java:
+	  Removed superfluous imports.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/was/Response.java:
+	  Add debug log of a successfull authentification inclusive the
+	  corresponding features of the authenticated user.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/webapp/WEB-INF/features.xml:
+	  Add example features for GGinA/WAS role flys_bfg.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/features/XMLFileFeatures.java:
+	  Don't use a xml namespace to get the "name" attribute of a role.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+	* src/main/java/de/intevation/flys/client/server/auth/was/Authenticator.java,
+	  src/main/java/de/intevation/flys/client/server/auth/was/Response.java,
+	  src/main/java/de/intevation/flys/client/server/auth/was/User.java:
+	  Implement Features handling for WAS authentication.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/LoginServlet.java,
+	  src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java,
+	  src/main/java/de/intevation/flys/client/server/auth/DefaultUser.java,
+	  src/main/java/de/intevation/flys/client/server/auth/was/Authenticator.java,
+	  src/main/java/de/intevation/flys/client/server/auth/Authenticator.java,
+	  src/main/java/de/intevation/flys/client/server/auth/User.java,
+	  src/main/java/de/intevation/flys/client/server/GGInAFilter.java:
+	  Refactor Authentication to allow to pass the Freatures to the user class.
+
+2012-08-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/features/XMLFileFeatures.java:
+	  Used HashMap instead of Hashtable. Limit to 80 chars per line.
+
+2012-08-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/meta/Converter.java:
+	  Removed trailing whitespace.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+	* src/main/java/de/intevation/flys/client/server/features/XMLFileFeatures.java:
+	  Always close FileInputStream, improve for loops and avoid XPath for
+	  getting a xml attribute.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+	* src/main/java/de/intevation/flys/client/server/CapabilitiesParser.java,
+	  src/main/java/de/intevation/flys/client/server/BaseServlet.java,
+	  src/main/webapp/WEB-INF/web.xml:
+	  Remove the obsolete BaseServlet. Initializing of logging is now handled by
+	  the BaseServletContextListener class which is loaded before any Servlet.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+	* src/main/java/de/intevation/flys/client/server/features/FeatureServletContextListener.java,
+	  src/main/java/de/intevation/flys/client/server/BaseServletContextListener.java,
+	  src/main/webapp/WEB-INF/web.xml:
+	  Rename and move FeatureServletContextListener.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+	* src/main/java/de/intevation/flys/client/server/features/FeatureServletContextListener.java,
+	  src/main/webapp/WEB-INF/web.xml:
+	  Implement a ServletContextListener to initialize the Fearures from a xml
+	  file. With the context parameter "features-file" in src/main/webapp/WEB-INF/web.xml
+	  a xml file to load features from can be specified.
+	  The FeatureServletContextListener class also initializes the logging now
+	  because it is loaded before the BaseServlet.
+
+2012-08-08	Björn Ricks <bjoern.ricks@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/features/XMLFileFeatures.java,
+	  src/main/java/de/intevation/flys/client/server/features/FeaturesNamespaceContext.java,
+	  src/main/java/de/intevation/flys/client/server/features/Features.java,
+	  src/main/webapp/WEB-INF/features.xml:
+	  Implementation of a feature representation. The XMLFileFeatures class can
+	  be used to load a feature xml file (src/main/webapp/WEB-INF/features.xml)
+	  and create a map of roles to a list of features.
+
+2012-08-08	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/meta/Converter.java:
+	  Cosmetics, reordered code.
+
+	* src/main/java/de/intevation/flys/client/client/ui/DatacageWidget.java:
+	  Show tooltip for rows in datacage widget.
+
+2012-08-08	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/meta/Converter.java:
+	  Documentation added, use static map instead of population in
+	  constructor.
+
+2012-07-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixQSelectPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Removed superfluous imports.
+
+2012-07-27  Ingo Weinzierl <ingo@intevation.de>
+
+	Tagged module as '2.8.1'.
+
+2012-07-26  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/ChartMode.java: Let
+	  'fix_vollmer_wq_curve" Output also use the NaviChartOutputTab.
+
+	* 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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added titles for the 'fix_vollmer_wq_curve' Output tab.
+
+2012-07-26	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/StyleHelper.java,
+	  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.properties,
+	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties,
+	  src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java:
+	  Merge point/line label styles. Add new style options for point/line
+	  label background.
+
+2012-07-25	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java:
+	  Accept differing state data names of FixationArtifacts.
+
+2012-07-24	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/Artifact.java,
+	  src/main/java/de/intevation/flys/client/shared/model/FixAnalysisArtifact.java,
+	  src/main/java/de/intevation/flys/client/client/FLYS.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Cosmetics.
+
+2012-07-24	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/ProjectList.java:
+	  Respect factory of cloned artifact when cloning.
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java,
+	  src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixGaugeSelectPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixLocationPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixMultiPeriodPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixQSelectPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixEventSelect.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixPeriodPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/PeriodPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/map/WMSLayersTree.java,
+	  src/main/java/de/intevation/flys/client/client/ui/DoubleInputPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/MultiPeriodPanel.java:
+	  Removed some superfluous casts.
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl:
+	  Catch the case that a previous gauge is before the start of the
+	  events. This led to a broken layout.
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl:
+	  Bring in sync with transformation in flys-client.
+
+2012-07-21	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl:
+	  Bring in sync with transformation in flys-client. Current weakness:
+	  Only english and german locales are supported.
+
+	* src/main/java/de/intevation/flys/client/server/FixingsOverviewServiceImpl.java:
+	  Depending on client given locale call transformation with
+	  locale "de" or "en".
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl: Merged
+	  changes from transformation in flys-artifacts: Render names
+	  to the gauges into the headline. Full names and spread are
+	  displayed as tooltips.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/OverviewOutputTab.java:
+	  Removed the export buttons for SVG and PDF; those exports aren't
+	  implemented on server side yet.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/sq/SQCampaignChart.java:
+	  New subclass of VLayout that displays a chart with field campaigns. The
+	  code is copied from SQMultiPeriodPanel.
+
+	* src/main/java/de/intevation/flys/client/client/ui/sq/SQMultiPeriodPanel.java:
+	  Moved the code to display the field campaign charts into SQCampaignChart
+	  class.
+
+	* src/main/java/de/intevation/flys/client/client/ui/sq/SQPeriodPanel.java:
+	  New UIProvider that allows the input of a time period; the helper panel
+	  displays a chart with field campaigns.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Registered SQPeriodPanel as new UIProvider.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Added a new UI provider that supports input of a time period (without
+	  any helper panel).
+
+2012-07-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java:
+	  Removed superfluous import.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java:
+	  Removed trailing whitespace.
+
+2012-07-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java:
+	  Made getChartOutputTab() protected.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java:
+	  Moved creation of a ChartToolbar and a ChartThemePanel from constructor to
+	  own methods which enables subclasses to override those.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/OverviewOutputTab.java:
+	  Override createThemePanel() and createChartToolbar() of parent class. Both
+	  methods return instances of minimalistic implementations of a
+	  ChartThemePanel and ChartToolbar. In addition, the overview chart is
+	  fetched as single image.
+
+2012-07-19  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/DoubleInputPanel.java:
+	  Read default value from Data item; set textfield to this value of a
+	  default value is existing.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/FixAnalysisArtifact.java,
+	  src/main/java/de/intevation/flys/client/shared/model/DoubleProperty.java,
+	  src/main/java/de/intevation/flys/client/client/ui/fixation/FixGaugeSelectPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/NaviChartOutputTab.java:
+	  Use more idiomatic Java when parsing doubles and ints.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* ChangeLog: Removed remains from former conflict.
+
+2012-07-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixFunctionSelect.java
+	  src/main/java/de/intevation/flys/client/client/ui/chart/NaviChartOutputTab.java:
+	  Removed superfluous imports.
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixationPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Removed trailing whitespace.
+
+2012-07-19	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Register (to-be-implemented) fix.qselect_panel UIProvider.
+
+2012-07-19	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java:
+	  Prepare for bandwidthcolor, and preset bandwidth with previously
+	  entered values.
+
+2012-07-19	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WspDatacagePanel.java:
+	  Cosmetics.
+
+2012-07-19  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixationPanel.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/NaviChartOutputTab.java:
+	  Input fields for chart navigation now use the correct i18n number formats.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl:
+	  Generate only legend entries for existing discharge sectors.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixGaugeSelectPanel.java:
+	  Replaced discharge sectors with more human readable labels.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl:
+	  Added legend at bottom of overview table.
+
+2012-07-18  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/fixation/FixFunctionSelect.java:
+	  New. UI provider for function selection in fix analysis. This UI provider
+	  shows the overview and chart in the helper panel.
+
+	* src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java:
+	  Use the new UI provider in function select state.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Populate double type theme attributes with already set values.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java:
+	  Code compres	  Code compression.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java:
+	  Improve validation.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/ManualWSPEditor.java:
+	  Cosmetic compression.
+
+2012-07-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Added public methods to lock and unlock the CollectionView. Locking the
+	  view means, a semi transparent layer prevents the user to use the
+	  control elements in the CollectionView. In addition to the semi
+	  transparent layer, a progress image is displayed.
+
+	* src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Lock the CollectionView when StepBack and StepForward events are fired.
+	  Unlock the screen on success or failure.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java:
+	  Handle upcoming "double" theme attribute type.
+
+2012-07-18	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/utils/DoubleValidator.java,
+	  src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java,
+	  src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java:
+	  Cosmetics.
+
+2012-07-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/auth/DefaultUser.java,
+	  src/main/java/de/intevation/flys/client/client/ui/chart/OverviewOutputTab.java:
+	  Removed trailing whitespace.
+
+2012-07-17	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* main/java/de/intevation/flys/client/client/FLYSConstants.java,
+	  main/java/de/intevation/flys/client/client/FLYSConstants.properties,
+	  main/java/de/intevation/flys/client/client/FLYSConstants_en.properties,
+	  main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
+	  Added i18n strings for bandwidth.
+
+	* src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java:
+	  Include bandwidth field.
+
+2012-07-17	Christian Lins	<christian.lins@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java:
+	  Correct height of ChartToolbar to 35 pixels.
+
+	* src/main/java/de/intevation/flys/client/client/ui/map/GetFeatureInfoWindow.java:
+	  Make use of generics and cosmetics.
+
+	* src/main/java/de/intevation/flys/client/client/ui/map/FloodMap.java,
+	  src/main/java/de/intevation/flys/client/client/ui/map/MapOutputTab.java,
+	  src/main/java/de/intevation/flys/client/client/ui/map/MapPanel.java:
+	  ThemePanel toggle stuff.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Increase default size as the toolbar has grown as well.
+
+	* pom.xml:
+	  Add commons-codec dependency.
+
+2012-07-13	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java,
+	  src/main/java/de/intevation/flys/client/client/ui/ParameterList.java:
+	  Cosmetics, docs.
+
+2012-07-16  Ingo Weinzierl <ingo@intevation.de>
+
+	* Tagged module as '2.8'.
+
 2012-07-15	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/client/client/ui/ThemePanel.java,
@@ -200,8 +1588,6 @@
 	  src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties:
 	  Add showpointlabel stlye attribute.
 
-
->>>>>>> .r4973
 2012-07-11	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java:
--- a/flys-client/pom.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/pom.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -15,8 +15,8 @@
       <!-- Convenience property to set the GWT version -->
       <gwtVersion>2.4.0</gwtVersion>
       <!-- GWT needs at least java 1.5 -->
-      <maven.compiler.source>1.5</maven.compiler.source>
-      <maven.compiler.target>1.5</maven.compiler.target>
+      <maven.compiler.source>1.6</maven.compiler.source>
+      <maven.compiler.target>1.6</maven.compiler.target>
   </properties>
 
   <dependencies>
@@ -32,12 +32,6 @@
       <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>
@@ -114,6 +108,11 @@
         <artifactId>commons-io</artifactId>
         <version>2.2</version>
     </dependency>
+    <dependency>
+    	<groupId>commons-codec</groupId>
+    	<artifactId>commons-codec</artifactId>
+    	<version>1.4</version>
+    </dependency>
   </dependencies>
 
   <build>
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYS.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYS.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,33 +1,24 @@
 package de.intevation.flys.client.client;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
 import com.google.gwt.core.client.EntryPoint;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.event.shared.UmbrellaException;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.xml.client.XMLParser;
-
 import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.HTMLPane;
 import com.smartgwt.client.widgets.Window;
-import com.smartgwt.client.widgets.HTMLPane;
-import com.smartgwt.client.widgets.layout.VLayout;
-import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.events.CloseClickEvent;
 import com.smartgwt.client.widgets.events.CloseClickHandler;
-import com.smartgwt.client.widgets.events.CloseClickEvent;
-
-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 com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
 
 import de.intevation.flys.client.client.event.CollectionChangeEvent;
 import de.intevation.flys.client.client.event.CollectionChangeHandler;
 import de.intevation.flys.client.client.services.ArtifactService;
 import de.intevation.flys.client.client.services.ArtifactServiceAsync;
+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;
 import de.intevation.flys.client.client.services.GetArtifactService;
@@ -37,12 +28,22 @@
 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.FLYSFooter;
 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;
+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 java.util.ArrayList;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.Set;
 
 
 /**
@@ -73,11 +74,14 @@
     protected GetArtifactServiceAsync getArtifactService =
         GWT.create(GetArtifactService.class);
 
+    /** The CreateCollectionServiceAsync used to create a new collection */
+    protected CreateCollectionServiceAsync collectionService =
+        GWT.create(CreateCollectionService.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.*/
+    /** 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. */
@@ -102,6 +106,7 @@
     /**
      * This is the entry point method.
      */
+    @Override
     public void onModuleLoad() {
         openProjects = new ArrayList<String>();
 
@@ -138,14 +143,25 @@
         Config config = Config.getInstance();
         String locale = config.getLocale();
 
-        getRivers();
-
         userService.getCurrentUser(locale, new AsyncCallback<User>() {
+            @Override
             public void onFailure(Throwable caught) {
                 GWT.log("Could not find a logged in user.");
-                SC.warn(MSG.getString(caught.getMessage()));
+                String msg = caught.getLocalizedMessage();
+                try {
+                    msg = MSG.getString(caught.getMessage());
+                }
+                catch(MissingResourceException ex) {
+                    // There are some server error exceptions with
+                    // varying text messages that cannot be localized
+                    // easily. In this rare cases, use the plain
+                    // exception message.
+                    GWT.log("Missing resource for: " + caught.getMessage());
+                }
+                SC.warn(msg);
             }
 
+            @Override
             public void onSuccess(User user) {
                 GWT.log("Found a user. Set '"+ user.getName() + "'");
                 setCurrentUser(user);
@@ -258,11 +274,13 @@
         String locale = config.getLocale();
 
         riverService.list(locale, new AsyncCallback<River[]>() {
+            @Override
             public void onFailure(Throwable caught) {
                 GWT.log("Could not recieve a list of rivers.");
                 SC.warn(MSG.getString(caught.getMessage()));
             }
 
+            @Override
             public void onSuccess(River[] newRivers) {
                 GWT.log("Retrieved " + newRivers.length + " new rivers.");
                 rivers = newRivers;
@@ -311,11 +329,13 @@
     }
 
 
+    /** Whether project uuid is currently opened. */
     protected boolean isProjectLocked(String uuid) {
         return openProjects.contains(uuid);
     }
 
 
+    /** Opens (or bring into foreground) project with given id. */
     public void openProject(final String collectionID) {
         if (collectionID == null) {
             return;
@@ -335,10 +355,12 @@
 
         describeCollectionService.describe(collectionID, locale,
             new AsyncCallback<Collection>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     SC.warn(MSG.getString(caught.getMessage()));
                 }
 
+                @Override
                 public void onSuccess(Collection c) {
                     final Collection collection = c;
 
@@ -357,7 +379,7 @@
                         return;
                     }
 
-                    final CollectionItem   item = c.getItem(0);
+                    final CollectionItem item = c.getItem(0);
 
                     if (item == null) {
                         SC.warn(MSG.error_load_parameterization());
@@ -369,11 +391,13 @@
                         item.identifier(),
                         item.hash(),
                         new AsyncCallback<Artifact>() {
+                            @Override
                             public void onFailure(Throwable caught) {
                                 unlockProject(collectionID);
                                 SC.warn(MSG.getString(caught.getMessage()));
                             }
 
+                            @Override
                             public void onSuccess(Artifact artifact) {
                                 CollectionView view = new CollectionView(
                                     FLYS.this, collection, artifact);
@@ -408,18 +432,70 @@
 
         artifactService.create(locale, factory, null,
             new AsyncCallback<Artifact>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     GWT.log("Could not create the new artifact.");
                     SC.warn(MSG.getString(caught.getMessage()));
                 }
 
+                @Override
                 public void onSuccess(Artifact artifact) {
                     GWT.log("Successfully created a new artifact.");
                 }
         });
     }
 
+    public void newGaugeDischargeCurve(String river, Long gaugeref) {
+        Config config = Config.getInstance();
 
+        final String locale = config.getLocale();
+        final String riv = river;
+        final Long ref = gaugeref;
+        final FLYS   flys = this;
+
+        User user = getCurrentUser();
+
+        if (user == null) {
+            SC.warn(MSG.error_not_logged_in());
+            return;
+        }
+
+        collectionService.create(locale, user.identifier(),
+            new AsyncCallback<Collection>() {
+                @Override
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not create new collection.");
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                @Override
+                public void onSuccess(Collection collection) {
+                    GWT.log("Successfully created a new collection.");
+                    final Collection col = collection;
+                    artifactService.createGaugeDischargeCurverArtifact(
+                        col, locale, riv, ref,
+                        new AsyncCallback<Artifact>() {
+                            @Override
+                            public void onFailure(Throwable caught) {
+                                GWT.log("Could not create the new artifact.");
+                                SC.warn(MSG.getString(caught.getMessage()));
+                            }
+
+                            @Override
+                            public void onSuccess(Artifact artifact) {
+                                GWT.log("Successfully created a new artifact.");
+                                CollectionView view = new CollectionView(flys,
+                                    col, artifact);
+                                workspace.addView("new-project", view);
+
+                                view.addCollectionChangeHandler(getProjectList());
+                            }
+                    });
+                }
+            });
+    }
+
+    @Override
     public void onCollectionChange(CollectionChangeEvent event) {
         Collection oldC = event.getOldValue();
 
@@ -444,6 +520,7 @@
             this.uuid = uuid;
         }
 
+        @Override
         public void onCloseClick(CloseClickEvent event) {
             flys.closeProject(uuid);
         }
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,8 @@
  */
 public interface FLYSConstants extends ConstantsWithLookup {
 
+    String add();
+
     String unexpected_exception();
 
     String title();
@@ -168,6 +170,8 @@
 
     String locations();
 
+    String single_location();
+
     String distance();
 
     String unitFrom();
@@ -226,6 +230,8 @@
 
     String helperPanelTitle();
 
+    String gaugePanelTitle();
+
     String wqTitle();
 
     String wqadaptedTitle();
@@ -262,6 +268,10 @@
 
     String unitQStep();
 
+    String main_channel();
+
+    String total_channel();
+
     String footerHome();
 
     String footerContact();
@@ -359,6 +369,17 @@
     String zoomboxTooltip();
 
     String chartPropertiesTooltip();
+
+    // Gauges
+
+    String gauge_mnq();
+
+    String gauge_mq();
+
+    String gauge_mhq();
+
+    String gauge_hq5();
+
     // Elevation window
 
     String ele_window_title();
@@ -385,6 +406,8 @@
 
     String discharge_curve();
 
+    String gauge_discharge_curve();
+
     String computed_discharge_curve();
 
     String computed_discharge_curves();
@@ -433,6 +456,8 @@
 
     String fix_derivate_curve();
 
+    String fix_vollmer_wq_curve();
+
     // EXPORTS
 
     String waterlevel_export();
@@ -499,6 +524,10 @@
 
     String bedheight_middle_export();
 
+    String bed_longitudinal_section();
+
+    String bed_longitudinal_section_export();
+
     String sq_relation_a();
 
     String sq_relation_b();
@@ -513,6 +542,20 @@
 
     String sq_relation_export();
 
+    String exportATTooltip();
+
+    String load_diameter();
+
+    String bed_diameter();
+
+    String soundings();
+
+    String bed_difference_year();
+
+    String bed_difference_epoch();
+
+    String bed_difference_height_year();
+
     // ERRORS
 
     String error_read_minmax_values();
@@ -543,8 +586,12 @@
 
     String error_no_rivers_found();
 
+    String error_no_gaugeoverviewinfo_found();
+
     String error_no_such_user();
 
+    String error_no_users();
+
     String error_no_waterlevel_pair_selected();
 
     String error_same_waterlevels_in_pair();
@@ -597,6 +644,8 @@
 
     String error_no_map_output_type();
 
+    String error_no_module_found();
+
     String warning_use_first_feature();
 
     String error_no_valid_gfi_url();
@@ -629,6 +678,12 @@
 
     String top_edge();
 
+    String error_same_location();
+
+    String error_contains_same_location();
+
+    String error_update_collection_attribute();
+
     // MAP RELATED STRINGS
 
     String digitize();
@@ -773,6 +828,16 @@
 
     String gaugelocations();
 
+    String single();
+
+    String epoch();
+
+    String bedheights();
+
+    String datacage();
+
+    String datacage_add_pair();
+
     // Capabilities Information Panel
 
     String addwmsInputTitle();
@@ -829,6 +894,24 @@
 
     String display_grid();
 
+    String display_logo();
+
+    String logo_placeh();
+
+    String logo_placev();
+
+    String top();
+
+    String bottom();
+
+    String center();
+
+    String left();
+
+    String right();
+
+    String none();
+
     String linetype();
 
     String textstyle();
@@ -839,6 +922,10 @@
 
     String showverticalline();
 
+    String horizontal();
+
+    String vertical();
+
     String textcolor();
 
     String textsize();
@@ -859,6 +946,8 @@
 
     String pointsize();
 
+    String bandwidth();
+
     String pointcolor();
 
     String showlines();
@@ -867,17 +956,17 @@
 
     String showpointlabel();
 
-    String linelabelfont();
-
-    String linelabelcolor();
+    String labelfontsize();
 
-    String linelabelsize();
+    String labelfontcolor();
 
-    String linelabelstyle();
+    String labelfontface();
 
-    String linelabelbgcolor();
+    String labelfontstyle();
 
-    String linelabelshowbg();
+    String labelbgcolor();
+
+    String labelshowbg();
 
     String showwidth();
 
@@ -889,7 +978,7 @@
 
     String transparent();
 
-    String alpha();
+    String transparency();
 
     String showarea();
 
@@ -942,5 +1031,21 @@
     String fix_parameters();
 
     String sq_overview();
+
+    // Gauge Overview Info
+
+    String gauge_zero();
+
+    String gauge_q_unit();
+
+    String gauge_info_link();
+
+    String gauge_river_info_link();
+
+    String gauge_river_url();
+
+    String gauge_url();
+
+    String gauge_curve_link();
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -55,20 +55,21 @@
 scale = Scale
 databasket = Databasket
 databasket_loading = Loading Databasket content
-fix = TODO FIX ANALYSE TODO
-fixanalysis = TODO FIX ANALYSE TODO
+fix = Fixing
+fixanalysis = Fixing Analysis
 next = Next
 location_distance_state = Choose calculation location(s) / range [km]
 distance_state = Choose calculation range [km]
 waterlevel_ground_state = Choose differences betweeen waterlevel and ground [m]
 location = Location(s)
 locations = Locations
+single_location = Location
 distance = Range
 unitFrom = km
 unitTo = km a
 unitWidth = m
 search = Search
-discharge = FIXME(Name)
+discharge = Discharge Name
 properties = Properties
 activateTheme = Activate
 deactivateTheme = Deactivate
@@ -83,6 +84,7 @@
 start_year = Start
 end_year = End
 period = Period
+
 # Header images
 flysLogo = images/flys_logo.gif
 bfgLogo = images/bfg_logo.gif
@@ -155,6 +157,7 @@
 wqHistorical = Selection of Analyse Type
 calcTableTitle = Calculated Output
 helperPanelTitle = Input Support
+gaugePanelTitle = Gauge Information
 wqW = W at Gauge [cm]
 wqQ = Q [m\u00b3/s]
 wqWFree = W free position [m+NHN]
@@ -170,9 +173,11 @@
 unitQFrom = m³/s&nbsp;-
 unitQTo = m³/s&nbsp;a
 unitQStep = m³/s
+main_channel = Main Channel
+total_channel = Total Channel
 footerHome = Home
-footerContact = Kontakt
-footerImpressum = Impressum
+footerContact = Contact
+footerImpressum = Legal info
 
 buttonNext = Next
 imageBack = images/back_en.png
@@ -187,8 +192,10 @@
 zoom_back = images/mag_zoom_back.png
 pan = images/hand.png
 askThemeRemove = Are you sure that you want to remove the selected theme / themes?
+add = Add
 
 discharge_curve = Discharge Curves at Gauges
+gauge_discharge_curve = Discharge Curves at Gauge
 computed_discharge_curve = Discharge Curve
 computed_discharge_curves = Discharge Curves
 longitudinal_section = Longitudinal Section Curve
@@ -200,6 +207,8 @@
 flow_velocity_export = Flow Velocity Export
 bedheight_middle = Middle Bed Height
 bedheight_middle_export = Middle Bed Height Export
+bed_longitudinal_section = Bed Quality
+bed_longitudinal_section_export = Bed Quality Export
 sq_relation_a = A Feinkornanteil
 sq_relation_b = B Sand (Suspensionstransport)
 sq_relation_c = C Sand (Geschiebetransport)
@@ -217,6 +226,16 @@
 fix_deltawt_curve = \u0394 W/t
 fix_longitudinal_section_curve = Longitudinal Section
 fix_derivate_curve = Derivate
+fix_vollmer_wq_curve = W/Q
+datacage_add_pair = Add difference pair
+load_diameter = Bedload Diameter
+bed_diameter = Bed Diameter
+soundings = Soundings
+bed_difference_year = Single Bedheight Differences
+bed_difference_epoch = Epoch Bedheight Differences
+bed_difference_height_year = Bedheight Differences per year
+
+exportATTooltip = Export as AT file
 
 waterlevel_export = Waterlevel Export
 waterlevel_report = Waterlevel Report
@@ -226,7 +245,7 @@
 discharge_longitudinal_section_report = Discharge Longitudinal Section Report
 durationcurve_export = Duration Curve Export
 durationcurve_report = Duration Curve Report
-dataexport = Datenexport
+dataexport = Data export
 csv = CSV
 wst = WST
 at = AT
@@ -248,6 +267,11 @@
 chart_themepanel_area_between = between ...
 against_x_axis = Over X-Axis
 
+gauge_mnq = around MNQ
+gauge_mq  = around MQ
+gauge_mhq = around MHQ
+gauge_hq5 = above HQ5
+
 ele_window_title = Elevation Node
 ele_window_label = Elevation settings in m \u00fc. NN.
 ele_window_x_col = X
@@ -277,11 +301,13 @@
 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_no_users = Error - no users found.
 error_no_waterlevel_pair_selected = Error - no waterlevel pair for building differences selected.
 error_same_waterlevels_in_pair = Error - minuend and subtrahend have to differ.
 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_wrong_date = Please enter valid dates.
+error_no_gaugeoverviewinfo_found = Error while fetching the river and gauge info
 
 error_feed_no_data = No input data found.
 error_feed_from_out_of_range = The lower value is bigger than the upper value.
@@ -317,6 +343,10 @@
 error_bad_dgm_river = You have selected a DEM for a wrong river.
 error_dialog_not_valid = One or more values are not valid.
 error_invalid_date = The entered date is not valid.
+error_same_location = Reference location equals selected location.
+error_contains_same_location = Target locations contains reference location.
+error_update_collection_attribute = Error while updating the collection attribut
+error_no_module_found = No modules found
 
 ## map related strings
 digitize = images/digitize.png
@@ -391,6 +421,10 @@
 dems = Digital Elevation Models
 hydrboundaries = Hydrological Boundaries
 gaugelocations = Location of Gauges
+single = Year
+epoch = Epoch
+bedheights = Bedheights
+datacage = Datacage
 
 # capabilities information panel
 addwmsInputTitle = Base URL of WMS service
@@ -423,6 +457,15 @@
 title = Title
 subtitle = Subtitle
 display_grid = Display grid
+display_logo = Display logo
+logo_placeh = Horiz. Place for logo
+logo_placev = Vertic. Place for logo
+top = top
+bottom = bottom
+center = center
+left = left
+right = right
+none = none
 
 linetype = Linetype
 textstyle = Textstyle
@@ -438,25 +481,28 @@
 textorientation = Textorientation
 linesize = Linesize
 pointsize = Pointsize
+bandwidth = Bandwidth
 pointcolor = Punktfarbe
 showlines = Show lines
 showlinelabel = Show line label
 showpointlabel = Show point label
-linelabelfont = Label: Font
-linelabelcolor = Label: Color
-linelabelsize = Label: Size
-linelabelstyle = Label: Style
-linelabelbgcolor = Label: Background Color
-linelabelshowbg = Label: Show Background
+labelfontface = Label: Font
+labelfontcolor = Label: Color
+labelfontsize = Label: Size
+labelfontstyle = Label: Style
+labelbgcolor = Label: Background Color
+labelshowbg = Label: Show Background
+horizontal = horizontal
+vertical = vertical
 showwidth = Show width
 showlevel = Show waterlevel
 showminimum = Show minimum
 showmaximum = Show maximum
 showborder = Show line
 transparent = Transparency
-alpha = Transparency Alpha
+transparency = Transparency
 showarea = Show Area
-showmiddleheight = Show middle height
+showmiddleheight = Show middle depth
 fillcolor = Fill Color
 wsplgen_cat1 = Fill Color 0.0 <= DIFF < 1
 wsplgen_cat2 = Fill Color 1.0 <= DIFF < 2
@@ -490,3 +536,11 @@
 fix_parameters = CSV
 
 sq_overview=Overview
+
+gauge_zero = Gauge zero ground
+gauge_q_unit = m\u00b3/s
+gauge_river_info_link = Riverinfo
+gauge_info_link = Gaugeinfo
+gauge_url = https://flys-intern.intevation.de/PegelInfo/
+gauge_river_url = https://flys-intern.intevation.de/GewaesserInfo/
+gauge_curve_link = Dischargecurve
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -63,6 +63,7 @@
 waterlevel_ground_state = Differenzen zwischen Wasserspiegel und Gel\u00e4nde [m]
 location = Ort(e)
 locations = Orte
+single_location = Ort
 distance = Strecke
 unitFrom = km&nbsp;-
 unitTo = km a
@@ -142,6 +143,7 @@
 wqHistorical = Auswahl der Analyseart
 calcTableTitle = Berechnungsausgabe
 helperPanelTitle = Eingabeunterst\u00fctzung
+gaugePanelTitle = Gew\u00e4sser/Pegel-Info
 wqW = W am Pegel [cm]
 wqQ = Q [m\u00b3/s]
 wqWFree = W auf freier Strecke [m+NHN]
@@ -157,6 +159,8 @@
 unitQFrom = m\u00b3/s&nbsp;-
 unitQTo = m\u00b3/s&nbsp;a
 unitQStep = m\u00b3/s
+main_channel = Hauptgerinne
+total_channel = Gesamtgerinne
 footerHome = Home
 footerContact = Kontakt
 footerImpressum = Impressum
@@ -174,6 +178,7 @@
 zoom_back = images/mag_zoom_back.png
 pan = images/hand.png
 askThemeRemove = Sind Sie sicher, dass sie die gew\u00e4hlten / das gew\u00e4lte Thema l\u00f6eschen wollen?
+add = Hinzuf\u00fcgen
 
 addPointsTooltip = Manuelle Punkte hinzuf\u00fcgen
 addWSPTooltip = Manuelle WSP hinzuf\u00fcgen
@@ -189,6 +194,7 @@
 chartPropertiesTooltip = Diagrammeigenschaften
 
 discharge_curve = Abflusskurven an Pegeln
+gauge_discharge_curve = Abflusskurven an Pegel
 computed_discharge_curve = Abflusskurve
 computed_discharge_curves = Abflusskurven
 longitudinal_section = L\u00e4ngsschnitt
@@ -200,6 +206,8 @@
 flow_velocity_export = Flie\u00dfgeschwindigkeiten Export
 bedheight_middle = Mittlere Sohlh\u00f6he
 bedheight_middle_export = Mittlere Sohlh\u00f6he Export
+bed_longitudinal_section = Sohlbeschaffenheit
+bed_longitudinal_section_export = Sohlbeschaffenheit Export
 sq_relation_a = A Feinkornanteil
 sq_relation_b = B Sand (Suspensionstransport)
 sq_relation_c = C Sand (Geschiebetransport)
@@ -217,6 +225,14 @@
 fix_deltawt_curve = \u0394 W/t
 fix_longitudinal_section_curve = L\u00e4ngsschnitt
 fix_derivate_curve = Ableitungskurve
+fix_vollmer_wq_curve = W/Q
+datacage_add_pair = Differenzenpaar hinzuf\u00fcgen
+load_diameter = Geschiebedurchmesser
+bed_diameter = Sohldurchmesser
+soundings = Peilungen
+bed_difference_year = Sohlh\u00f6hendifferenz (Jahr)
+bed_difference_epoch = Sohlh\u00f6hendifferenz (Epoche)
+bed_difference_height_year = Sohlh\u00f6hendifferenz pro Jahr
 
 waterlevel_export = Wasserstand/Wasserspiegellagen Export
 waterlevel_report = Wasserstand/Wasserspiegellagen Bericht
@@ -237,6 +253,8 @@
 events = Ereignisse
 kmchart = Diagramm
 
+exportATTooltip = Daten als AT Datei exportieren
+
 chart_themepanel_header_themes = Thema
 chart_themepanel_header_actions = Aktionen
 chart_themepanel_synchron = Synchron navigieren
@@ -248,6 +266,11 @@
 chart_themepanel_area_between = zwischen ...
 against_x_axis =  \u00fcber X-Achse
 
+gauge_mnq = um MNQ
+gauge_mq  = um MQ
+gauge_mhq = um MHQ
+gauge_hq5 = \u00fcber HQ5
+
 ele_window_title = H\u00f6henknoten setzen
 ele_window_label = H\u00f6henangaben in m \u00fc. NN.
 ele_window_x_col = X
@@ -276,12 +299,14 @@
 error_create_collection = Fehler beim Erstellen eines neuen Projektes.
 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_no_such_user = Fehler - Kein solcher Benutzer vorhanden.
+error_no_users = Fehler - Keine Benutzer vorhanden.
 error_no_waterlevel_pair_selected = Fehler - kein Paar zur Differenzenbildung gew\u00e4hlt.
 error_same_waterlevels_in_pair = Error - minuend and subtrahend m\u00fcssen sich unterscheiden.
 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_wrong_date = Bitte geben Sie gültige Daten ein.
+error_no_gaugeoverviewinfo_found = Fehler beim Laden der Fluss- und Pegelinformationen
 
 error_feed_no_data = Keine Eingabedaten gefunden.
 error_feed_from_out_of_range = Der untere Wert liegt au\u00dferhalb des g\u00fcltigen Wertebereiches.
@@ -317,6 +342,10 @@
 error_bad_dgm_river = Das gew\u00e4hlte DGM passt nicht zum gew\u00e4hlten Fluss.
 error_dialog_not_valid = Eine oder mehrere Daten sind nicht korrekt.
 error_invalid_date = Das eingegebene Datum ist nicht korrekt.
+error_same_location = Der gewählte Ort ist der Bezugsort.
+error_contains_same_location = Zielorte beinhalten den Bezugsort.
+error_update_collection_attribute = Fehler beim Aktualisieren des Collection-Attributs.
+error_no_module_found = Keine nutzbaren Module gefunden.
 
 ## map related strings
 digitize = images/digitize.png
@@ -391,6 +420,10 @@
 dems = Digitale Gel\u00e4ndemodelle
 hydrboundaries = Hydrologische Grenzen
 gaugelocations = Pegellagen
+single = Jahr
+epoch = Epoche
+bedheights = Sohlh\u00f6hen
+datacage = Datenkorb
 
 # capabilities information panel
 addwmsInputTitle = Basis URL des WMS Dienstes
@@ -423,6 +456,15 @@
 title = Titel
 subtitle = Untertitel
 display_grid = Gitterlinien anzeigen
+display_logo = Logo anzeigen
+logo_placeh = Horizontale Ausrichtung Logo
+logo_placev = Vertikale Ausrichtung Logo
+top = oben
+bottom = unten
+center = mittig
+left = links
+right = rechts
+none = keines
 
 linetype = Linientyp
 textstyle = Textstil
@@ -438,25 +480,28 @@
 textorientation = Textausrichtung
 linesize = Liniendicke
 pointsize = Punktdicke
+bandwidth = Bandbreite
 pointcolor = Punktfarbe
 showlines = Linien anzeigen
 showlinelabel = Linienbeschriftung anzeigen
 showpointlabel = Punktbeschriftung anzeigen
-linelabelfont = Beschriftung: Schriftart
-linelabelcolor = Beschriftung: Schriftfarbe
-linelabelsize =  Beschriftung: Schriftgr\u00f6\u00dfe
-linelabelstyle = Beschriftung: Schriftstil
-linelabelbgcolor = Beschriftung: Hintergrundfarbe
-linelabelshowbg = Beschriftung: Hintergrund f\u00fcllen
+labelfontface = Beschriftung: Schriftart
+labelfontcolor = Beschriftung: Schriftfarbe
+labelfontsize =  Beschriftung: Schriftgr\u00f6\u00dfe
+labelfontstyle = Beschriftung: Schriftstil
+labelbgcolor = Beschriftung: Hintergrundfarbe
+labelshowbg = Beschriftung: Hintergrund f\u00fcllen
+horizontal = horizontal
+vertical = vertikal
 showwidth = Breite anzeigen
 showlevel = Wasserstand anzeigen
 showminimum = Minimum anzeigen
 showmaximum = Maximum anzeigen
 showborder = Linie anzeigen
-transparent = Transparenz
-alpha = Alpha-Transparenzwert
+transparent = Transparent
+transparency = Transparenz
 showarea = Fl\u00e4che beschriften
-showmiddleheight = Mittlere H\u00f6he anzeigen
+showmiddleheight = Mittlere Tiefe anzeigen
 fillcolor = F\u00fcllfarbe
 wsplgen_cat1 = F\u00fcllfarbe 0.0 <= DIFF < 1
 wsplgen_cat2 = F\u00fcllfarbe 1.0 <= DIFF < 2
@@ -474,7 +519,7 @@
 editpoints = Eintr\u00e4ge editieren
 addWSP = Neues WSP Thema anlegen
 addWSPButton = WSP Thema
-selection = Selektion
+selection = Auswahl
 
 # Reference Curves
 reference_curve = Bezugslinie
@@ -489,3 +534,11 @@
 fix_parameters_export = Angepasste Koeffizienten
 fix_parameters = CSV
 sq_overview=\u00dcbersicht
+
+gauge_zero = Pegelnullpunkt
+gauge_q_unit = m\u00b3/s
+gauge_river_info_link = Gew\u00e4sserinfo
+gauge_info_link = Pegelinfo
+gauge_url = https://flys-intern.intevation.de/PegelInfo/
+gauge_river_url = https://flys-intern.intevation.de/GewaesserInfo/
+gauge_curve_link = Abflusskurve
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties	Fri Sep 28 12:15:40 2012 +0200
@@ -55,14 +55,15 @@
 scale = Scale
 databasket = Databasket
 databasket_loading = Loading Databasket content
-fix = TODO FIX ANALYSE TODO
-fixanalysis = TODO FIX ANALYSE TODO
+fix = Fixing
+fixanalysis = Fixing Analysis
 next = Next
 location_distance_state = Choose calculation location(s) / range [km]
 distance_state = Choose calculation range [km]
 waterlevel_ground_state = Choose differences betweeen waterlevel and ground [m]
 location = Location(s)
 locations = Locations
+single_location = Location
 distance = Range
 unitFrom = km
 unitTo = km a
@@ -156,6 +157,7 @@
 wqHistorical = Selection of Analyse Type
 calcTableTitle = Calculated Output
 helperPanelTitle = Input Support
+gaugePanelTitle = Gauge Information
 wqW = W at Gauge [cm]
 wqQ = Q [m\u00b3/s]
 wqWFree = W at free position [m+NHN]
@@ -171,9 +173,11 @@
 unitQFrom = m³/s&nbsp;-
 unitQTo = m³/s&nbsp;a
 unitQStep = m³/s
+main_channel = Main Channel
+total_channel = Total Channel
 footerHome = Home
-footerContact = Kontakt
-footerImpressum = Impressum
+footerContact = Contact
+footerImpressum = Legal info
 
 buttonNext = Next
 imageBack = images/back_en.png
@@ -188,8 +192,10 @@
 zoom_back = images/mag_zoom_back.png
 pan = images/hand.png
 askThemeRemove = Are you sure that you want to remove the selected theme / themes?
+add = Add
 
 discharge_curve = Discharge Curves at Gauges
+gauge_discharge_curve = Discharge Curves at Gauge
 computed_discharge_curve = Discharge Curve
 computed_discharge_curves = Discharge Curves
 longitudinal_section = Longitudinal Section Curve
@@ -201,6 +207,8 @@
 flow_velocity_export = Flow Velocity Export
 bedheight_middle = Middle Bed Height
 bedheight_middle_export = Middle Bed Height Export
+bed_longitudinal_section = Bed Quality
+bed_longitudinal_section_export = Bed Quality Export
 sq_relation_a = A Feinkornanteil
 sq_relation_b = B Sand (Suspensionstransport)
 sq_relation_c = C Sand (Geschiebetransport)
@@ -218,7 +226,16 @@
 fix_deltawt_curve = \u0394 W/t
 fix_longitudinal_section_curve = Longitudinal Section
 fix_derivate_curve = Derivate
+fix_vollmer_wq_curve = W/Q
+datacage_add_pair = Add difference pair
+load_diameter = Bedload Diameter
+bed_diameter = Bed Diameter
+soundings = Soundings
+bed_difference_year = Single Bedheight Differences
+bed_difference_epoch = Epoch Bedheight Differences
+bed_difference_height_year = Bedheight Difference per year
 
+exportATTooltip = Export as AT file
 
 waterlevel_export = Waterlevel Export
 waterlevel_report = Waterlevel Report
@@ -228,7 +245,7 @@
 discharge_longitudinal_section_report = Discharge Longitudinal Section Report
 durationcurve_export = Duration Curve Export
 durationcurve_report = Duration Curve Report
-dataexport = Datenexport
+dataexport = Data export
 csv = CSV
 wst = WST
 at = AT
@@ -250,6 +267,11 @@
 chart_themepanel_area_between = between ...
 against_x_axis = Over X-Axis
 
+gauge_mnq = around MNQ
+gauge_mq  = around MQ
+gauge_mhq = around MHQ
+gauge_hq5 = above HQ5
+
 ele_window_title = Elevation Node
 ele_window_label = Elevation settings in m \u00fc. NN.
 ele_window_x_col = X
@@ -279,11 +301,13 @@
 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_no_users = Error - no users found.
 error_no_waterlevel_pair_selected = Error - no waterlevel pair for building differences selected.
 error_same_waterlevels_in_pair = Error - minuend and subtrahend have to differ.
 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_wrong_date = Please enter valid dates.
+error_no_gaugeoverviewinfo_found = Error while fetching the river and gauge info
 
 error_feed_no_data = No input data found.
 error_feed_from_out_of_range = The lower value is bigger than the upper value.
@@ -319,6 +343,10 @@
 error_bad_dgm_river = You have selected a DEM for a wrong river.
 error_dialog_not_valid = One or more values are not valid.
 error_invalid_date = The entered date is not valid.
+error_same_location = Reference location equals selected location.
+error_contains_same_location = Target locations contains reference location.
+error_update_collection_attribute = Error while updating the collection attribut
+error_no_module_found = No modules found
 
 ## map related strings
 digitize = images/digitize.png
@@ -393,6 +421,10 @@
 dems = Digital Elevation Models
 hydrboundaries = Hydrological Boundaries
 gaugelocations = Location of Gauges
+single = Year
+epoch = Epoch
+bedheights = Bedheights
+datacage = Datacage
 
 # capabilities information panel
 addwmsInputTitle = Base URL of WMS service
@@ -425,6 +457,15 @@
 title = Title
 subtitle = Subtitle
 display_grid = Display grid
+display_logo = Display logo
+logo_placeh = Horiz. Place for logo
+logo_placev = Vertic. Place for logo
+top = top
+bottom = bottom
+center = center
+left = left
+right = right
+none = none
 
 linetype = Linetype
 textstyle = Textstyle
@@ -440,25 +481,28 @@
 textorientation = Textorientation
 linesize = Linesize
 pointsize = Pointsize
+bandwidth = Bandwidth
 pointcolor = Pointcolor
 showlines = Show lines
 showlinelabel = Show label
 showpointlabel = Show point label
-linelabelfont = Label: Font
-linelabelcolor = Label: Color
-linelabelsize = Label: Size
-linelabelstyle = Label: Style
-linelabelbgcolor = Label: Background Color
-linelabelshowbg = Label: Show Background
+labelfontface = Label: Font
+labelfontcolor = Label: Color
+labelfontsize = Label: Size
+labelfontstyle = Label: Style
+labelbgcolor = Label: Background Color
+labelshowbg = Label: Show Background
+horizontal = horizontal
+vertical = vertical
 showwidth = Show width
 showlevel = Show waterlevel
 showminimum = Show minimum
 showmaximum = Show maximum
 showborder = Show line
 transparent = Transparency
-alpha = Transparency Alpha
+transparency = Transparency
 showarea = Show Area
-showmiddleheight = Show middle height
+showmiddleheight = Show middle depth
 fillcolor = Fill Color
 wsplgen_cat1 = Fill Color 0.0 <= DIFF < 1
 wsplgen_cat2 = Fill Color 1.0 <= DIFF < 2
@@ -491,3 +535,11 @@
 fix_parameters_export = Adjusted coefficient
 fix_parameters = CSV
 sq_overview=Overview
+
+gauge_zero = Gauge zero ground
+gauge_q_unit = m\u00b3/s
+gauge_river_info_link = Riverinfo
+gauge_info_link = Gaugeinfo
+gauge_url = https://flys-intern.intevation.de/PegelInfo/
+gauge_river_url = https://flys-intern.intevation.de/GewaesserInfo/
+gauge_curve_link = Dischargecurve
--- a/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactService.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,6 +5,7 @@
 
 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.shared.model.Recommendation;
 
@@ -31,5 +32,19 @@
         String         factory,
         Recommendation recommendation
     ) throws ServerException;
+
+    /**
+     * Create a new GaugeDischageCurveArtifact
+     *
+     * @param collection the collection to add the artifact to
+     * @param river      the river
+     * @param gaugeref   reference id of the gauge
+     */
+    public Artifact createGaugeDischargeCurverArtifact(
+            Collection collection,
+            String locale,
+            String river,
+            Long   gaugeref
+    ) throws ServerException;
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ArtifactServiceAsync.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,6 +3,7 @@
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.Collection;
 
 import de.intevation.flys.client.shared.model.Recommendation;
 
@@ -19,5 +20,13 @@
         String         factory,
         Recommendation recommendation,
         AsyncCallback<Artifact> callback);
+
+    public void createGaugeDischargeCurverArtifact(
+        Collection collection,
+        String locale,
+        String river,
+        Long   gaugeref,
+        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/GaugeOverviewInfoService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,17 @@
+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.RiverInfo;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+@RemoteServiceRelativePath("gaugeoverviewinfo")
+public interface GaugeOverviewInfoService extends RemoteService {
+
+    public RiverInfo getRiverInfo(String river) throws ServerException;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/GaugeOverviewInfoServiceAsync.java	Fri Sep 28 12:15:40 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.RiverInfo;
+
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public interface GaugeOverviewInfoServiceAsync {
+
+    public void getRiverInfo(String river, AsyncCallback<RiverInfo> callback);
+}
+
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ModuleService.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,22 @@
+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.Module;
+
+@RemoteServiceRelativePath("modules")
+public interface ModuleService extends RemoteService {
+
+    /**
+     * Returns the list of available modules of a user
+     *
+     * @param locale The locale used for the request
+     * @return a String array of all available modules
+     *
+     */
+    public Module[] list(String locale) throws ServerException;
+}
+
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/ModuleServiceAsync.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,12 @@
+package de.intevation.flys.client.client.services;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import de.intevation.flys.client.shared.model.Module;
+
+public interface ModuleServiceAsync {
+
+    public void list(String locale,
+        AsyncCallback<Module[]> callback);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/AbstractUIProvider.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,10 +1,6 @@
 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.util.SC;
 import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.Canvas;
@@ -26,10 +22,12 @@
 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 java.util.ArrayList;
+import java.util.List;
+
 
 /**
  * An abstract UIProvider that provides some basic methods.
@@ -75,6 +73,7 @@
      *
      * @param handler A new StepBackHandler.
      */
+    @Override
     public void addStepBackHandler(StepBackHandler handler) {
         if (handler != null) {
             backHandlers.add(handler);
@@ -87,6 +86,7 @@
      *
      * @param handler A new StepForwardHandler.
      */
+    @Override
     public void addStepForwardHandler(StepForwardHandler handler) {
         if (handler != null) {
             forwardHandlers.add(handler);
@@ -128,6 +128,7 @@
      *
      * @param e The click event.
      */
+    @Override
     public void onClick(ClickEvent e) {
         List<String> errors = validate();
         if (errors == null || errors.isEmpty()) {
@@ -186,6 +187,7 @@
         Img back   = new Img(url, 16, 16);
 
         back.addClickHandler(new ClickHandler() {
+            @Override
             public void onClick(ClickEvent event) {
                 fireStepBackEvent(new StepBackEvent(targetState));
             }
@@ -201,6 +203,7 @@
      * @param helperContainer A container that is used to position helper
      * widgets.
      */
+    @Override
     public void setContainer(VLayout helperContainer) {
         this.helperContainer = helperContainer;
     }
@@ -211,16 +214,19 @@
      *
      * @param art An artifact containing status information.
      */
+    @Override
     public void setArtifact(Artifact art) {
         this.artifact = art;
     }
 
 
+    @Override
     public void setCollection(Collection collection) {
         this.collection = collection;
     }
 
 
+    @Override
     public void setParameterList(ParameterList list) {
         this.parameterList = list;
     }
@@ -314,6 +320,7 @@
      *
      * @return a Canvas object that displays <i>data</i>.
      */
+    @Override
     public abstract Canvas create(DataList data);
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,10 +2,14 @@
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.VerticalAlignment;
 import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Img;
 import com.smartgwt.client.widgets.Window;
 import com.smartgwt.client.widgets.events.CloseClickEvent;
 import com.smartgwt.client.widgets.events.CloseClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.Layout;
 import com.smartgwt.client.widgets.layout.VLayout;
 import com.smartgwt.client.widgets.tab.TabSet;
@@ -112,6 +116,8 @@
     /** The layout. */
     protected Layout layout;
 
+    protected VLayout lockScreen;
+
     protected int artifactsQueue;
     protected int recommendationQueue;
     protected Stack<Recommendation> newRecommendations;
@@ -139,9 +145,9 @@
         this.layout        = new VLayout();
         this.parameterList = new ParameterList(
             flys, this, messages.new_project());
-        this.artifactsQueue     = 0;
+        this.artifactsQueue      = 0;
         this.recommendationQueue = 0;
-        this.newRecommendations = new Stack<Recommendation>();
+        this.newRecommendations  = new Stack<Recommendation>();
 
         this.currentKm = -1d;
         this.minKm = -1d;
@@ -216,8 +222,10 @@
      * This method handles the initial layout stuff.
      */
     protected void init() {
-        setWidth(950);
-        setHeight(650);
+        setWidth(1010);
+        setHeight(700);
+
+        setMaximized(true);
 
         layout.setWidth100();
 
@@ -321,6 +329,41 @@
     }
 
 
+    /** Disables input, grey out, show spinning wheel of joy. */
+    public void lockUI() {
+        if (lockScreen == null) {
+            lockScreen = new VLayout();
+            lockScreen.setWidth100();
+            lockScreen.setHeight100();
+            lockScreen.setBackgroundColor("#7f7f7f");
+            lockScreen.setOpacity(50);
+            lockScreen.setAlign(VerticalAlignment.CENTER);
+            lockScreen.setDefaultLayoutAlign(VerticalAlignment.CENTER);
+
+            HLayout inner = new HLayout();
+            inner.setAlign(Alignment.CENTER);
+            inner.setDefaultLayoutAlign(Alignment.CENTER);
+            inner.setOpacity(100);
+
+            Img img = new Img(
+                GWT.getHostPageBaseURL() + messages.loadingImg(),
+                25, 25);
+
+            inner.addMember(img);
+
+            lockScreen.addMember(inner);
+        }
+
+        layout.addChild(lockScreen);
+    }
+
+
+    /** Enable input, remove grey, remove spinning wheel of joy. */
+    public void unlockUI() {
+        layout.removeChild(lockScreen);
+    }
+
+
     /**
      * This method returns true, if the Collection is new and no plugins has
      * been chosen.
@@ -384,8 +427,8 @@
 
     protected void artifactChanged() {
         ArtifactDescription desc = getArtifact().getArtifactDescription();
-        OutputMode[] outs        = desc.getOutputModes();
-        final Recommendation[] recom   = desc.getRecommendations();
+        //OutputMode[] outs        = desc.getOutputModes();
+        final Recommendation[] recom = desc.getRecommendations();
 
         Collection c = getCollection();
 
@@ -596,7 +639,12 @@
     @Override
     public void onCloseClick(CloseClickEvent event) {
         if (collection != null) {
-            flys.closeProject(collection.identifier());
+            if(artifact != null) {
+                flys.closeProject(collection.identifier());
+            }
+            else {
+                flys.getProjectList().deleteCollection(collection);
+            }
         }
         else {
             hide();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacagePairWidget.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacagePairWidget.java	Fri Sep 28 12:15:40 2012 +0200
@@ -20,13 +20,14 @@
 
 
 /**
- * Widget showing two Datacages and a plus-button.
- * Insert a record into a listgrid when plus-button clicked.
+ * Widget showing two Datacages and a add-this-button.
+ * Insert a record into a listgrid when add-this-button clicked.
  */
 public class DatacagePairWidget
 extends      VLayout
 {
-    protected FLYSConstants messages =
+    /** i18n resource. */
+    protected FLYSConstants MSG =
         GWT.create(FLYSConstants.class);
 
     /** The "remote" ListGrid to insert data to when add-button is clicked. */
@@ -71,8 +72,9 @@
         hLayout.addMember(firstDatacageWidget);
         hLayout.addMember(secondDatacageWidget);
 
-        // TODO: i18n + icon
-        Button plusBtn = new Button("+");
+        // TODO: icon
+        Button plusBtn = new Button(MSG.datacage_add_pair());
+        plusBtn.setAutoFit(true);
         plusBtn.addClickHandler(new ClickHandler() {
             @Override
             public void onClick(ClickEvent event) {
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWidget.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWidget.java	Fri Sep 28 12:15:40 2012 +0200
@@ -28,6 +28,8 @@
 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
 
+import com.smartgwt.client.widgets.grid.HoverCustomizer;
+
 import de.intevation.flys.client.shared.model.Artifact;
 import de.intevation.flys.client.shared.model.User;
 import de.intevation.flys.client.shared.model.ToLoad;
@@ -137,6 +139,32 @@
         treeGrid.setEmptyMessage(messages.databasket_loading());
         treeGrid.setLoadingDataMessage(messages.databasket_loading());
 
+        treeGrid.setHoverMoveWithMouse(true);
+        treeGrid.setCanHover(true);
+        treeGrid.setShowHover(true);
+        treeGrid.setHoverOpacity(75);
+
+        treeGrid.setHoverCustomizer(new HoverCustomizer() {
+            @Override
+            public String hoverHTML(Object value,
+                ListGridRecord record,
+                int rowNum,
+                int colNum
+                ) {
+                if(record instanceof TreeNode) {
+                    TreeNode hoveredTreeNode = (TreeNode)record;
+                    String info = hoveredTreeNode.getAttribute("info");
+                    if (info == null) {
+                        info = hoveredTreeNode.getName();
+                    }
+                    return info;
+                }
+                else {
+                    return "";// should not happen
+                }
+            }
+        });
+
         treeGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() {
             @Override
             public void onRecordDoubleClick(RecordDoubleClickEvent event) {
@@ -358,6 +386,7 @@
     }
 
 
+    /** Get meta-data and populate tree with it. */
     protected void triggerTreeBuilding() {
         Config config = Config.getInstance();
         String locale = config.getLocale();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleArrayPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -100,7 +100,7 @@
     public void setValues(double[] values) {
         NumberFormat f = NumberFormat.getDecimalFormat();
 
-        if(values.length == 0) {
+        if(values == null || values.length == 0) {
             ti.clearValue();
             return;
         }
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleInputPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DoubleInputPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,32 +1,25 @@
 package de.intevation.flys.client.client.ui;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.google.gwt.core.client.GWT;
-
 import com.google.gwt.i18n.client.NumberFormat;
-
 import com.smartgwt.client.util.SC;
-
 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.TextItem;
-
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
 import de.intevation.flys.client.client.FLYSConstants;
-
 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 java.util.ArrayList;
-import java.util.List;
-
 /**
  * This UIProvider creates a panel for location or distance input.
  *
@@ -67,10 +60,17 @@
         Label title = new Label(data.get(0).getDescription());
         title.setHeight("25px");
 
+        DataItem defaultItem = data.get(0).getDefault();
+
         DynamicForm form = new DynamicForm();
         inputPanel = new TextItem();
         inputPanel.setTitle("outliers");
         inputPanel.setShowTitle(false);
+
+        if (defaultItem != null) {
+            inputPanel.setValue(defaultItem.getStringValue());
+        }
+
         form.setFields(inputPanel);
 
         layout.addMember(title);
@@ -131,7 +131,7 @@
                 new DataItem[] { item }));
         }
 
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ExportPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ExportPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -68,6 +68,9 @@
             List<Facet> facets = mode.getFacets();
 
             for (Facet facet: facets) {
+                if (name.equals("fix_wq_curve_at_export")) {
+                    continue;
+                }
                 layout.addMember(createExportButton(name, facet.getName()));
             }
         }
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSView.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSView.java	Fri Sep 28 12:15:40 2012 +0200
@@ -5,6 +5,8 @@
 
 
 /**
+ * Vertically speaking the main part of the ui (containing projectlist
+ * and workspace).
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class FLYSView extends Canvas {
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/FLYSWorkspace.java	Fri Sep 28 12:15:40 2012 +0200
@@ -7,6 +7,7 @@
 
 
 /**
+ * "Workspace" canvas showing the CollectionViews (subwindows).
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class FLYSWorkspace extends Canvas {
@@ -29,6 +30,9 @@
      */
     public FLYSWorkspace() {
         views = new HashMap<String, CollectionView>();
+
+        setWidth("100%");
+        setHeight("100%");
     }
 
 
@@ -39,10 +43,8 @@
      * @param collectionView A new CollectionView.
      */
     public void addView(String uuid, CollectionView collectionView) {
-        int num    = views != null ? views.size() : 0;
-        int factor = num % MAX_WINDOWS;
-
-        collectionView.moveTo(factor * WINDOW_OFFSET, factor * WINDOW_OFFSET);
+        collectionView.moveTo(0, 0);
+        collectionView.setMaximized(true);
 
         views.put(uuid, collectionView);
         addChild(collectionView);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,209 @@
+package de.intevation.flys.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+
+import com.smartgwt.client.types.Overflow;
+import com.smartgwt.client.widgets.events.ResizedEvent;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+import com.smartgwt.client.widgets.layout.SectionStackSection;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.services.GaugeOverviewInfoService;
+import de.intevation.flys.client.client.services.GaugeOverviewInfoServiceAsync;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+/**
+ * The GaugePanel is intendet to be used within a SectionStackSection
+ * It extends the VLayout by two methods to show and hide the
+ * section stack section.
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugePanel extends VLayout implements ResizedHandler {
+
+    /** SectionStackSection where this GaugePanel belongs in*/
+    private SectionStackSection sectionStack;
+
+    /** Name of the river */
+    private String river;
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    private FLYS flys;
+
+    protected GaugeOverviewInfoServiceAsync gaugeOverviewInfoService =
+        GWT.create(GaugeOverviewInfoService.class);
+
+    protected GaugeTree gaugetree;
+
+    protected RiverInfoPanel riverinfopanel;
+
+    /**
+     * Creates a new VLayout with a SectionStackSection
+     * The GaugePanel's SectionStackSection is hidden by default.
+     *
+     * @param flys The FLYS object
+     * @param sectionStack The section stack section to place the VLayout in.
+     */
+    public GaugePanel(FLYS flys, SectionStackSection sectionStack) {
+        gaugetree = new GaugeTree(flys);
+        setOverflow(Overflow.HIDDEN);
+        sectionStack.setHidden(true);
+        sectionStack.setItems(this);
+        this.sectionStack = sectionStack;
+        setStyleName("gaugepanel");
+        addResizedHandler(this);
+    }
+
+    /**
+     * Sets and loads the river data if river is not the current set river
+     */
+    public void setRiver(String river) {
+        if (!river.equals(this.river)) {
+            this.river = river;
+            this.refresh();
+        }
+    }
+
+    /**
+     * Sets the data and closes not corresponding folds in the gauge tree
+     */
+    public void setData(DataList[] data) {
+        gaugetree.setData(data);
+    }
+
+    /**
+     * Loads the river info and renders it afterwards
+     */
+    public void refresh() {
+        gaugeOverviewInfoService.getRiverInfo(this.river, new AsyncCallback<RiverInfo>() {
+            public void onFailure(Throwable e) {
+                GWT.log("Could not load the river info." + e);
+            }
+
+            public void onSuccess(RiverInfo riverinfo) {
+                GWT.log("Loaded river info");
+                renderGaugeOverviewInfo(riverinfo);
+            }
+        });
+    }
+
+    public void renderGaugeOverviewInfo(RiverInfo riverinfo) {
+        removeMembers(getMembers());
+
+        riverinfopanel = new RiverInfoPanel(riverinfo);
+        addMember(riverinfopanel);
+        addMember(gaugetree);
+
+        gaugetree.setGauges(riverinfo);
+    }
+
+    @Override
+    public void onResized(ResizedEvent event) {
+        /* this height calculation is only an approximation and doesn't reflect
+         * the real height of the the gaugetree. */
+        int height = getInnerContentHeight() -
+            (RiverInfoPanel.HEIGHT +
+            (2 * RiverInfoPanel.BORDER_WIDTH) +
+            (2 * RiverInfoPanel.PADDING) +
+            (2 * RiverInfoPanel.MARGIN));
+
+        if (height < 0) {
+            height = 0;
+        }
+
+        gaugetree.setHeight("" + height + "px");
+    }
+
+
+    /**
+     * Hide the section stack section.
+     */
+    public void hide() {
+        GWT.log("GaugePanel - hide");
+        this.sectionStack.setHidden(true);
+    }
+
+    /**
+     * Show the section stack section.
+     */
+    public void show() {
+        GWT.log("GaugePanel - show");
+        this.sectionStack.setHidden(false);
+    }
+
+    class RiverInfoPanel extends HorizontalPanel {
+
+        public final static int HEIGHT = 30;
+        public final static int BORDER_WIDTH = 3;
+        public final static int PADDING = 8;
+        public final static int MARGIN = 10;
+
+        public RiverInfoPanel(RiverInfo riverinfo) {
+            setStyleName("riverinfopanel");
+            setHeight("" + HEIGHT + "px");
+            setVerticalAlignment(ALIGN_MIDDLE);
+
+            NumberFormat nf = NumberFormat.getDecimalFormat();
+
+            addLabel(riverinfo.getName(), false);
+
+            String kmtext = "";
+            Double start = riverinfo.getKmStart();
+            Double end = riverinfo.getKmEnd();
+
+            if (!riverinfo.isKmUp()) {
+                Double tmp = end;
+                end = start;
+                start = tmp;
+            }
+            if (end != null) {
+                kmtext += nf.format(end);
+                kmtext += " - ";
+            }
+            if (start != null) {
+                kmtext += nf.format(start);
+            }
+            kmtext += " km";
+
+            addLabel(kmtext, false);
+
+            String qtext = "";
+            Double qmin = riverinfo.getMinQ();
+            Double qmax = riverinfo.getMaxQ();
+            if (qmin != null) {
+                qtext += nf.format(qmin);
+                qtext += " " + MSG.gauge_q_unit();
+                qtext += " - ";
+            }
+            if (qmax != null) {
+                qtext += nf.format(qmax);
+                qtext += " " + MSG.gauge_q_unit();
+            }
+
+            addLabel(qtext, false);
+
+            Long number = riverinfo.getOfficialNumber();
+            String url = number != null ?
+                MSG.gauge_river_url() + number :
+                MSG.gauge_river_url();
+            Anchor anchor = new Anchor(MSG.gauge_river_info_link(), url);
+            add(anchor);
+        }
+
+        private void addLabel(String text, boolean wordwrap) {
+            Label label = new Label(text, wordwrap);
+            add(label);
+            setCellHeight(label, "" + HEIGHT + "px");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,465 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.DecoratorPanel;
+import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.ScrollPanel;
+import com.google.gwt.user.client.ui.Tree;
+import com.google.gwt.user.client.ui.TreeItem;
+
+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.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.GaugeInfo;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+
+public class GaugeTree extends ScrollPanel {
+
+    private FLYS flys;
+    private Tree tree;
+    private DataList[] data;
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    public GaugeTree(FLYS flys) {
+        this.flys = flys;
+        tree = new Tree();
+        setWidget(tree);
+    }
+
+    /**
+     * Resets the items of the tree.
+     * If the list of gauges is empty or null the tree will be empty.
+     */
+    public void setGauges(RiverInfo riverinfo) {
+        tree.clear();
+
+        List<GaugeInfo> gauges = riverinfo.getGauges();
+
+        if (gauges != null && !gauges.isEmpty()) {
+
+            ArrayList<GaugeInfo> emptygauges = new ArrayList<GaugeInfo>();
+
+            if (!riverinfo.isKmUp()) {
+                for (GaugeInfo gauge : gauges) {
+                    addGauge(gauge, emptygauges);
+                }
+            }
+            else {
+                for (int i = gauges.size()-1; i >= 0; i--) {
+                    GaugeInfo gauge = gauges.get(i);
+                    addGauge(gauge, emptygauges);
+                }
+            }
+
+            // put empty gauges to the end
+            for (GaugeInfo gauge : emptygauges) {
+                addGauge(gauge);
+            }
+
+            open();
+        }
+    }
+
+    private void addGauge(GaugeInfo gauge, List<GaugeInfo> empty) {
+        if (gauge.getKmStart() != null && gauge.getKmEnd() != null) {
+            addGauge(gauge);
+        }
+        else {
+            empty.add(gauge);
+        }
+    }
+
+    private void addGauge(GaugeInfo gauge) {
+        GaugeInfoItem gaugeitem = new GaugeInfoItem(flys, gauge);
+        tree.addItem(gaugeitem);
+    }
+
+    public void openAll() {
+        GWT.log("GaugeTree - openAll");
+        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
+            TreeItem item = it.next();
+            item.setState(true);
+        }
+    }
+
+    public void setData(DataList[] data) {
+        this.data = data;
+        if (tree.getItemCount() > 0) {
+            open();
+        }
+    }
+
+    public void open() {
+        ArrayList<Double> locations = new ArrayList<Double>();
+
+        if (data != null && data.length > 0) {
+            for (int i = 0; i < data.length; i++) {
+                DataList dl = data[i];
+                String state = dl.getState();
+                GWT.log("GaugeTree - setData " + state);
+                if (state.equals("state.winfo.location_distance")) {
+                    Double ldfrom = null;
+                    Double ldto = null;
+
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        String label = d.getLabel();
+                        GWT.log("GaugeTree - setData - label " + label + " " + d.getStringValue());
+                        if (label.equals("ld_from")) {
+                            ldfrom = getDoubleValue(d);
+                        }
+                        else if (label.equals("ld_to")) {
+                            ldto = getDoubleValue(d);
+                        }
+                        else if (label.equals("ld_locations")) {
+                            getLocationsFromData(locations, d);
+                            openOnLocations(locations);
+                            return;
+                        }
+                    }
+                    if (ldfrom != null) {
+                        openOnDistance(ldfrom, ldto);
+                        return;
+                    }
+                }
+                else if(state.equals("state.winfo.distance_only") ||
+                        state.equals("state.winfo.distance")) {
+                    Double ldfrom = null;
+                    Double ldto = null;
+
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        String label = d.getLabel();
+                        GWT.log("GaugeTree - setData - label " + label + " " + d.getStringValue());
+                        if (label.equals("ld_from")) {
+                            ldfrom = getDoubleValue(d);
+                        }
+                        else if (label.equals("ld_to")) {
+                            ldto = getDoubleValue(d);
+                        }
+                    }
+
+                    if (ldfrom != null) {
+                        openOnDistance(ldfrom, ldto);
+                        return;
+                    }
+                        }
+                else if (state.equals("state.winfo.location")) {
+                    getLocations("ld_locations", locations, dl);
+                    openOnLocations(locations);
+                    return;
+                }
+                else if (state.equals("state.winfo.reference.curve.input.start")) {
+                    getLocations("reference_startpoint", locations, dl);
+                }
+                else if (state.equals("state.winfo.reference.curve.input.end")) {
+                    getLocations("reference_endpoint", locations, dl);
+                }
+                else if (state.equals("state.winfo.historicalq.reference_gauge")) {
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        String label = d.getLabel();
+                        if (label.equals("reference_gauge")) {
+                            String tmp = d.getStringValue();
+                            if (tmp != null) {
+                                Long gaugereference = Long.valueOf(tmp);
+                                if (gaugereference != null) {
+                                    openOnReference(gaugereference);
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (!locations.isEmpty()) {
+            openOnLocations(locations);
+        }
+        else {
+            openAll();
+        }
+    }
+
+    private void getLocations(String labelname, List<Double> locations, DataList dl) {
+        for (int j = dl.size()-1; j >= 0; --j) {
+            Data d = dl.get(j);
+            String label = d.getLabel();
+            if (label.equals(labelname)) {
+                getLocationsFromData(locations, d);
+            }
+        }
+    }
+
+    private void getLocationsFromData(List<Double> locations, Data data) {
+        DataItem[] items = data.getItems();
+        for (int k = 0; k < items.length; k++) {
+            String tmp = items[k].getStringValue();
+            GWT.log("GaugeTree - getLocationsFromData " + tmp);
+            if (tmp != null) {
+                if (tmp.contains(" ")) {
+                    // string contains several values ...
+                    String[] values = tmp.split(" ");
+                    for(int i=0; i < values.length; i++) {
+                        Double value = Double.valueOf(values[i]);
+                        if (value != null) {
+                            locations.add(value);
+                        }
+                    }
+                }
+                else {
+                    Double value = Double.valueOf(tmp);
+                    if (value != null) {
+                        locations.add(value);
+                    }
+                }
+            }
+        }
+    }
+
+    private Double getDoubleValue(Data d) {
+        String tmp = d.getStringValue();
+        if (tmp != null) {
+            return Double.valueOf(tmp);
+        }
+        return null;
+    }
+
+    public void openOnReference(Long number) {
+        GWT.log("GaugeTree - openOnReference " + number);
+        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
+            TreeItem item = it.next();
+            if (item instanceof GaugeInfoItem) {
+                GaugeInfoItem gitem = (GaugeInfoItem)item;
+                if (gitem.getReference().equals(number)) {
+                    item.setState(true);
+                }
+                else {
+                    item.setState(false);
+                }
+            }
+        }
+    }
+
+    public void openOnDistance(Double start, Double end) {
+        GWT.log("GaugeTree - openOnDistance " + start + " " + end + " " +
+                tree.getItemCount());
+
+        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
+            TreeItem item = it.next();
+            /* Strange stuff is happening here:
+             * GWT Tree.treeItemIterator returns another TreeItem for each
+             * GaugeInfoItem */
+            if (item instanceof GaugeInfoItem) {
+                boolean setstate = false;
+                GaugeInfoItem gitem = (GaugeInfoItem)item;
+                if (end == null) {
+                    if (gitem.getStart() >= start) {
+                        setstate = true;
+                    }
+                }
+                else {
+                    GWT.log("GaugeTree - openOnDistance gitem " + gitem.getStart() + " " + gitem.getEnd());
+                    if ((start >= gitem.getStart() && start <= gitem.getEnd()) ||
+                            (end >= gitem.getStart() && end <= gitem.getEnd()) ||
+                            (start <= gitem.getStart() && end >= gitem.getEnd())) {
+                        setstate = true;
+                            }
+                }
+                item.setState(setstate);
+            }
+        }
+    }
+
+    public void openOnLocations(List<Double> locations) {
+        GWT.log("GaugeTree - openOnLocations " + locations + " " +
+                tree.getItemCount());
+
+        if (locations == null || locations.isEmpty()) {
+            return;
+        }
+
+        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
+            TreeItem item = it.next();
+            if (item instanceof GaugeInfoItem) {
+                GaugeInfoItem gitem = (GaugeInfoItem)item;
+                boolean isset = false;
+                for (Double location: locations) {
+                    if (locations == null) {
+                        continue;
+                    }
+                    if (location >= gitem.getStart() &&
+                            location <= gitem.getEnd()) {
+                        isset = true;
+                        break;
+                            }
+                }
+                item.setState(isset);
+            }
+        }
+    }
+
+    class GaugeInfoItem extends TreeItem {
+
+        private GaugeInfo gauge;
+
+        public GaugeInfoItem(FLYS flys, GaugeInfo gauge) {
+            GaugeInfoHead gaugeinfohead = new GaugeInfoHead(flys, gauge);
+            GaugeInfoPanel gaugeinfopanel = new GaugeInfoPanel(gauge);
+            setWidget(gaugeinfohead);
+            addItem(gaugeinfopanel);
+            this.gauge = gauge;
+        }
+
+        public Double getStart() {
+            return gauge.getKmStart();
+        }
+
+        public Double getEnd() {
+            return gauge.getKmEnd();
+        }
+
+        public Long getReference() {
+            return gauge.getOfficialNumber();
+        }
+    }
+
+    class GaugeInfoHead extends HLayout {
+
+        public GaugeInfoHead(FLYS flys, GaugeInfo gauge) {
+            setStyleName("gaugeinfohead");
+            setAutoHeight();
+            setAutoWidth();
+
+            NumberFormat nf = NumberFormat.getDecimalFormat();
+
+            Label label = new Label(gauge.getName(), true);
+            addMember(label);
+
+            Double start;
+            Double end;
+
+            if (!gauge.isKmUp()) {
+                start = gauge.getKmStart();
+                end   = gauge.getKmEnd();
+            }
+            else {
+                start = gauge.getKmEnd();
+                end   = gauge.getKmStart();
+            }
+
+            String kmtext = "";
+            if (start != null) {
+                kmtext += nf.format(start);
+                kmtext += " - ";
+            }
+            if (end != null) {
+                kmtext += nf.format(end);
+            }
+            if (start != null || end != null) {
+                kmtext += " km";
+            }
+
+            label = new Label(kmtext);
+
+            addMember(label);
+
+            Double station = gauge.getStation();
+            if (station != null) {
+                String stext = nf.format(station);
+                stext += " km";
+                label = new Label(stext);
+                addMember(label);
+            }
+
+            Long number = gauge.getOfficialNumber();
+            String url = number != null ?
+                MSG.gauge_url() + number :
+                MSG.gauge_url();
+            Anchor anchor = new Anchor(MSG.gauge_info_link(), url);
+            addMember(anchor);
+
+            addMember(new GaugeCurveAnchor(flys, gauge));
+        }
+    }
+
+    class GaugeCurveAnchor extends Anchor implements ClickHandler {
+
+        private FLYS flys;
+        private GaugeInfo gauge;
+
+        public GaugeCurveAnchor(FLYS flys, GaugeInfo gauge) {
+            super(MSG.gauge_curve_link());
+            this.flys = flys;
+            this.gauge = gauge;
+
+            addClickHandler(this);
+        }
+
+        public void onClick(ClickEvent ev) {
+            GWT.log("GaugeCurveAnchor - onClick " + gauge.getRiverName() +
+                    " " + gauge.getOfficialNumber());
+            flys.newGaugeDischargeCurve(gauge.getRiverName(),
+                    gauge.getOfficialNumber());
+        }
+    }
+
+    class GaugeInfoPanel extends DecoratorPanel {
+
+        public GaugeInfoPanel(GaugeInfo gauge) {
+            setStyleName("gaugeinfopanel");
+            Grid grid = new Grid(4, 2);
+
+            NumberFormat nf = NumberFormat.getDecimalFormat();
+
+            Double minw = gauge.getMinW();
+            Double maxw = gauge.getMaxW();
+            if (minw != null && maxw != null) {
+                grid.setText(0, 0, MSG.wq_value_q());
+                grid.setText(0, 1, "" + nf.format(minw) +
+                        " - " + nf.format(maxw));
+            }
+
+            Double minq = gauge.getMinQ();
+            Double maxq = gauge.getMaxQ();
+            if (minq != null && maxq != null) {
+                grid.setText(1, 0, MSG.wq_value_w());
+                grid.setText(1, 1, "" + nf.format(minq) +
+                        " - " + nf.format(maxq));
+            }
+
+            Double aeo = gauge.getAeo();
+            if (aeo != null) {
+                grid.setText(2, 0, "AEO [km²]");
+                grid.setText(2, 1, "" + nf.format(aeo));
+            }
+
+            Double datum = gauge.getDatum();
+            if (datum != null) {
+                grid.setText(3, 0, MSG.gauge_zero() + " [" +
+                        gauge.getWstUnit() + "]");
+                grid.setText(3, 1, "" + nf.format(datum));
+            }
+
+            setWidget(grid);
+        }
+    }
+
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/LinkSelection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/LinkSelection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 
 import com.smartgwt.client.types.VerticalAlignment;
 import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Img;
 import com.smartgwt.client.widgets.Label;
 import com.smartgwt.client.widgets.form.DynamicForm;
 import com.smartgwt.client.widgets.form.fields.LinkItem;
@@ -157,6 +158,10 @@
         }
         layout.setAlign(VerticalAlignment.TOP);
 
+        String baseUrl = GWT.getHostPageBaseURL();
+        Img map = new Img(baseUrl + messages.riverMap(), 400, 452);
+        helperContainer.addMember(map);
+
         return layout;
     }
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/LocationDistancePanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -452,14 +452,14 @@
             }
         };
 
-        ListGridField addfrom = new ListGridField ("", "");
+        ListGridField addfrom = new ListGridField ("from", MESSAGES.from());
         addfrom.setType (ListGridFieldType.ICON);
-        addfrom.setWidth (20);
+        addfrom.setWidth (30);
         addfrom.setCellIcon(baseUrl + MESSAGES.markerGreen());
 
-        ListGridField addto2 = new ListGridField ("", "");
+        ListGridField addto2 = new ListGridField ("to", MESSAGES.to());
         addto2.setType (ListGridFieldType.ICON);
-        addto2.setWidth (20);
+        addto2.setWidth (30);
         addto2.setCellIcon(baseUrl + MESSAGES.markerRed());
 
         locationDistanceTable.addCellClickHandler (new CellClickHandler () {
@@ -601,7 +601,18 @@
         Data       dLocations = getData(items, "ld_locations");
         DataItem[] lItems     = dLocations.getItems();
 
-        String value = lItems[0].getLabel();
+        String[] splitted = lItems[0].getStringValue().split(" ");
+        String value = "";
+        for (int i = 0; i < splitted.length; i++) {
+            try {
+                NumberFormat nf = NumberFormat.getDecimalFormat();
+                double dv = Double.parseDouble(splitted[i]);
+                value += nf.format(dv) + " ";
+            }
+            catch(NumberFormatException nfe) {
+                value += splitted[i] + " ";
+            }
+        }
 
         Label selected = new Label(value);
         selected.setWidth(130);
@@ -1013,7 +1024,7 @@
             data.add(dMode);
         }
 
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
@@ -1323,7 +1334,7 @@
         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")) {
+                if (dl.getState().endsWith("river")) {
                     for (int j = 0; j < dl.size(); j++) {
                         Data d = dl.get(j);
                         DataItem[] di = d.getItems();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ModuleSelection.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,8 +3,10 @@
 import java.util.LinkedHashMap;
 
 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.Label;
 import com.smartgwt.client.widgets.form.DynamicForm;
@@ -12,12 +14,16 @@
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
+import de.intevation.flys.client.client.services.ModuleService;
+import de.intevation.flys.client.client.services.ModuleServiceAsync;
 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.Module;
 
+import de.intevation.flys.client.client.Config;
 import de.intevation.flys.client.client.FLYSConstants;
 
 /**
@@ -33,34 +39,21 @@
     /** 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   = "new_map";
-
-    /** Constant value for the CHART plugin.*/
-    public static final String FIELD_PLUGIN_CHART = "new_chart";
-
-    /** Constant value for the FIX plugin.*/
-    public static final String FIELD_PLUGIN_FIX   = "fixanalysis";
-
-
     /** The module checkboxes.*/
     protected RadioGroupItem radio;
 
+    /** */
+    protected Module[] modules;
+
+    /** The ModuleService used to retrieve the available modules of a user.*/
+    protected ModuleServiceAsync moduleService = GWT.create(ModuleService.class);
+
 
     /**
      * The default constructor.
      */
     public ModuleSelection() {
+        readModules();
     }
 
 
@@ -73,6 +66,7 @@
      * @return the module selection combined with the river selection.
      */
     public Canvas create(DataList data) {
+        GWT.log("ModuleSelection - create()");
         VLayout newLayout = new VLayout();
         newLayout.setMembersMargin(10);
         newLayout.setAlign(VerticalAlignment.TOP);
@@ -85,6 +79,45 @@
         return newLayout;
     }
 
+    private void readModules() {
+        Config config = Config.getInstance();
+        String locale = config.getLocale();
+
+        moduleService.list(locale, new AsyncCallback<Module[]>() {
+            @Override
+            public void onFailure(Throwable caught) {
+                GWT.log("Could not recieve a list of modules.");
+                SC.warn(MSG.getString(caught.getMessage()));
+            }
+
+            @Override
+            public void onSuccess(Module[] newmodules) {
+                GWT.log("Retrieved " + newmodules.length + " modules.");
+                modules = newmodules;
+                setModules();
+            }
+        });
+    }
+
+    private void setModules() {
+        LinkedHashMap values = new LinkedHashMap();
+
+        if (this.modules!= null) {
+            for(Module module : this.modules) {
+                values.put(module.getName(), module.getLocalizedName());
+                if (module.isSelected()) {
+                    GWT.log("Module " + module.getName() + " is selected.");
+                    if (radio != null) {
+                        radio.setDefaultValue(module.getName());
+                        GWT.log("Setting " + module.getName() + " as selected.");
+                    }
+                }
+            }
+        }
+        if (radio != null) {
+            radio.setValueMap(values);
+        }
+    }
 
     /**
      * Creates a widget that displays a checkbox for each module.
@@ -102,22 +135,13 @@
         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.new_chart());
-        values.put(FIELD_PLUGIN_MAP, messages.new_map());
 
         radio.setShowTitle(false);
         radio.setVertical(true);
-        radio.setValueMap(values);
 
-        LinkedHashMap initial = new LinkedHashMap();
-        initial.put(FIELD_PLUGIN, FIELD_PLUGIN_WINFO);
+        setModules();
 
         form.setFields(radio);
-        form.setValues(initial);
 
         layout.addMember(label);
         layout.addMember(form);
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/MultiPeriodPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MultiPeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -178,7 +178,7 @@
                         null,
                         new DataItem[] { item }));
         }
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MultipleLocationPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -86,7 +86,7 @@
         }
         catch(java.util.MissingResourceException mre) {
             GWT.log("Cannot find translation for data item name : " + getDataItemName());
-            labelString = MSG.location();
+            labelString = getLabelString();
         }
         Label label   = new Label(labelString);
         Canvas widget = createWidget(data);
@@ -171,7 +171,7 @@
         locationPanel = new DoubleArrayPanel(
             MSG.unitLocation(),
             getLocationValues(),
-            new BlurHandler(){public void onBlur(BlurEvent be) {}});
+            new BlurHandler(){public void onBlur(BlurEvent be) {validate();}});
 
         picker.getLocationTable().setAutoFetchData(true);
 
@@ -197,6 +197,9 @@
         List<String> errors = new ArrayList<String>();
         NumberFormat nf     = NumberFormat.getDecimalFormat();
 
+        DataList[] ref = artifact.getArtifactDescription().getOldData();
+        String mode = ref[1].get(0).getStringValue();
+
         saveLocationValues(locationPanel);
 
         if (!locationPanel.validateForm()) {
@@ -208,7 +211,14 @@
         double[] good   = new double[lValues.length];
         int      idx    = 0;
 
+        double reference =
+            Double.valueOf(ref[2].get(0).getStringValue()).doubleValue();
         for (double value: lValues) {
+            if (mode.equals("calc.reference.curve") &&
+                value == reference) {
+                errors.add(MSG.error_contains_same_location());
+                return errors;
+            }
             if (value < min || value > max) {
                 String tmp = MSG.error_validate_range();
                 tmp = tmp.replace("$1", nf.format(value));
@@ -315,7 +325,26 @@
         catch(NumberFormatException nfe) {
             // Is there anything else to do here?
         }
+
+        // compare reference location and target location.
+        DataList[] ref = artifact.getArtifactDescription().getOldData();
+        String mode = ref[1].get(0).getStringValue();
+        if (mode.equals("calc.reference.curve") &&
+            ref[2].get(0).getStringValue().equals(record.getAttribute("from")))
+        {
+            SC.warn(MSG.error_same_location());
+            return;
+        }
+
         setLocationValues(selected);
     }
+
+    /**
+     * Returns the label string for the input panel.
+     */
+    protected String getLabelString() {
+        return MSG.location();
+    }
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/OutputTab.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/OutputTab.java	Fri Sep 28 12:15:40 2012 +0200
@@ -16,7 +16,7 @@
     /** The Collection that should be displayed in this tab.*/
     protected Collection collection;
 
-    /** The CollectionView. */
+    /** The CollectionView containing this tab. */
     protected CollectionView collectionView;
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java	Fri Sep 28 12:15:40 2012 +0200
@@ -21,6 +21,7 @@
 import com.smartgwt.client.widgets.tab.events.TabSelectedHandler;
 
 import de.intevation.flys.client.shared.model.Artifact;
+import de.intevation.flys.client.shared.model.WINFOArtifact;
 import de.intevation.flys.client.shared.model.ArtifactDescription;
 import de.intevation.flys.client.shared.model.Collection;
 import de.intevation.flys.client.shared.model.Data;
@@ -109,6 +110,7 @@
     protected VLayout report;
     protected VLayout helperPanel;
     protected VLayout tablePanel;
+    protected GaugePanel gaugePanel;
     protected Canvas  reportPanel;
 
     public ParameterList(FLYS flys, CollectionView cView, String title) {
@@ -207,7 +209,24 @@
         stack.setCanResizeSections(true);
         stack.setVisibilityMode(VisibilityMode.MULTIPLE);
 
-        // This canvas is used to render helper widgets
+        final SectionStackSection gaugeSection = new SectionStackSection();
+        gaugeSection.setExpanded(false);
+        gaugeSection.setTitle(MSG.gaugePanelTitle());
+        gaugePanel = new GaugePanel(flys, gaugeSection) {
+            public void addMember(Canvas component) {
+                super.addMember(component);
+                gaugeSection.setExpanded(true);
+            }
+
+            public void removeMembers(Canvas[] components) {
+                super.removeMembers(components);
+                gaugeSection.setExpanded(false);
+            }
+        };
+        gaugePanel.setWidth100();
+        gaugePanel.setHeight100();
+
+        // This canvas is used to render helper widgets.
         final SectionStackSection helperSection = new SectionStackSection();
         helperSection.setExpanded(false);
         helperSection.setTitle(MSG.helperPanelTitle());
@@ -226,7 +245,7 @@
         helperPanel.setHeight100();
         helperSection.setItems(helperPanel);
 
-        // This canvas is used to render calculation results
+        // This canvas is used to render calculation results.
         final SectionStackSection tableSection = new SectionStackSection();
         tableSection.setExpanded(false);
         tableSection.setTitle(MSG.calcTableTitle());
@@ -245,12 +264,13 @@
         tablePanel.setWidth100();
         tableSection.setItems(tablePanel);
 
-        stack.setSections(helperSection, tableSection);
+        stack.setSections(gaugeSection, helperSection, tableSection);
 
         return stack;
     }
 
 
+    /** Sets and forwards artifact. */
     protected void setArtifact(Artifact artifact) {
         setArtifact(artifact, true);
     }
@@ -322,13 +342,14 @@
             null,
             items);
 
-        LinkSelection widget         = new LinkSelection();
+        LinkSelection widget           = new LinkSelection();
         HasStepForwardHandlers handler = (HasStepForwardHandlers) widget;
 
         widget.setContainer(helperPanel);
 
         handler.addStepForwardHandler(new StepForwardHandler() {
             public void onStepForward(StepForwardEvent event) {
+                lockUI();
                 Data[] data = event.getData();
 
                 DataItem[] moduleItems = data[0].getItems();
@@ -339,6 +360,7 @@
 
                 if (module == null) {
                     // TODO throw / show error!
+                    unlockUI();
                     return;
                 }
 
@@ -348,12 +370,13 @@
                 Config config       = Config.getInstance();
                 final String locale = config.getLocale();
 
-                final Data[] feedData  = new Data[] { data[1] };
+                final Data[] feedData = new Data[] { data[1] };
 
                 artifactService.create(
                     locale, module.toLowerCase(), null,
                     new AsyncCallback<Artifact>() {
                         public void onFailure(Throwable caught) {
+                            unlockUI();
                             GWT.log("Could not create the new artifact.");
                             SC.warn(MSG.getString(caught.getMessage()));
                         }
@@ -364,6 +387,7 @@
                             forwardService.go(locale, artifact, feedData,
                             new AsyncCallback<Artifact>() {
                                 public void onFailure(Throwable caught) {
+                                    unlockUI();
                                     GWT.log("Could not feed the artifact.");
                                     SC.warn(caught.getMessage());
                                 }
@@ -373,6 +397,7 @@
                                     old.clear();
                                     cView.addArtifactToCollection(artifact);
                                     setArtifact(artifact);
+                                    unlockUI();
                                 }
                             });
                         }
@@ -581,13 +606,15 @@
      */
     public void onStepForward(StepForwardEvent event) {
         GWT.log("CollectionView - onStepForward()");
+        lockUI();
 
-        Config config    = Config.getInstance();
-        String locale    = config.getLocale();
+        Config config = Config.getInstance();
+        String locale = config.getLocale();
 
         forwardService.go(locale, artifact, event.getData(),
             new AsyncCallback<Artifact>() {
                 public void onFailure(Throwable caught) {
+                    unlockUI();
                     GWT.log("Could not feed the artifact.");
                     SC.warn(MSG.getString(caught.getMessage()));
                 }
@@ -597,6 +624,7 @@
                     old.clear();
 
                     setArtifact(artifact, true);
+                    unlockUI();
                 }
         });
     }
@@ -609,6 +637,7 @@
      * @param e The StepBackEvent that holds the identifier of the target state.
      */
     public void onStepBack(StepBackEvent e) {
+        lockUI();
         final String target    = e.getTarget();
 
         Config config          = Config.getInstance();
@@ -617,6 +646,7 @@
         advanceService.advance(locale, artifact, target,
             new AsyncCallback<Artifact>() {
                 public void onFailure(Throwable caught) {
+                    unlockUI();
                     GWT.log("Could not go back to '" + target + "'");
                     SC.warn(MSG.getString(caught.getMessage()));
                 }
@@ -627,6 +657,7 @@
                     old.clear();
 
                     setArtifact(artifact, false);
+                    unlockUI();
                 }
             }
         );
@@ -711,6 +742,15 @@
                 setCurrentData(null, null);
             }
         }
+        if (art instanceof WINFOArtifact) {
+            String river = desc.getRiver();
+            if (river != null) {
+                renderGaugeInfo(desc.getRiver(), desc.getOldData());
+            }
+            else {
+                gaugePanel.hide();
+            }
+        }
 
         addOldDatas(
             desc.getOldData(),
@@ -873,5 +913,23 @@
     public void registerCollectionViewTabHandler (TabSelectedHandler tsh) {
         this.cView.registerTabHandler (tsh);
     }
+
+
+    protected void lockUI() {
+        cView.lockUI();
+    }
+
+
+    protected void unlockUI() {
+        cView.unlockUI();
+    }
+
+
+    private void renderGaugeInfo(String river, DataList[] data) {
+        gaugePanel.setRiver(river);
+        gaugePanel.setData(data);
+        gaugePanel.show();
+    }
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrix.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrix.java	Fri Sep 28 12:15:40 2012 +0200
@@ -13,13 +13,24 @@
 import com.google.gwt.user.client.ui.Widget;
 import com.google.gwt.user.client.ui.ClickListener;
 
+import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.tile.TileLayout;
 
+import de.intevation.flys.client.client.FLYSConstants;
 import de.intevation.flys.client.shared.model.DataItem;
 import de.intevation.flys.client.shared.model.IntegerOptionsData;
 import de.intevation.flys.client.shared.model.StringOptionsData;
 
 
+/**
+ * Some parameters take the form of on/off options that can also be seen
+ * as a matrix.
+ *
+ * This class helps to survive the underlying objects and create a visual
+ * representation of this matrix. Later can happen in two ways to overcome
+ * shortcomings of GWT/SmartGWT combination.
+ */
 public class ParameterMatrix {
 
     public static class Column implements Serializable {
@@ -44,6 +55,8 @@
         }
     } // end of class Column
 
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MESSAGE = GWT.create(FLYSConstants.class);
 
     public static final int CELL_HEIGHT = 25;
 
@@ -114,8 +127,55 @@
     }
 
 
-    public Widget create() {
-        Grid grid = new Grid(valueNames.size()+1, columnNames.size() + 1);
+    public Widget createTileLayout() {
+        TileLayout tileLayout = new TileLayout();
+        tileLayout.setTilesPerLine (columnNames.size() + 1);
+        tileLayout.setAutoWrapLines(false);
+        tileLayout.setTileMargin(1);
+
+        tileLayout.addTile(new Label(""));
+        for (int i = 0, n = columnNames.size(); i < n; i++) {
+            String columnName = columnNames.get(i);
+            Column col        = columns.get(columnName);
+
+            selected.put(columnName, new ArrayList<String>());
+
+            tileLayout.addTile(createLabel(MESSAGE.getString(columnName)));
+        }
+
+        int nVals = valueNames.size();
+
+        for (int j = 0; j < nVals; j++) {
+            for (int i = 0, n = columnNames.size(); i < n; i++) {
+                String valueName  = valueNames.get(j);
+                String columnName = columnNames.get(i);
+                Column col        = columns.get(columnName);
+                String value      = col.getValue(valueName);
+
+                if (i == 0) {
+                    tileLayout.addTile(createLabel(valueName));
+                }
+
+                if (value != null && value.length() > 0) {
+                    tileLayout.addTile(createCheckBox(columnName, value));
+                }
+            }
+        }
+
+        return tileLayout;
+    }
+
+
+    /**
+     * Returns a widget with matrix of checkboxes and labels.
+     * @param tileLayouted if true, use a TileLayout (for inclusion in SmartGWT
+     *                     containers, avoiding scrollbar-issues.
+     */
+    public Widget create(boolean tileLayouted) {
+        if (tileLayouted) {
+            return createTileLayout();
+        }
+        Grid grid = new Grid(valueNames.size() + 1, columnNames.size() + 1);
 
         for (int i = 0, n = columnNames.size(); i < n; i++) {
             String columnName = columnNames.get(i);
@@ -123,7 +183,7 @@
 
             selected.put(columnName, new ArrayList<String>());
 
-            grid.setWidget(0, i+1, createLabel(columnName));
+            grid.setWidget(0, i+1, createLabel(MESSAGE.getString(columnName)));
 
             for (int j = 0, o = valueNames.size(); j < o; j++) {
                 String valueName = valueNames.get(j);
@@ -134,7 +194,7 @@
                 }
 
                 if (value != null && value.length() > 0) {
-                    grid.setWidget(j+1, i+1, createWidget(columnName, value));
+                    grid.setWidget(j+1, i+1, createCheckBox(columnName, value));
                 }
             }
         }
@@ -143,6 +203,7 @@
     }
 
 
+    /** Creates label with given text. */
     protected Label createLabel(String text) {
         Label label = new Label(text);
         label.setHeight(CELL_HEIGHT);
@@ -151,7 +212,8 @@
     }
 
 
-    protected CheckBox createWidget(final String colName, final String value) {
+    /** Create Checkbox for column/value. */
+    protected Canvas createCheckBox(final String colName, final String value) {
         CheckBox box = new CheckBox();
         box.addClickListener(new ClickListener() {
             @Override
@@ -169,7 +231,9 @@
             }
         });
 
-        return box;
+        Canvas c = new Canvas();
+        c.addChild(box);
+        return c;
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import com.google.gwt.user.client.ui.HTML;
+
 import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.Label;
 import com.smartgwt.client.widgets.layout.HLayout;
@@ -68,6 +70,7 @@
     }
 
 
+    /** Canvas to show in non-edit mode. */
     @Override
     public Canvas createOld(DataList dataList) {
         HLayout layout  = new HLayout();
@@ -98,6 +101,9 @@
                 value.setHeight(20);
 
                 cols.addMember(value);
+                HTML hr = new HTML("<hr>");
+                hr.setHeight("3px");
+                cols.addMember(hr);
             }
 
             row.addMember(parameter);
@@ -114,6 +120,8 @@
         return layout;
     }
 
+
+    /** Create the main canvas in the "editing" mode. */
     @Override
     public Canvas create(DataList dataList) {
         VLayout v = new VLayout();
@@ -130,15 +138,24 @@
             }
         }
 
-        v.addMember(matrix.create());
+        // If too many items are shown, show it in the helper Panel.
+        // TODO its not about the datalist, but about the "rows" in the data.
+        if (dataList.getAll().size() > 5) {
+            v.addMember(matrix.create(false));
+        }
+        else {
+            helperContainer.addMember(matrix.create(true));
+        }
         v.addMember(getNextButton());
 
         return v;
     }
 
 
+    /** Reaturns a label with description of first Data. */
     protected Canvas createTitle(DataList dataList) {
-        Label label = new Label(dataList.getState());
+        Data data = dataList.get(0);
+        Label label = new Label(data.getDescription());
         label.setHeight(35);
 
         return label;
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/PeriodPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/PeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -173,7 +173,7 @@
                 new DataItem[] { endItem }));
         }
 
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ProjectList.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ProjectList.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,22 +1,18 @@
 package de.intevation.flys.client.client.ui;
 
-import java.util.Date;
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.MissingResourceException;
-
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.i18n.client.DateTimeFormat;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.rpc.AsyncCallback;
-
 import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.Autofit;
 import com.smartgwt.client.types.ListGridEditEvent;
 import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.types.Overflow;
 import com.smartgwt.client.types.SelectionStyle;
 import com.smartgwt.client.types.SortArrow;
 import com.smartgwt.client.types.SortDirection;
+import com.smartgwt.client.types.VerticalAlignment;
 import com.smartgwt.client.util.BooleanCallback;
 import com.smartgwt.client.util.SC;
 import com.smartgwt.client.widgets.Canvas;
@@ -32,49 +28,55 @@
 import com.smartgwt.client.widgets.grid.events.CellDoubleClickHandler;
 import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
 import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
+import com.smartgwt.client.widgets.grid.events.HeaderDoubleClickEvent;
+import com.smartgwt.client.widgets.grid.events.HeaderDoubleClickHandler;
 import com.smartgwt.client.widgets.grid.events.RowContextClickEvent;
 import com.smartgwt.client.widgets.grid.events.RowContextClickHandler;
-import com.smartgwt.client.widgets.grid.events.HeaderDoubleClickHandler;
-import com.smartgwt.client.widgets.grid.events.HeaderDoubleClickEvent;
 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.MenuItemSeparator;
-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.shared.model.Artifact;
-import de.intevation.flys.client.shared.model.Recommendation;
-
-import de.intevation.flys.client.client.event.FilterHandler;
-import de.intevation.flys.client.client.event.StringFilterEvent;
-import de.intevation.flys.client.client.event.RangeFilterEvent;
+import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
 
 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.FilterHandler;
+import de.intevation.flys.client.client.event.RangeFilterEvent;
+import de.intevation.flys.client.client.event.StringFilterEvent;
+import de.intevation.flys.client.client.services.AddArtifactService;
+import de.intevation.flys.client.client.services.AddArtifactServiceAsync;
 import de.intevation.flys.client.client.services.ArtifactService;
 import de.intevation.flys.client.client.services.ArtifactServiceAsync;
+import de.intevation.flys.client.client.services.CreateCollectionService;
+import de.intevation.flys.client.client.services.CreateCollectionServiceAsync;
 import de.intevation.flys.client.client.services.DeleteCollectionService;
 import de.intevation.flys.client.client.services.DeleteCollectionServiceAsync;
+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.SetCollectionNameService;
 import de.intevation.flys.client.client.services.SetCollectionNameServiceAsync;
 import de.intevation.flys.client.client.services.SetCollectionTTLService;
 import de.intevation.flys.client.client.services.SetCollectionTTLServiceAsync;
 import de.intevation.flys.client.client.services.UserCollectionsService;
 import de.intevation.flys.client.client.services.UserCollectionsServiceAsync;
-import de.intevation.flys.client.client.services.DescribeCollectionService;
-import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync;
-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.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.CollectionRecord;
+import de.intevation.flys.client.shared.model.Recommendation;
+import de.intevation.flys.client.shared.model.User;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingResourceException;
 
 
 /**
@@ -105,7 +107,7 @@
     public static final String COLUMN_FAVORITE_WIDTH = "75px";
 
     /** The interface that provides i18n messages. */
-    private FLYSConstants messages = GWT.create(FLYSConstants.class);
+    private final FLYSConstants messages = GWT.create(FLYSConstants.class);
 
     /** The UserService used to retrieve information about the current user. */
     protected UserCollectionsServiceAsync userCollectionsService =
@@ -139,6 +141,10 @@
     protected AddArtifactServiceAsync addArtifactService =
         GWT.create(AddArtifactService.class);
 
+    /** The GetArtifactService used to open an existing collection. */
+    protected GetArtifactServiceAsync getArtifactService =
+        GWT.create(GetArtifactService.class);
+
     /** A pointer to the FLYS instance.*/
     protected FLYS flys;
 
@@ -157,6 +163,10 @@
     /** The collection to clone*/
     protected Collection cloneCollection;
 
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+
     /**
      * The default constructor that creates a new ProjectList for a specific
      * user.
@@ -164,11 +174,12 @@
      * @param user The user.
      */
     public ProjectList(FLYS flys, User user) {
+        super();
         this.flys = flys;
         this.user = user;
 
-        filteredCollections = new ArrayList();
-        collections = new ArrayList();
+        filteredCollections = new ArrayList<Collection>();
+        collections = new ArrayList<Collection>();
         grid = new ListGrid();
         initGrid();
         init();
@@ -182,7 +193,7 @@
 
     protected void initGrid() {
         grid.setWidth100();
-        grid.setHeight100();
+        grid.setAutoFitData(Autofit.VERTICAL);
         grid.setAutoFitMaxWidth(500);
         grid.setEmptyMessage(messages.no_projects());
         grid.setLoadingDataMessage(messages.load_projects());
@@ -195,6 +206,7 @@
         grid.setSelectionType(SelectionStyle.SINGLE);
         grid.setCanReorderFields(false);
         grid.setLeaveScrollbarGap(false);
+        grid.setBorder("0px");
 
         ListGridField date = buildDateField();
         ListGridField name = buildNameField();
@@ -203,14 +215,16 @@
         grid.setFields(date, name, fav);
 
         grid.addHeaderDoubleClickHandler(new HeaderDoubleClickHandler() {
+            @Override
             public void onHeaderDoubleClick(HeaderDoubleClickEvent event) {
-                // cancel the event.
+                // Cancel the event.
                 return;
             }
         });
 
-        // add a handler to set / unset the favorite state of a project
+        // Add a handler to set / unset the favorite state of a project.
         grid.addCellClickHandler(new CellClickHandler() {
+            @Override
             public void onCellClick(CellClickEvent event) {
                 if (event.getColNum() != 2) {
                     return;
@@ -224,8 +238,9 @@
             }
         });
 
-        // add a handler to open a project
+        // Add a handler to open a project.
         grid.addCellDoubleClickHandler(new CellDoubleClickHandler() {
+            @Override
             public void onCellDoubleClick(CellDoubleClickEvent e) {
                 CollectionRecord record = (CollectionRecord) e.getRecord();
                 String uuid = record != null
@@ -235,8 +250,9 @@
             }
         });
 
-        // add a handler to open a context menu
+        // Add a handler to open a context menu.
         grid.addRowContextClickHandler(new RowContextClickHandler() {
+            @Override
             public void onRowContextClick(RowContextClickEvent event) {
                 CollectionRecord record = (CollectionRecord) event.getRecord();
 
@@ -291,6 +307,7 @@
 
         MenuItem open = new MenuItem(messages.open_project());
         open.addClickHandler(new ClickHandler() {
+            @Override
             public void onClick(MenuItemClickEvent evt) {
                 getFlys().openProject(record.getCollection().identifier());
             }
@@ -298,8 +315,10 @@
 
         MenuItem del = new MenuItem(messages.delete_project());
         del.addClickHandler(new ClickHandler() {
+            @Override
             public void onClick(MenuItemClickEvent evt) {
                 SC.ask(messages.really_delete(), new BooleanCallback() {
+                    @Override
                     public void execute(Boolean value) {
                         if (value) {
                             deleteCollection(record.getCollection());
@@ -311,6 +330,7 @@
 
         MenuItem rename = new MenuItem(messages.rename_project());
         rename.addClickHandler(new ClickHandler() {
+            @Override
             public void onClick(MenuItemClickEvent evt) {
                 int row = grid.getRecordIndex(record);
                 grid.startEditing(row, 1, false);
@@ -319,6 +339,7 @@
 
         MenuItem clone = new MenuItem(messages.clone_project());
         clone.addClickHandler(new ClickHandler() {
+            @Override
             public void onClick(MenuItemClickEvent evt) {
                 cloneProject(record.getCollection());
             }
@@ -345,6 +366,7 @@
         setShowEdges(false);
         setLayoutMargin(0);
         setLayoutAlign(VerticalAlignment.TOP);
+        setOverflow(Overflow.AUTO);
 
         Label title = new Label(messages.projects());
         title.setHeight("20");
@@ -366,6 +388,7 @@
         TableFilter filter = new TableFilter();
         filter.setHeight("30px");
         filter.addFilterHandler(this);
+        filter.setBorder("1px solid gray");
 
         addMember(titleWrapper);
         addMember(gridWrapper);
@@ -373,6 +396,7 @@
     }
 
 
+    @Override
     public void onFilterCriteriaChanged(StringFilterEvent event) {
         String search = event.getFilter();
         if (search != null && search.length() > 0) {
@@ -389,11 +413,14 @@
     }
 
 
+    @Override
     public void onFilterCriteriaChanged(RangeFilterEvent event) {
         //Empty. No Ranges to filter.
     }
 
 
+    /** On collection change, update list (probably name change or similar). */
+    @Override
     public void onCollectionChange(CollectionChangeEvent event) {
         if (event.getOldValue() == null) {
             updateUserCollections();
@@ -401,6 +428,7 @@
     }
 
 
+    @Override
     public void onEditComplete(EditCompleteEvent event) {
         if (event.getColNum() != 1) {
             return;
@@ -411,7 +439,7 @@
         CollectionRecord r = (CollectionRecord) grid.getRecord(row);
         Collection       c = r.getCollection();
 
-        Map newValues = event.getNewValues();
+        Map<?, ?> newValues = event.getNewValues();
         String name   = (String) newValues.get("name");
 
         int maxLength = getMaxNameLength();
@@ -449,6 +477,7 @@
         GWT.log("=> New name = " + c.getName());
 
         nameService.setName(c, new AsyncCallback<Void>(){
+            @Override
             public void onFailure(Throwable caught) {
                 String msg = caught.getMessage();
 
@@ -460,6 +489,7 @@
                 }
             }
 
+            @Override
             public void onSuccess(Void v) {
                 updateUserCollections();
                 if(flys.getWorkspace().hasView(c.identifier())) {
@@ -485,6 +515,7 @@
         GWT.log("=> New ttl = " + c.getTTL());
 
         ttlService.setTTL(c, new AsyncCallback<Void>() {
+            @Override
             public void onFailure(Throwable caught) {
                 String msg = caught.getMessage();
 
@@ -496,6 +527,7 @@
                 }
             }
 
+            @Override
             public void onSuccess(Void v) {
                 updateUserCollections();
             }
@@ -508,7 +540,7 @@
      *
      * @param c The Collection that should be deleted.
      */
-    protected void deleteCollection(final Collection c) {
+    public void deleteCollection(final Collection c) {
         if (c == null) {
             return;
         }
@@ -516,6 +548,7 @@
         GWT.log("Delete Collection: " + c.identifier());
 
         deleteService.delete(c, new AsyncCallback<Void>(){
+            @Override
             public void onFailure(Throwable caught) {
                 String msg = caught.getMessage();
 
@@ -527,6 +560,7 @@
                 }
             }
 
+            @Override
             public void onSuccess(Void v) {
                 flys.getWorkspace().destroyProject(c.identifier());
                 updateUserCollections();
@@ -543,6 +577,7 @@
 
         userCollectionsService.getUserCollections(locale, user.identifier(),
             new AsyncCallback<Collection[]>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     String msg = caught.getMessage();
 
@@ -554,6 +589,7 @@
                     }
                 }
 
+                @Override
                 public void onSuccess(Collection[] collections) {
                     int num = collections != null ? collections.length : 0;
 
@@ -565,6 +601,7 @@
         );
     }
 
+
     /**
      * Delete all entries in the ListGrid.
      */
@@ -613,6 +650,7 @@
         }
     }
 
+
     /**
      * Filter for the user collections.
      *
@@ -668,6 +706,7 @@
         date.setCanEdit(false);
 
         date.setCellFormatter(new CellFormatter() {
+            @Override
             public String format(Object value, ListGridRecord rec, int r, int c) {
                 if (value == null) {
                     return null;
@@ -699,6 +738,7 @@
         name.setType(ListGridFieldType.TEXT);
         name.setShowHover(true);
         name.setHoverCustomizer(new HoverCustomizer() {
+            @Override
             public String hoverHTML(
                 Object         value,
                 ListGridRecord record,
@@ -747,22 +787,25 @@
 
         describeCollectionService.describe(c.identifier(), locale,
             new AsyncCallback<Collection>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     GWT.log("Could not DESCRIBE collection.");
                     SC.warn(messages.getString(caught.getMessage()));
                 }
 
 
+                @Override
                 public void onSuccess(Collection newCollection) {
                     GWT.log("Successfully DESCRIBED collection.");
                     String uuid = getMasterArtifact(newCollection);
-                    cloneArtifact(uuid);
+                    cloneArtifact(uuid, newCollection);
                 }
             }
         );
     }
 
 
+    /** Get master artifacts UUID of a collection. */
     protected String getMasterArtifact(Collection newCollection) {
         String uuid = newCollection.getItem(0).identifier();
         // The master artifact uuid.
@@ -770,12 +813,11 @@
     }
 
 
-    protected void cloneArtifact(String uuid) {
-        Config config       = Config.getInstance();
-        final String locale = config.getLocale();
-
+    /** Clone artifact/create collection, using the refArtifacts factory. */
+    protected void cloneArtifact(String uuid, Artifact refArtifact,
+        final String locale) {
         Recommendation recommendation = new Recommendation(
-            "winfo",
+            refArtifact.getName(),
             null,
             uuid,
             null);
@@ -784,11 +826,13 @@
         createArtifactService.create(
             locale, factory, recommendation,
             new AsyncCallback<Artifact>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     GWT.log("Error loading recommendations: " +
                         caught.getMessage());
                 }
 
+                @Override
                 public void onSuccess(Artifact artifact) {
                     GWT.log("Created new artifact: " + artifact.getUuid());
                     createCollection(artifact);
@@ -798,6 +842,33 @@
     }
 
 
+    /**
+     * Clone a project (collection).
+     */
+    protected void cloneArtifact(final String uuid, Collection newCollection) {
+        Config config       = Config.getInstance();
+        final String locale = config.getLocale();
+
+        // Find out which factory to use for cloning.
+        CollectionItem master = newCollection.getItem(0);
+        getArtifactService.getArtifact(
+            locale,
+            master.identifier(),
+            master.hash(),
+            new AsyncCallback<Artifact>() {
+                @Override
+                public void onFailure(Throwable caught) {
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                @Override
+                public void onSuccess(Artifact artifact) {
+                    cloneArtifact(uuid, artifact, locale);
+                }
+        });
+    }
+
+
     protected void createCollection(final Artifact artifact) {
         Config config        = Config.getInstance();
         final String locale  = config.getLocale();
@@ -807,11 +878,13 @@
             locale,
             ownerid,
             new AsyncCallback<Collection>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     GWT.log("Could not create the new collection.");
                     SC.warn(messages.getString(caught.getMessage()));
                 }
 
+                @Override
                 public void onSuccess(Collection collection) {
                     GWT.log("Successfully created a new collection.");
                     addArtifactToCollection(artifact, collection);
@@ -828,11 +901,13 @@
         addArtifactService.add(
             c, a, locale,
             new AsyncCallback<Collection>() {
+                @Override
                 public void onFailure(Throwable caught) {
                     GWT.log("An error occured while adding artifact.");
                     SC.warn(messages.getString(caught.getMessage()));
                 }
 
+                @Override
                 public void onSuccess(Collection newColl) {
                     String name = cloneCollection.getName();
                     if(name == null || name.equals("")) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/RadioPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,92 @@
+package de.intevation.flys.client.client.ui;
+
+import java.util.LinkedHashMap;
+
+import com.google.gwt.core.client.GWT;
+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;
+
+public class RadioPanel extends AbstractUIProvider {
+
+    protected String dataName;
+    protected DynamicForm form;
+
+    @Override
+    public Canvas createOld(DataList dataList) {
+        // TODO Auto-generated method stub
+        Data       data  = dataList.get(0);
+        DataItem[] items = data.getItems();
+
+        HLayout layout = new HLayout();
+        Label   label  = new Label(dataList.getLabel());
+        Label   value  = new Label(items[0].getLabel());
+
+        layout.setHeight(35);
+        layout.setWidth(400);
+        label.setWidth(200);
+
+        layout.addMember(label);
+        layout.addMember(value);
+        layout.addMember(getBackButton(dataList.getState()));
+
+        return layout;
+    }
+
+    @Override
+    public Canvas create(DataList dataList) {
+        Data       data  = dataList.get(0);
+        DataItem[] items = data.getItems();
+
+        this.dataName = data.getLabel();
+
+        VLayout layout = new VLayout();
+        Label   label  = new Label(data.getDescription());
+        RadioGroupItem rgi = new RadioGroupItem("selection");
+        rgi.setShowTitle(false);
+        GWT.log("items: " + items.length);
+        LinkedHashMap<String, String> elems = new LinkedHashMap<String, String>();
+        for (int i = 0; i < items.length; i++) {
+            GWT.log(items[i].getStringValue() + "; " + items[i].getLabel());
+            elems.put(items[i].getStringValue(), items[i].getLabel());
+        }
+        rgi.setValueMap(elems);
+        rgi.setDefaultValue(items[0].getStringValue());
+
+        form = new DynamicForm();
+        form.setFields(rgi);
+        layout.setMembersMargin(10);
+        layout.setHeight(35);
+        label.setHeight(35);
+
+        layout.addMember(label);
+        layout.addMember(form);
+        layout.addMember(getNextButton());
+        layout.setMembersMargin(10);
+
+        //initDefaultValues(dataList);
+
+        return layout;
+    }
+
+    @Override
+    protected Data[] getData() {
+        String value = form.getValueAsString("selection");
+        DataItem item = new DefaultDataItem("ye_select", "ye_select", value);
+        return new Data[] { new DefaultData(
+            "ye_select", null, null, new DataItem[]{item})};
+    }
+
+    protected String getTitle(DataItem item) {
+        return item.getLabel();
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/SingleLocationPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -113,5 +113,10 @@
         }
         setLocationValues(selected);
     }
+
+
+    protected String getLabelString() {
+        return MSG.single_location();
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/StyleEditorWindow.java	Fri Sep 28 12:15:40 2012 +0200
@@ -17,8 +17,11 @@
 import com.smartgwt.client.widgets.form.fields.FormItem;
 import com.smartgwt.client.widgets.form.fields.SelectItem;
 import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
 import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
 import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+import com.smartgwt.client.widgets.form.validator.IsFloatValidator;
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
@@ -28,6 +31,7 @@
 import de.intevation.flys.client.client.services.CollectionItemAttributeServiceAsync;
 import de.intevation.flys.client.client.services.ThemeListingService;
 import de.intevation.flys.client.client.services.ThemeListingServiceAsync;
+import de.intevation.flys.client.client.utils.DoubleValidator;
 import de.intevation.flys.client.shared.model.Collection;
 import de.intevation.flys.client.shared.model.CollectionItemAttribute;
 import de.intevation.flys.client.shared.model.FacetRecord;
@@ -42,6 +46,7 @@
 import java.util.Set;
 
 /**
+ * Editor window for styles.
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
 public class StyleEditorWindow
@@ -66,7 +71,11 @@
     /** Main layout. */
     protected VLayout layout;
 
+    /** The form that contains all the input widgets. */
+    protected DynamicForm df;
+
     protected VLayout properties;
+
     protected Canvas container;
 
     protected Map<String, Style> styleGroups;
@@ -83,6 +92,7 @@
     protected ThemeListingServiceAsync themeListingService =
         GWT.create(ThemeListingService.class);
 
+
     /**
      * Setup editor dialog.
      * @param collection The collection the current theme belongs to.
@@ -202,7 +212,11 @@
         accept.addClickHandler(new ClickHandler() {
             @Override
             public void onClick(ClickEvent e) {
-                saveStyle();
+                // TODO Fix this, for whatever reason it doesnt work
+                // (always valid).
+                if (!df.hasErrors() && df.validate()) {
+                    saveStyle();
+                }
             }
         });
 
@@ -281,16 +295,19 @@
                          "pointcolor",
                          "pointsize",
                          "textcolor",
-                         "textorientation",
                          "backgroundcolor",
                          "showbackground",
                          "showlinelabel",
-                         "linelabelfont",
-                         "linelabelcolor",
-                         "linelabelsize",
-                         "linelabelstyle",
-                         "linelabelshowbg",
-                         "linelabelbgcolor"};
+                         "labelfontface",
+                         "labelfontcolor",
+                         "labelfontsize",
+                         "labelfontstyle",
+                         "textorientation",
+                         "labelshowbg",
+                         "labelbgcolor",
+                         "showpointlabel",
+                         "bandwidthcolor",
+                         "bandwidth"};
 
         for (String settingName: sets) {
             StyleSetting set = style.getSetting(settingName);
@@ -341,7 +358,7 @@
         String type,
         String value)
     {
-        DynamicForm df = new DynamicForm();
+        df = new DynamicForm();
         df.setColWidths("40%", "60%");
 
         FormItem f;
@@ -349,8 +366,9 @@
             f = new SelectItem(name, MSG.getString(name));
             if (name.equals("linesize")) {
                 f = createLineSizeUI(f);
+                f.setValue(value);
             }
-            else if (name.equals("textsize") || name.equals("linelabelsize")) {
+            else if (name.equals("labelfontsize")) {
                 LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
                 valueMap.put("3", "3");
                 valueMap.put("5", "5");
@@ -361,6 +379,24 @@
                 valueMap.put("18", "18");
                 valueMap.put("24", "24");
                 f.setValueMap(valueMap);
+                f.setValue(value);
+            }
+            else if (name.equals("bandwidth")) {
+                LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
+                valueMap.put("0", "0");
+                valueMap.put("1", "1");
+                valueMap.put("2", "2");
+                valueMap.put("3", "3");
+                valueMap.put("4", "4");
+                valueMap.put("5", "5");
+                valueMap.put("6", "6");
+                valueMap.put("7", "7");
+                valueMap.put("8", "8");
+                valueMap.put("9", "9");
+                valueMap.put("10", "10");
+                valueMap.put("11", "11");
+                f.setValueMap(valueMap);
+                f.setValue(value);
             }
             else if (name.equals("pointsize")) {
                 LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
@@ -372,15 +408,23 @@
                 valueMap.put("6", "6");
                 valueMap.put("7", "7");
                 f.setValueMap(valueMap);
+                f.setValue(value);
             }
-            f.setValue(value);
+            else if (name.equals("transparency")) {
+                LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
+                for (int n = 10; n < 100; n += 10) {
+                    valueMap.put(Integer.toString(n), n + "%");
+                }
+                f.setValueMap(valueMap);
+                f.setValue(value);
+            }
         }
         else if (type.equals("boolean")) {
             if(name.equals("textorientation")) {
                 f = new SelectItem(name, MSG.getString(name));
                 LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
-                valueMap.put("true", "horizontal");
-                valueMap.put("false", "vertical");
+                valueMap.put("true", MSG.getString("horizontal"));
+                valueMap.put("false", MSG.getString("vertical"));
                 f.setValueMap(valueMap);
                 f.setValue(value);
             }
@@ -401,6 +445,28 @@
             c.setValue(rgbToHtml(value));
             f = c;
         }
+        else if (type.equals("double")) {
+            f = new FormItem(name);
+            IsFloatValidator fpv = new IsFloatValidator();
+
+            f.setValidators(fpv);
+            f.setValidateOnChange(true);
+            f.setTitle(MSG.getString(name));
+            f.addBlurHandler(new BlurHandler() {
+                @Override
+                public void onBlur(BlurEvent e) {
+                     DoubleValidator validator = new DoubleValidator();
+                     Map<?, ?> errors = e.getForm().getErrors();
+                     if(validator.validate(e.getItem(), errors)) {
+                         e.getForm().setErrors(errors, true);
+                     }
+                     else {
+                         e.getForm().setErrors(errors, true);
+                     }
+                }
+            });
+            f.setValue(value);
+        }
         else if (type.equals("Dash")) {
             f = new SelectItem(name, MSG.getString(name));
             LinkedHashMap<String, String> valueIcons = new LinkedHashMap<String, String>();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ThemePanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ThemePanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -121,6 +121,8 @@
         this.outHandlers = new ArrayList<OutputParameterChangeHandler>();
         this.navigation  = new ThemeNavigationPanel();
         this.navigation.addOnMoveHandler(this);
+
+        this.setShowResizeBar(true);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/UIProviderFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,13 +1,17 @@
 package de.intevation.flys.client.client.ui;
 
-import de.intevation.flys.client.shared.model.User;
-
+import de.intevation.flys.client.client.ui.fixation.FixEventSelect;
+import de.intevation.flys.client.client.ui.fixation.FixFunctionSelect;
+import de.intevation.flys.client.client.ui.fixation.FixGaugeSelectPanel;
 import de.intevation.flys.client.client.ui.fixation.FixLocationPanel;
+import de.intevation.flys.client.client.ui.fixation.FixMultiPeriodPanel;
 import de.intevation.flys.client.client.ui.fixation.FixPeriodPanel;
-import de.intevation.flys.client.client.ui.fixation.FixGaugeSelectPanel;
-import de.intevation.flys.client.client.ui.fixation.FixEventSelect;
-import de.intevation.flys.client.client.ui.fixation.FixMultiPeriodPanel;
-import de.intevation.flys.client.client.ui.sq.SQMultiPeriodPanel;
+import de.intevation.flys.client.client.ui.fixation.FixQSelectPanel;
+import de.intevation.flys.client.client.ui.sq.SQPeriodPanel;
+import de.intevation.flys.client.client.ui.minfo.BedHeightsDatacagePanel;
+import de.intevation.flys.client.client.ui.minfo.BedMultiPeriodPanel;
+import de.intevation.flys.client.client.ui.minfo.CheckboxPanel;
+import de.intevation.flys.client.shared.model.User;
 
 /**
  * Depending on the provider the state declared, return a UIProvider.
@@ -20,6 +24,7 @@
     private UIProviderFactory() {
     }
 
+    /** @param uiProvider uiprovider demanded for by state. */
     public static UIProvider getProvider(String uiProvider, User user) {
         if (uiProvider == null || uiProvider.equals("")) {
             return new SelectProvider();
@@ -99,6 +104,9 @@
         else if (uiProvider.equals("fix.period_ana_panel")) {
             return new FixMultiPeriodPanel();
         }
+        else if (uiProvider.equals("fix.qselect_panel")) {
+            return new FixQSelectPanel();
+        }
         else if (uiProvider.equals("fix.gaugeselect_panel")) {
             return new FixGaugeSelectPanel();
         }
@@ -108,8 +116,17 @@
         else if (uiProvider.equals("fix.preprocessing_panel")) {
             return new BooleanPanel();
         }
+        else if (uiProvider.equals("fix.functionselect")) {
+            return new FixFunctionSelect();
+        }
+        else if (uiProvider.equals("period_select")) {
+            return new PeriodPanel();
+        }
         else if (uiProvider.equals("periods_select")) {
-            return new SQMultiPeriodPanel();
+            return new MultiPeriodPanel();
+        }
+        else if (uiProvider.equals("sq.period.select")) {
+            return new SQPeriodPanel();
         }
         else if (uiProvider.equals("outliers_input")) {
             return new DoubleInputPanel();
@@ -117,8 +134,23 @@
         else if (uiProvider.equals("parameter-matrix")) {
             return new ParameterMatrixPanel();
         }
+        else if (uiProvider.equals("minfo.bed.year_epoch")) {
+            return new RadioPanel();
+        }
+        else if (uiProvider.equals("bedquality_periods_select")) {
+            return new BedMultiPeriodPanel();
+        }
+        else if (uiProvider.equals("bedheights_twin_panel")) {
+            return new BedHeightsDatacagePanel(user);
+        }
+        else if (uiProvider.equals("minfo.bed.char_diameter")) {
+            return new CheckboxPanel();
+        }
         else {
+            //GWT.log("Picked default provider.");
             return new SelectProvider();
         }
     }
 }
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/WQInputPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -88,7 +88,6 @@
 
     public static final int WIDTH_LEFT_LOWER = 223;
 
-
     /** The container that manages the w and q panels.*/
     protected HLayout container;
 
@@ -283,6 +282,7 @@
         Tab wTab = new Tab(MESSAGE.wq_table_w());
         Tab qTab = new Tab(MESSAGE.wq_table_q());
 
+        qdTable.showSelect();
         wTab.setPane(wTable);
         qTab.setPane(qdTable);
 
@@ -480,7 +480,7 @@
      * Initializes the single values of W or Q from DataList.
      *
      * @param list The DataList that contains the 'wq_single' object.
-     * @param theMode The W or Q mode.
+     * @param isQ W or Q mode?
      */
     protected void initUserSingleValues(DataList list, boolean isQ) {
         List<Data> allData = list.getAll();
@@ -521,7 +521,7 @@
      * Initializes the range values of W or Q from DataList.
      *
      * @param list The DataList that contains the 'wq_single' object.
-     * @param theMode The W or Q mode.
+     * @param isQ W or Q mode?
      */
     protected void initUserRangeValues(DataList list, boolean isQ) {
         List<Data> allData = list.getAll();
@@ -1295,6 +1295,13 @@
             qdTable.showIconFields();
         }
 
+        if (!isRange) {
+            qdTable.showSelect();
+        }
+        else {
+            qdTable.showIconFields();
+        }
+
         updatePanels(isQ, isFree, isRange);
     }
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/WspDatacagePanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/WspDatacagePanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -71,7 +71,7 @@
      * we have to create a new Artifact specified by  the Datacage selection via
      * Async request.
      *
-     * @param The ClickEvent.
+     * @param e The ClickEvent.
      */
     @Override
     public void onClick(ClickEvent e) {
@@ -88,7 +88,7 @@
                 c, r, "winfo", locale,
                 new AsyncCallback<Artifact>() {
                     public void onFailure(Throwable caught) {
-                        SC.warn(MSG.getString(caught.getMessage()));
+                        SC.warn(caught.getMessage());
                     }
 
                     public void onSuccess(Artifact artifact) {
@@ -108,7 +108,7 @@
         ToLoad toLoad = widget.getSelection();
         List<Recommendation> recoms = toLoad.toRecommendations();
 
-        return recoms.get(0);
+        return recoms.size() > 0 ? recoms.get(0) : null;
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java	Fri Sep 28 12:15:40 2012 +0200
@@ -53,7 +53,7 @@
     public static final int DEFAULT_CHART_WIDTH  = 600;
     public static final int DEFAULT_CHART_HEIGHT = 500;
 
-    public static final int THEMEPANEL_MIN_WIDTH = 200;
+    public static final int THEMEPANEL_MIN_WIDTH = 250;
 
     /** The service that is used to fetch chart information. */
     protected ChartInfoServiceAsync info = GWT.create(ChartInfoService.class);
@@ -115,10 +115,10 @@
         zoomStack = new Stack<ZoomObj>();
 
         zoom = new Number[] {
-            new Integer(0), new Integer(1),
-            new Integer(0), new Integer(1) };
+            new Double(0), new Double(1),
+            new Double(0), new Double(1) };
 
-        left.setBorder("1px solid black");
+        left.setBorder("1px solid gray");
         left.setWidth(THEMEPANEL_MIN_WIDTH);
         left.setMinWidth(THEMEPANEL_MIN_WIDTH);
         right.setWidth("*");
@@ -134,27 +134,26 @@
         hLayout.addMember(left);
         hLayout.addMember(right);
 
-        // Output "cross_section" needs slightly modified ThemePanel
-        // (with action buttons).
-        if (mode.getName().equals("cross_section")) {
-            ctp = new CrossSectionChartThemePanel(mode, this.view);
+        ctp = createThemePanel(mode, collectionView);
+        if (ctp != null) {
+            ctp.addRedrawRequestHandler(this);
+            ctp.addOutputParameterChangeHandler(this);
+            left.addChild(ctp);
         }
         else {
-            ctp = new ChartThemePanel(mode, this.view);
+            left.setVisible(false);
         }
 
-        ctp.addRedrawRequestHandler(this);
-        ctp.addOutputParameterChangeHandler(this);
-
         chart = createChartImg();
         right.addChild(chart);
         right.setOverflow(Overflow.HIDDEN);
-        //right.addChild(createChartPanel());
-        left.addChild(ctp);
 
-        tbarPanel = new ChartToolbar(this);
+        left.setShowResizeBar(true);
+
+        tbarPanel = createChartToolbar(this);
         vLayout.addMember(tbarPanel);
         vLayout.addMember(hLayout);
+        vLayout.setOverflow(Overflow.HIDDEN);
 
         setPane(vLayout);
 
@@ -162,6 +161,25 @@
     }
 
 
+    public ChartThemePanel createThemePanel(
+        OutputMode mode, CollectionView view
+    ) {
+        // Output "cross_section" needs slightly modified ThemePanel
+        // (with action buttons).
+        if (mode.getName().equals("cross_section")) {
+            return new CrossSectionChartThemePanel(mode, view);
+        }
+        else {
+            return new ChartThemePanel(mode, view);
+        }
+    }
+
+
+    public ChartToolbar createChartToolbar(ChartOutputTab tab) {
+        return new ChartToolbar(tab);
+    }
+
+
     public void toggleThemePanel() {
         this.left.setVisible(!left.isVisible());
     }
@@ -310,6 +328,7 @@
         Number[] x = panAxis(xAxis, diffX);
         Number[] y = panAxis(yAxis, diffY);
 
+        // Set the zoom coordinates.
         zoom[0] = x[0];
         zoom[1] = x[1];
         zoom[2] = y[0];
@@ -423,7 +442,7 @@
 
 
     public static Number[] computeZoom(Axis axis, Number min, Number max) {
-        Number[] zoom = new Number[2];
+        Number[] hereZoom = new Number[2];
 
         Number absMin = axis.getMin();
         Number absMax = axis.getMax();
@@ -431,10 +450,10 @@
             ? subtract(absMax, absMin)
             : subtract(absMin, absMax);
 
-        zoom[0] = divide(subtract(min, absMin), diff);
-        zoom[1] = divide(subtract(max, absMin), diff);
+        hereZoom[0] = divide(subtract(min, absMin), diff);
+        hereZoom[1] = divide(subtract(max, absMin), diff);
 
-        return zoom;
+        return hereZoom;
     }
 
 
@@ -689,6 +708,7 @@
     }
 
 
+    /** Add two numbers, casting to Type of param left. */
     public static Number add(Number left, Number right) {
         if (left instanceof Double) {
             return new Double(left.doubleValue() + right.doubleValue());
@@ -702,12 +722,13 @@
     }
 
 
+    /** Divde left by right. Note that Long will be casted to double. */
     public static Number divide(Number left, Number right) {
         if (left instanceof Double) {
             return new Double(left.doubleValue() / right.doubleValue());
         }
         else if (left instanceof Long) {
-            return new Long(left.longValue() / right.longValue());
+            return new Double(left.doubleValue() / right.doubleValue());
         }
         else {
             return new Integer(left.intValue() / right.intValue());
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartPropertiesEditor.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,5 +1,6 @@
 package de.intevation.flys.client.client.ui.chart;
 
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -19,6 +20,7 @@
 import com.smartgwt.client.widgets.form.DynamicForm;
 import com.smartgwt.client.widgets.form.fields.FormItem;
 import com.smartgwt.client.widgets.form.fields.CheckboxItem;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
 import com.smartgwt.client.widgets.form.fields.TextItem;
 
 import com.smartgwt.client.widgets.events.ClickEvent;
@@ -49,6 +51,8 @@
 import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync;
 
 /**
+ * Dialog for the Chart-Properties, constructed from respective xml document.
+ *
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
 public class ChartPropertiesEditor
@@ -160,6 +164,7 @@
         centerInPage();
     }
 
+
     /**
      * This method is called when the user aborts theming.
      * @param event The event.
@@ -266,7 +271,8 @@
 
 
     /**
-     *
+     * Generate a form with items for the properties/settings, preset with
+     * values.
      */
     protected DynamicForm generatePropertySetting(
         Property setting,
@@ -288,9 +294,13 @@
             item.setValue(((IntegerProperty)orig).getValue());
         }
         else if (setting instanceof StringProperty) {
-            item = createStringProperty((StringProperty)setting);
+            StringProperty property = (StringProperty) setting;
+            item = createStringProperty(property);
             item.setValue(((StringProperty)orig).getValue());
         }
+        else {
+            GWT.log("generatePropertySetting: unknown setting type.");
+        }
         form.setFields(item);
         return form;
     }
@@ -301,6 +311,103 @@
         if (name.contains("-")) {
             name = name.replace("-", "_");
         }
+
+        String choiceAttribute = sp.getAttribute("choice");
+
+        if (choiceAttribute != null && choiceAttribute.equals("logo")) {
+            SelectItem logoChooser = new SelectItem();
+            logoChooser.setImageURLPrefix(GWT.getHostPageBaseURL() + "images/logo-");
+            logoChooser.setValueIconHeight(50);
+            logoChooser.setValueIconWidth(100);
+
+            LinkedHashMap valueMap = new LinkedHashMap<String, String>();
+            LinkedHashMap<String, String> valueIcons = new LinkedHashMap<String, String>();
+            valueMap.put("none", MSG.getString("none"));
+            /*
+             If you want to add images, remember to change code in these places:
+             flys-artifacts:
+             XYChartGenerator.java
+             Timeseries*Generator.java and
+             in the flys-client projects Chart*Propert*Editor.java.
+             Also, these images have to be put in
+             flys-artifacts/src/main/resources/images/
+             flys-client/src/main/webapp/images/
+             */
+            valueMap.put("BfG", "");
+            valueMap.put("Intevation", "");
+            valueIcons.put("BfG", "bfg.gif");
+            valueIcons.put("Intevation", "intevation.png");
+            logoChooser.setValueIcons(valueIcons);
+            logoChooser.setValueMap(valueMap);
+            logoChooser.setTitleStyle("color:#000;");
+            logoChooser.setTitleAlign(Alignment.LEFT);
+            logoChooser.setTitle(MSG.getString(name));
+            logoChooser.setTitleAlign(Alignment.LEFT);
+            logoChooser.addBlurHandler(new BlurHandler() {
+                public void onBlur(BlurEvent e) {
+                    String val;
+                    if (e.getItem().getValue() == null) {
+                        val = "";
+                    }
+                    else {
+                        val = e.getItem().getValue().toString();
+                    }
+                    sp.setValue(val);
+                }
+            });
+            return logoChooser;
+        }
+        else if (choiceAttribute != null && choiceAttribute.equals("placeh")) {
+            SelectItem placeChooser = new SelectItem();
+            LinkedHashMap valueMap = new LinkedHashMap<String, String>();
+            valueMap.put("right", MSG.getString("right"));
+            valueMap.put("left", MSG.getString("left"));
+            valueMap.put("center", MSG.getString("center"));
+            placeChooser.setValueMap(valueMap);
+            placeChooser.setTitleStyle("color:#000;");
+            placeChooser.setTitleAlign(Alignment.LEFT);
+            placeChooser.setTitle(MSG.getString(name));
+            placeChooser.setTitleAlign(Alignment.LEFT);
+            placeChooser.addBlurHandler(new BlurHandler() {
+                public void onBlur(BlurEvent e) {
+                    String val;
+                    if (e.getItem().getValue() == null) {
+                        val = "";
+                    }
+                    else {
+                        val = e.getItem().getValue().toString();
+                    }
+                    sp.setValue(val);
+                }
+            });
+            return placeChooser;
+        }
+        else if (choiceAttribute != null && choiceAttribute.equals("placev")) {
+            SelectItem placeChooser = new SelectItem();
+            LinkedHashMap valueMap = new LinkedHashMap<String, String>();
+            valueMap.put("top", MSG.getString("top"));
+            valueMap.put("bottom", MSG.getString("bottom"));
+            valueMap.put("center", MSG.getString("center"));
+            placeChooser.setValueMap(valueMap);
+            placeChooser.setTitleStyle("color:#000;");
+            placeChooser.setTitleAlign(Alignment.LEFT);
+            placeChooser.setTitle(MSG.getString(name));
+            placeChooser.setTitleAlign(Alignment.LEFT);
+            placeChooser.addBlurHandler(new BlurHandler() {
+                public void onBlur(BlurEvent e) {
+                    String val;
+                    if (e.getItem().getValue() == null) {
+                        val = "";
+                    }
+                    else {
+                        val = e.getItem().getValue().toString();
+                    }
+                    sp.setValue(val);
+                }
+            });
+            return placeChooser;
+        }
+
         TextItem item = new TextItem();
         item.setTitle(MSG.getString(name));
         item.setTitleAlign(Alignment.LEFT);
@@ -367,11 +474,8 @@
                  Map errors = e.getForm().getErrors();
                  if(validator.validate(e.getItem(), errors)) {
                      dp.setValueFromUI(e.getItem().getValue().toString());
-                     e.getForm().setErrors(errors, true);
                  }
-                 else {
-                     e.getForm().setErrors(errors, true);
-                 }
+                 e.getForm().setErrors(errors, true);
             }
         });
         return item;
@@ -396,11 +500,8 @@
                 Map errors = e.getForm().getErrors();
                 if(validator.validate(e.getItem(), errors)) {
                     ip.setValue(e.getItem().getValue().toString());
-                    e.getForm().setErrors(errors, true);
                 }
-                else {
-                    e.getForm().setErrors(errors, true);
-                }
+                e.getForm().setErrors(errors, true);
             }
         });
         return item;
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartToolbar.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,15 +1,15 @@
 package de.intevation.flys.client.client.ui.chart;
 
 import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.types.Overflow;
 import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.ImgButton;
 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.events.ResizedEvent;
-import com.smartgwt.client.widgets.events.ResizedHandler;
 
+import de.intevation.flys.client.client.Config;
 import de.intevation.flys.client.client.FLYSConstants;
 import de.intevation.flys.client.client.event.ZoomEvent;
 import de.intevation.flys.client.client.event.ZoomHandler;
@@ -27,7 +27,7 @@
 
     protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);
 
-    public static final int PANEL_HEIGHT = 30;
+    public static final int PANEL_HEIGHT = 35;
 
     protected Button manageThemes;
     protected Button datacage;
@@ -43,12 +43,19 @@
     protected ImgButton chartProperties;
     protected Button addPoints;
     protected Button addWSP;
+    protected ImgLink exportAT;
     protected PanControl panControl;
 
 
     /** @param chartTab Output-Tab on which this toolbar is located. */
     public ChartToolbar(ChartOutputTab chartTab) {
         super(chartTab);
+        initTools();
+    }
+
+
+    protected void initTools() {
+        ChartOutputTab chartTab = getChartOutputTab();
 
         manageThemes    = new Button(MSG.manageThemes());
         datacage        = new Button(MSG.databasket());
@@ -98,6 +105,24 @@
         });
 
         String baseUrl = GWT.getHostPageBaseURL();
+        String moduleUrl = GWT.getModuleBaseURL();
+        Config config = Config.getInstance();
+
+        if (chartTab.getMode().getName().equals("fix_wq_curve")) {
+            exportAT = new ImgLink(
+                baseUrl + MSG.downloadCSV(),
+                moduleUrl + "export" +
+                   "?uuid=" + chartTab.getCollection().identifier() +
+                   "&mode=" + chartTab.getMode().getName() + "_at_export" +
+                   "&type=at" +
+                   "&server=" + config.getServerUrl() +
+                   "&locale=" + config.getLocale() +
+                   "&km=" + chartTab.getCollectionView().getCurrentKm(),
+                20,
+                20
+            );
+            exportAT.setTooltip(MSG.exportATTooltip());
+        }
 
         downloadPNG = new ImgLink(
             baseUrl + MSG.downloadPNG(),
@@ -193,17 +218,6 @@
         chartProperties.setTooltip(MSG.chartPropertiesTooltip());
 
         initLayout();
-        addResizedHandler(new ResizedHandler() {
-            @Override
-            public void onResized(ResizedEvent e) {
-                if (getVisibleWidth() < 740) {
-                    setHeight(55);
-                }
-                else {
-                    setHeight(40);
-                }
-            }
-        });
     }
 
     /** Set width, height and other properties of an imagebutton. */
@@ -220,7 +234,7 @@
     }
 
 
-    private ChartOutputTab getChartOutputTab() {
+    protected ChartOutputTab getChartOutputTab() {
         return (ChartOutputTab)getOutputTab();
     }
 
@@ -243,6 +257,9 @@
         addMember(downloadPDF);
         addMember(downloadSVG);
         addMember(downloadCSV);
+        if (getChartOutputTab().getMode().getName().equals("fix_wq_curve")) {
+            addMember(exportAT);
+        }
         addMember(zoomToMaxExtent);
         addMember(historyBack);
         addMember(zoomOut);
@@ -257,6 +274,8 @@
 
         addMember(spacer);
         addMember(position);
+
+        setOverflow(Overflow.HIDDEN);
     }
 
     /**
@@ -299,5 +318,22 @@
     public void deselectControls() {
         zoombox.deselect();
     }
+
+    public void updateLinks() {
+        ChartOutputTab chartTab = getChartOutputTab();
+        String moduleUrl = GWT.getModuleBaseURL();
+        Config config = Config.getInstance();
+
+        if (chartTab.getMode().getName().equals("fix_wq_curve")) {
+            exportAT.setSource(
+                   moduleUrl + "export" +
+                   "?uuid=" + chartTab.getCollection().identifier() +
+                   "&mode=" + chartTab.getMode().getName() + "_at_export" +
+                   "&type=at" +
+                   "&server=" + config.getServerUrl() +
+                   "&locale=" + config.getLocale() +
+                   "&km=" + chartTab.getCollectionView().getCurrentKm());
+        }
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/CrossSectionChartThemePanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/CrossSectionChartThemePanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,60 +1,30 @@
 package de.intevation.flys.client.client.ui.chart;
 
 import com.google.gwt.core.client.GWT;
-
-import com.google.gwt.i18n.client.NumberFormat;
-
 import com.google.gwt.user.client.rpc.AsyncCallback;
-
-import com.smartgwt.client.data.Record;
-
 import com.smartgwt.client.types.ListGridFieldType;
-
 import com.smartgwt.client.util.SC;
-
-import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.Label;
-
-import com.smartgwt.client.widgets.events.ClickEvent;
-
 import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.FormItemValueFormatter;
-import com.smartgwt.client.widgets.form.FormItemValueParser;
-
-import com.smartgwt.client.widgets.form.fields.FormItem;
 import com.smartgwt.client.widgets.form.fields.SelectItem;
-import com.smartgwt.client.widgets.form.fields.SpinnerItem;
-import com.smartgwt.client.widgets.form.fields.TextItem;
-
-import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
-import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
 import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
 import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
-import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
-import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
-
 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.layout.HLayout;
 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.ClickHandler;
 import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
 
 import de.intevation.flys.client.client.Config;
-
 import de.intevation.flys.client.client.services.CrossSectionKMServiceAsync;
 import de.intevation.flys.client.client.services.LoadArtifactService;
 import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
-
 import de.intevation.flys.client.client.ui.CollectionView;
-
+import de.intevation.flys.client.client.widgets.KMSpinner;
+import de.intevation.flys.client.client.widgets.KMSpinnerChangeListener;
 import de.intevation.flys.client.shared.model.Artifact;
 import de.intevation.flys.client.shared.model.Data;
 import de.intevation.flys.client.shared.model.DefaultArtifact;
@@ -80,7 +50,9 @@
  * Also can show 'area creation' context menus.
  */
 public class CrossSectionChartThemePanel
-extends      ChartThemePanel {
+extends ChartThemePanel
+implements KMSpinnerChangeListener
+{
     /** Artifact Clone/Creation service. */
     protected LoadArtifactServiceAsync loadService =
                 GWT.create(LoadArtifactService.class);
@@ -270,12 +242,14 @@
 
 
     /** Disable the UI (becomes gray, inresponsive to user input). */
+    @Override
     public void disable() {
         this.layout.setDisabled(true);
     }
 
 
     /** DisDisable the UI (becomes ungray, responsive to user input). */
+    @Override
     public void enable() {
         this.layout.setDisabled(false);
     }
@@ -422,9 +396,7 @@
      *                    two values in \param in are in the same distance to
      *                    \param to.
      */
-    public void spinnerValueEntered(final SpinnerItem item,
-        final double enteredKm, final FacetRecord facetRecord, final boolean up
-    ) {
+    public void spinnerValueEntered(KMSpinner spinner, final double enteredKm, final FacetRecord facetRecord, final boolean up) {
         disable();
         Config config       = Config.getInstance();
         final String locale = config.getLocale();
@@ -455,6 +427,7 @@
                     //updateGrid();
                     enable();
                 }
+
                 @Override
                 public void onSuccess(Map<Integer, Double[]> obj) {
                     Double[] kms = obj.get(dbid);
@@ -492,156 +465,13 @@
 
 
     /**
-     * Create a "kilometer spinner" for CrossSection Facets.
-     * @param facetRecord The respective Facet/Theme.
-     * @return label, intialized SpinnerItem.
-     */
-    public SpinnerItem createSpinnerItem(FacetRecord facetRecord) {
-        SpinnerItem spinnerItem = new SpinnerItem();
-        spinnerItem.setShowTitle(false);
-        spinnerItem.setTitle("Waterlevel-Spinner");
-        spinnerItem.setWidth(45);
-        spinnerItem.setDefaultValue(Double.valueOf(facetRecord.getTheme()
-            .getCollectionItem()
-            .getData().get(CS_KM)));
-
-        spinnerItem.setMin(0);
-        spinnerItem.setMax(2000);
-        spinnerItem.setStep(0.1d);
-        spinnerItem.setChangeOnKeypress(true);
-        return spinnerItem;
-    }
-
-
-    /**
-     * SpinnerItem-like element with text label and up/down buttons.
-     */
-    public class KmSpinner extends HLayout {
-        protected Label label;
-
-        protected FacetRecord facetRecord;
-
-        protected double currentValue;
-
-        public KmSpinner(FacetRecord facetRecord) {
-            super(2);
-            this.facetRecord = facetRecord;
-            final FacetRecord _facetRecord = facetRecord;
-            currentValue = Double.valueOf(facetRecord.getTheme()
-                .getCollectionItem().getData().get(CS_KM));
-            // Buttons and labels.
-            int height = 18;
-            // minusButton shall ask service for previous available cs.
-            Button minusButton = new Button("-");
-            minusButton.setWidth(10);
-            minusButton.setHeight(height);
-            minusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
-                public void onClick(ClickEvent evt) {
-                    spinnerValueEntered(null, currentValue - 0.1d, _facetRecord, false);
-                }
-            });
-
-            DynamicForm form = new DynamicForm();
-            final TextItem kmField = new TextItem();
-            kmField.setValue(currentValue);
-            kmField.setWidth(35);
-            kmField.setTitle("");
-            kmField.setHeight(height);
-
-            FormItemValueFormatter doubleFormat = new FormItemValueFormatter() {
-                public String formatValue(Object value, Record record,
-                    DynamicForm form, FormItem item) {
-                        if (value != null) {
-                            NumberFormat nf = NumberFormat.getDecimalFormat();
-                            try {
-                                double d = Double.valueOf(value.toString()).doubleValue();
-                                return nf.format(d);
-                            } catch (Exception e) {
-                                return value.toString();
-                            }
-                        }
-                        else {
-                            return null;
-                        }
-                    }
-            };
-            kmField.setEditorValueFormatter(doubleFormat);
-
-            FormItemValueParser doubleParser = new FormItemValueParser() {
-                public Object parseValue(String value,
-                                  DynamicForm form,
-                                  FormItem item) {
-                    if (value == null)
-                        return null;
-                    try {
-                        NumberFormat nf = NumberFormat.getDecimalFormat();
-                        double d = nf.parse(value.toString());
-                        return (new Double(d)).toString();
-                    }
-                    catch(NumberFormatException nfe) {
-                        return value;
-                    }
-                }
-            };
-            kmField.setEditorValueParser(doubleParser);
-
-            // Update on focus lost and enter-pressed.
-            kmField.addBlurHandler(new BlurHandler() {
-                @Override
-                public void onBlur(BlurEvent be) {
-                    if (kmField.getValue() != null) {
-                        try {
-                            spinnerValueEntered(null,
-                                Double.parseDouble(kmField.getValue().toString()),
-                                _facetRecord, true);
-                        }
-                        catch(NumberFormatException nfe) {
-                            GWT.log("entered string cannot be parsed to double.");
-                        }
-                    }
-                }
-            });
-            kmField.addKeyPressHandler(new KeyPressHandler(){
-                @Override
-                public void onKeyPress(KeyPressEvent kpe) {
-                    if (kpe.getKeyName().equals("Enter")) {
-                        kmField.blurItem();
-                    }
-                }
-            });
-            // TODO: i18n Now add all the validators, formatters, editors/parsers  etc.
-            form.setFields(kmField);
-            form.setTitle("");
-            form.setTitlePrefix("");
-            form.setTitleSuffix("");
-            form.setTitleWidth(0);
-            form.setWidth(40);
-            form.setHeight(height);
-            // PlusButton shall ask service for next available cs.
-            Button plusButton = new Button("+");
-            plusButton.setWidth(10);
-            plusButton.setHeight(height);
-            plusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
-                public void onClick(ClickEvent evt) {
-                    spinnerValueEntered(null, currentValue + 0.1d, _facetRecord, true);
-                }
-            });
-            this.addMember(minusButton);
-            this.addMember(form);
-            this.addMember(plusButton);
-
-            this.setHeight(height*2);
-            this.setWidth(60);
-        }
-    }
-
-
-    /**
      * Create and configure the Grid to display.
      * @return ListGrid with Themes and related controls inside.
      */
     @Override
     protected ListGrid createGrid() {
+        final CrossSectionChartThemePanel parent = this;
+
         ListGrid list = new ListGrid() {
             @Override
             protected Canvas createRecordComponent(
@@ -659,23 +489,11 @@
                     String fieldName = this.getFieldName(colNum);
 
                     if (fieldName.equals(GRID_FIELD_ACTIONS)) {
-                        /*
-                        TODO:
-                        if (facetRecord.getTheme().getActive() != 1) {
-                            spinnerItem.disable();
-                        }
-                        */
-
-                        /*
-                        // To have visual representation of synchronous
-                        // navigation or not per theme, snip:
-                        if (synchronCrossSectionThemes.contains (themeHash
-                            (facetRecord.getTheme()))) {
-                            spinnerItem.setTextBoxStyle("bgBlueDark");
-                        }
-                        */
-
-                        return new KmSpinner(facetRecord);
+                        double currentValue =
+                            Double.valueOf(facetRecord.getTheme().getCollectionItem().getData().get(CS_KM));
+                        KMSpinner kmSpinner = new KMSpinner(currentValue, facetRecord);
+                        kmSpinner.addChangeListener(parent);
+                        return kmSpinner;
                     }
                     else {
                         return null;
@@ -715,7 +533,7 @@
         name.setType(ListGridFieldType.TEXT);
 
         ListGridField actions = new ListGridField(GRID_FIELD_ACTIONS,
-             MSG.chart_themepanel_header_actions(), 65);
+             MSG.chart_themepanel_header_actions(), 100);
 
         list.setFields(active, name, actions);
     }
@@ -734,6 +552,7 @@
 
 
     /** Returns name of cross section area facets. */
+    @Override
     protected String getAreaFacetName() {
         return "cross_section.area";
     }
@@ -745,6 +564,7 @@
      * TODO join with canArea, generalize to allow easier modification
      *      in subclasses.
      */
+    @Override
     protected boolean areAreaCompatible(Theme a, Theme b) {
         if (a.equals(b)) {
             return false;
@@ -760,6 +580,7 @@
      * True if context menu should contain 'create area' submenu on
      * this theme.
      */
+    @Override
     protected boolean canArea(Theme a) {
         return a.getFacet().equals("cross_section")
             || a.getFacet().equals("cross_section_water_line")
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ManualPointsEditor.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,61 +1,53 @@
 package de.intevation.flys.client.client.ui.chart;
 
-import java.util.List;
-
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
 import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONBoolean;
 import com.google.gwt.json.client.JSONNumber;
 import com.google.gwt.json.client.JSONParser;
 import com.google.gwt.json.client.JSONString;
-import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
 import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Button;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Label;
 import com.smartgwt.client.widgets.Window;
-import com.smartgwt.client.widgets.layout.VLayout;
-import com.smartgwt.client.widgets.layout.HLayout;
-import com.smartgwt.client.widgets.IButton;
-import com.smartgwt.client.widgets.Button;
-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.grid.CellEditValueFormatter;
+import com.smartgwt.client.widgets.grid.CellEditValueParser;
+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.RecordClickEvent;
 import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
-import com.smartgwt.client.types.ListGridFieldType;
-import com.smartgwt.client.widgets.grid.CellFormatter;
-import com.google.gwt.i18n.client.NumberFormat;
-
-import com.smartgwt.client.widgets.grid.CellEditValueParser;
-import com.smartgwt.client.widgets.grid.CellEditValueFormatter;
-import com.smartgwt.client.widgets.events.ClickEvent;
-import com.smartgwt.client.widgets.events.ClickHandler;
-
-import com.smartgwt.client.types.Alignment;
-
-import de.intevation.flys.client.shared.model.Artifact;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
 
 import de.intevation.flys.client.client.Config;
 import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.event.RedrawRequestEvent;
+import de.intevation.flys.client.client.event.RedrawRequestHandler;
+import de.intevation.flys.client.client.services.FeedServiceAsync;
+import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
+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.client.services.LoadArtifactService;
-import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
-import de.intevation.flys.client.client.services.FeedService;
-import de.intevation.flys.client.client.services.FeedServiceAsync;
-
 import de.intevation.flys.client.shared.model.Data;
 import de.intevation.flys.client.shared.model.DefaultArtifact;
 import de.intevation.flys.client.shared.model.DefaultData;
-import de.intevation.flys.client.shared.model.Recommendation;
-import de.intevation.flys.client.shared.model.Settings;
 import de.intevation.flys.client.shared.model.Property;
 import de.intevation.flys.client.shared.model.PropertyGroup;
+import de.intevation.flys.client.shared.model.Recommendation;
+import de.intevation.flys.client.shared.model.Settings;
 import de.intevation.flys.client.shared.model.StringProperty;
 
-import de.intevation.flys.client.client.event.RedrawRequestHandler;
-import de.intevation.flys.client.client.event.RedrawRequestEvent;
+import java.util.List;
 
 
 /**
@@ -80,6 +72,8 @@
     /** The listGrid showing point entries. */
     protected ListGrid listGrid;
 
+    protected ListGridFieldType fieldTypeX = ListGridFieldType.FLOAT;
+
     /** Service handle to clone and add artifacts to collection. */
     LoadArtifactServiceAsync loadArtifactService = GWT.create(
             de.intevation.flys.client.client.services.LoadArtifactService.class);
@@ -120,7 +114,7 @@
 
         for (int i = 0; i < size; i++) {
             CollectionItem item = collection.getItem(i);
-            String dataValue = (String) item.getData().get(pointDataItemName);
+            String dataValue = item.getData().get(pointDataItemName);
             if (dataValue != null) {
                 // Found it.
                 uuid = item.identifier();
@@ -178,52 +172,6 @@
         listGrid.setCanEdit(true);
         listGrid.setShowHeaderContextMenu(false);
 
-        CellFormatter doubleFormat = new CellFormatter() {
-            public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
-                if(value != null) {
-                    NumberFormat nf = NumberFormat.getDecimalFormat();
-                    try {
-                        double d = Double.valueOf(value.toString()).doubleValue();
-                        return nf.format(d);
-                    } catch (Exception e) {
-                        return value.toString();
-                    }
-                } else {
-                   return null;
-                }
-            }};
-
-        CellEditValueParser cevp = new CellEditValueParser() {
-            public Object parse(Object value, ListGridRecord record, int rowNum, int colNum) {
-                if (value == null)
-                    return null;
-                try {
-                    NumberFormat nf = NumberFormat.getDecimalFormat();
-                    double d = nf.parse(value.toString());
-                    return (new Double(d)).toString();
-                }
-                catch(NumberFormatException nfe) {
-                    return value;
-                }
-            }
-        };
-
-        CellEditValueFormatter cevf = new CellEditValueFormatter() {
-            public Object format(Object value, ListGridRecord record, int rowNum, int colNum) {
-                if (value == null) {
-                    return "";
-                }
-                NumberFormat nf = NumberFormat.getDecimalFormat();
-                try {
-                    double d = Double.valueOf(value.toString()).doubleValue();
-                    return nf.format(d);
-                }
-                catch(NumberFormatException nfe) {
-                    return value;
-                }
-            }
-        };
-
         // Use X and Y as default fallback.
         String xAxis = "X";
         String yAxis = "Y";
@@ -234,6 +182,7 @@
         if(axes != null) {
             for (Property p: axes) {
                 PropertyGroup pg = (PropertyGroup)p;
+                GWT.log(pg.toString());
                 StringProperty id =
                     (StringProperty)pg.getPropertyByName("id");
                 if(id.getValue().equals("X")) {
@@ -248,18 +197,29 @@
                 }
             }
         }
+
+        CellFormatter format = createCellFormatter();
+        CellEditValueParser cevp = createCellEditValueParser();
+        CellEditValueFormatter cevf = createCellEditValueFormatter();
+
         ListGridField xField =
-            new ListGridField(PointRecord.ATTRIBUTE_X, xAxis);
-        xField.setType(ListGridFieldType.FLOAT);
-        xField.setCellFormatter(doubleFormat);
-        xField.setEditValueParser(cevp);
-        xField.setEditValueFormatter(cevf);
-
+                new ListGridField(PointRecord.ATTRIBUTE_X, xAxis);
+        if(xAxis.equalsIgnoreCase("date") || xAxis.equalsIgnoreCase("Datum")) {
+            // FIXME: This is a hack for the special axis with Date type
+            xField.setType(ListGridFieldType.DATE);
+            this.fieldTypeX = ListGridFieldType.DATE;
+        }
+        else {
+            xField.setType(ListGridFieldType.FLOAT);
+            xField.setCellFormatter(format);
+            xField.setEditValueParser(cevp);
+            xField.setEditValueFormatter(cevf);
+        }
 
         ListGridField yField =
             new ListGridField(PointRecord.ATTRIBUTE_Y, yAxis);
         yField.setType(ListGridFieldType.FLOAT);
-        yField.setCellFormatter(doubleFormat);
+        yField.setCellFormatter(format);
         yField.setEditValueParser(cevp);
         yField.setEditValueFormatter(cevf);
 
@@ -334,6 +294,61 @@
     }
 
 
+    protected CellFormatter createCellFormatter() {
+        return new CellFormatter() {
+            public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
+                if(value != null) {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
+                    try {
+                        double d = Double.valueOf(value.toString()).doubleValue();
+                        return nf.format(d);
+                    } catch (Exception e) {
+                        return value.toString();
+                    }
+                } else {
+                   return null;
+                }
+            }};
+    }
+
+
+    protected CellEditValueParser createCellEditValueParser() {
+        return new CellEditValueParser() {
+            public Object parse(Object value, ListGridRecord record, int rowNum, int colNum) {
+                if (value == null)
+                    return null;
+                try {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
+                    double d = nf.parse(value.toString());
+                    return (new Double(d)).toString();
+                }
+                catch(NumberFormatException nfe) {
+                    return value;
+                }
+            }
+        };
+    }
+
+
+    protected CellEditValueFormatter createCellEditValueFormatter() {
+        return new CellEditValueFormatter() {
+            public Object format(Object value, ListGridRecord record, int rowNum, int colNum) {
+                if (value == null) {
+                    return "";
+                }
+                NumberFormat nf = NumberFormat.getDecimalFormat();
+                try {
+                    double d = Double.valueOf(value.toString()).doubleValue();
+                    return nf.format(d);
+                }
+                catch(NumberFormatException nfe) {
+                    return value;
+                }
+            }
+        };
+    }
+
+
     /** Create JSON representation of the points present in the list grid. */
     protected JSONArray jsonArrayFromListGrid() {
         JSONArray list = new JSONArray();
@@ -365,8 +380,13 @@
                     nameString = xString + "/" + yString;
                 }
 
-                data.set(0, new JSONNumber(record.
-                    getAttributeAsDouble(PointRecord.ATTRIBUTE_X)));
+                if(fieldTypeX.equals(ListGridFieldType.DATE)) {
+                    data.set(0, new JSONString(record.getAttribute(PointRecord.ATTRIBUTE_X)));
+                }
+                else {
+                    data.set(0, new JSONNumber(record.
+                            getAttributeAsDouble(PointRecord.ATTRIBUTE_X)));
+                }
                 data.set(1, new JSONNumber(record.
                     getAttributeAsDouble(PointRecord.ATTRIBUTE_Y)));
                 data.set(2, new JSONString(nameString));
@@ -406,7 +426,7 @@
                         enable();
                     }
                     public void onSuccess(Artifact fartifact) {
-                        GWT.log("Successfully set points ");
+                        GWT.log("Successfully set points");
                         redrawRequestHandler.onRedrawRequest(
                             new RedrawRequestEvent());
                         destroy();
@@ -479,8 +499,6 @@
         protected static final String ATTRIBUTE_NAME = "name";
         protected static final String ATTRIBUTE_ACTIVE = "active";
 
-        private PointRecord() {;}
-
         public PointRecord(boolean b, double x, double y, String name) {
             setActive(b);
             setName(name);
@@ -526,9 +544,14 @@
     protected boolean isDialogValid() {
         boolean valid = true;
         for (ListGridRecord record : listGrid.getRecords()) {
-            if (record.getAttributeAsDouble(PointRecord.ATTRIBUTE_X) == null
-                || record.getAttributeAsDouble(PointRecord.ATTRIBUTE_Y) == null) {
-                return false;
+            try {
+                if (record.getAttribute(PointRecord.ATTRIBUTE_X) == null
+                    || record.getAttribute(PointRecord.ATTRIBUTE_Y) == null) {
+                    return false;
+                }
+            }
+            catch(IllegalArgumentException ex) {
+
             }
         }
         if (listGrid.hasErrors()) {
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ManualWSPEditor.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ManualWSPEditor.java	Fri Sep 28 12:15:40 2012 +0200
@@ -203,12 +203,8 @@
             public void onBlur(BlurEvent e) {
                  DoubleValidator validator = new DoubleValidator();
                  Map errors = e.getForm().getErrors();
-                 if(validator.validate(e.getItem(), errors)) {
-                     e.getForm().setErrors(errors, true);
-                 }
-                 else {
-                     e.getForm().setErrors(errors, true);
-                 }
+                 validator.validate(e.getItem(), errors);
+                 e.getForm().setErrors(errors, true);
             }
         });
         nameInputPanel = new TextItem();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/MousePositionPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/MousePositionPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -14,6 +14,7 @@
 
 
 /**
+ * Panel showing the mouse position in data space.
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class MousePositionPanel extends HLayout implements MouseMoveHandler {
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/NaviChartOutputTab.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/NaviChartOutputTab.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 import java.util.HashMap;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
 
 import com.smartgwt.client.types.Alignment;
 
@@ -20,8 +21,6 @@
 import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
 import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
 
-import com.smartgwt.client.widgets.form.validator.IsFloatValidator;
-
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
@@ -80,7 +79,6 @@
         currentkm = new TextItem();
         currentkm.setWidth(60);
         currentkm.setShowTitle(false);
-        currentkm.setValidators(new IsFloatValidator());
 
         form.setFields(currentkm);
         form.setWidth(60);
@@ -88,7 +86,7 @@
 
         String s = fix.getArtifactDescription().getDataValueAsString("step");
         try {
-            double ds = Double.valueOf(s).doubleValue();
+            double ds = Double.parseDouble(s);
             collectionView.setSteps(ds);
         }
         catch(NumberFormatException nfe) {
@@ -97,11 +95,23 @@
         collectionView.setMinKm(fix.getFilter().getFromKm());
         collectionView.setMaxKm(fix.getFilter().getToKm());
 
+        NumberFormat nf = NumberFormat.getDecimalFormat();
         if (collectionView.getCurrentKm() == -1d) {
-            currentkm.setValue(fix.getFilter().getFromKm());
+            try {
+                double d = Double.valueOf(fix.getFilter().getFromKm());
+                currentkm.setValue(nf.format(d));
+            } catch (NumberFormatException e) {
+                currentkm.setValue(fix.getFilter().getFromKm());
+            }
             collectionView.setCurrentKm(fix.getFilter().getFromKm());
         }
         else {
+            try {
+                double d = Double.valueOf(fix.getFilter().getFromKm());
+                currentkm.setValue(nf.format(d));
+            } catch (NumberFormatException e) {
+                currentkm.setValue(fix.getFilter().getFromKm());
+            }
             currentkm.setValue(collectionView.getCurrentKm());
         }
 
@@ -109,7 +119,13 @@
             public void onClick(ClickEvent ce) {
                 tbarPanel.deselectControls();
                 updateChartDown();
-                currentkm.setValue(collectionView.getCurrentKm());
+                try {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
+                    double d = Double.valueOf(collectionView.getCurrentKm());
+                    currentkm.setValue(nf.format(d));
+                } catch (NumberFormatException e) {
+                    currentkm.setValue(collectionView.getCurrentKm());
+                }
             }
         });
 
@@ -117,7 +133,13 @@
             public void onClick(ClickEvent ce) {
                 tbarPanel.deselectControls();
                 updateChartUp();
-                currentkm.setValue(collectionView.getCurrentKm());
+                try {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
+                    double d = Double.valueOf(collectionView.getCurrentKm());
+                    currentkm.setValue(nf.format(d));
+                } catch (NumberFormatException e) {
+                    currentkm.setValue(collectionView.getCurrentKm());
+                }
             }
         });
 
@@ -126,14 +148,22 @@
                 if (!kpe.getKeyName().equals("Enter")) {
                     return;
                 }
-                if(kpe.getForm().validate() && kpe.getItem().getValue() != null) {
+                if(kpe.getItem().getValue() != null) {
                     tbarPanel.deselectControls();
                     try {
                         String s = kpe.getItem().getValue().toString();
-                        Double d = new Double(s);
+                        double d;
+                        try {
+                            NumberFormat nf = NumberFormat.getDecimalFormat();
+                            d = nf.parse(s);
+                            currentkm.setValue(nf.format(d));
+                        } catch (NumberFormatException e) {
+                            d = -1d;
+                        }
                         if (d <= collectionView.getMaxKm() &&
                             d >= collectionView.getMinKm()) {
                             collectionView.setCurrentKm(d);
+                            tbarPanel.updateLinks();
                             if (right != null) {
                                 updateChartPanel();
                                 updateChartInfo();
@@ -162,6 +192,7 @@
             double newVal = currentKm * 100;
             newVal += (collectionView.getSteps() / 10);
             collectionView.setCurrentKm((double)Math.round(newVal) / 100);
+            tbarPanel.updateLinks();
             updateChartPanel();
             updateChartInfo();
         }
@@ -172,6 +203,7 @@
             double newVal = currentKm * 100;
             newVal -= (collectionView.getSteps() / 10);
             collectionView.setCurrentKm((double)Math.round(newVal) / 100);
+            tbarPanel.updateLinks();
             updateChartPanel();
             updateChartInfo();
         }
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/OverviewOutputTab.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/OverviewOutputTab.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,203 +1,109 @@
 package de.intevation.flys.client.client.ui.chart;
 
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
 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.ResizedEvent;
-import com.smartgwt.client.widgets.events.ResizedHandler;
-import com.smartgwt.client.widgets.layout.HLayout;
-import com.smartgwt.client.widgets.layout.VLayout;
-
-import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.event.OutputParameterChangeHandler;
+import de.intevation.flys.client.client.event.RedrawRequestHandler;
 import de.intevation.flys.client.client.ui.CollectionView;
-import de.intevation.flys.client.client.ui.OutputTab;
-
+import de.intevation.flys.client.client.ui.ImgLink;
 import de.intevation.flys.client.shared.model.Collection;
 import de.intevation.flys.client.shared.model.OutputMode;
-
-
-/**
- * An overview output tab. This tab displays an overview of all charts
- * integrated in the current calculation mode.
- *
- * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
- */
-public class OverviewOutputTab
-extends OutputTab
-implements   ResizedHandler
-{
-    /** The collection view.*/
-    protected CollectionView view;
-
-    /** The root layout. */
-    protected HLayout root;
-
-    /** The columns */
-    protected VLayout[] columns;
-
-    /** The chart container.*/
-    protected Canvas[][] charts;
-
-    /** All relevant output modes. */
-    protected Map<String, OutputMode> relModes;
+import de.intevation.flys.client.shared.model.Theme;
 
 
-    public OverviewOutputTab(
-        String title,
-        Collection collection,
-        OutputMode mode,
-        CollectionView collectionView)
-    {
-        super(title, collection, collectionView, mode);
+public class OverviewOutputTab extends ChartOutputTab  {
 
-        relModes = new HashMap<String, OutputMode>();
-
-        Map<String, OutputMode> modes = collection.getOutputModes();
-        Set<String> keys = modes.keySet();
+    private class NoChartThemePanel extends ChartThemePanel {
 
-        // Get all relevant outputs.
-        for (String key: keys) {
-            OutputMode m = modes.get(key);
-            if (m.getType().equals("chart")) {
-                relModes.put(key, m);
-            }
+        public NoChartThemePanel(OutputMode mode, CollectionView view) {
+            super(mode, view);
         }
 
-        root = new HLayout();
-        setPane(root);
-        root.addResizedHandler(this);
-
-        // Get the column and row count and initialize the grid.
-        int width = getColumnCount(relModes.size());
-        int height = getRowCount(relModes.size());
-        charts = new Canvas[width][height];
-        columns = new VLayout[width];
-
-        for (int i = 0; i < width; i++) {
-            columns[i] = new VLayout();
-            root.addMember(columns[i]);
+        @Override
+        public void activateTheme(Theme theme, boolean active) { }
 
-            for (int j = 0; j < height; j++) {
-                charts[i][j] = new Canvas();
-
-                // This is for 3, 6 or 9 charts only! 
-                // TODO: Calculate the height.
-                charts[i][j].setHeight("50%");
+        @Override
+        public void feedTellArea(
+            final String artifact,
+            Theme under,
+            Theme over,
+            boolean between
+        ) { }
 
-                String type =
-                    ((OutputMode)relModes.values()
-                        .toArray()[j + i * height]).getName();
-                columns[i].addMember(charts[i][j]);
-                charts[i][j].addChild(
-                    new Img(getImgUrl(
-                        charts[i][j].getWidth(),
-                        charts[i][j].getHeight(), type)));
+        @Override
+        public void createAreaArtifact(
+            final Theme   over,
+            final Theme   under,
+            final boolean between
+        ) { }
 
-            }
+        @Override
+        public void addOutputParameterChangeHandler(OutputParameterChangeHandler h) { }
+
+        @Override
+        public void addRedrawRequestHandler(RedrawRequestHandler h){ }
+    }
+
+
+
+    private class MinimumChartToolbar extends ChartToolbar {
+
+        public MinimumChartToolbar(ChartOutputTab tab) {
+            super(tab);
+        }
+
+        @Override
+        protected void initTools() {
+            GWT.log("CREATE NEW MINIMALISTIC CHART TOOLBAR");
+            ChartOutputTab chartTab = getChartOutputTab();
+
+            String baseUrl = GWT.getHostPageBaseURL();
+
+            downloadPNG = new ImgLink(
+                baseUrl + MSG.downloadPNG(),
+                chartTab.getExportUrl(-1, -1, "png"),
+                20,
+                20);
+            downloadPNG.setTooltip(MSG.downloadPNGTooltip());
+
+            initLayout();
+        }
+
+
+        @Override
+        protected void initLayout() {
+            setWidth100();
+            setHeight(PANEL_HEIGHT);
+            setMembersMargin(10);
+            setPadding(5);
+            setBorder("1px solid black");
+
+            addMember(downloadPNG);
         }
     }
 
 
-    /**
-     * Resize handler.
-     * 
-     * @param event The resize event.
-     */
-    @Override
-    public void onResized(ResizedEvent event) {
-        for (int i = 0; i < charts.length; i++) {
-            // This is for 3, 6 or 9 charts only! 
-            // TODO: Calculate the width.
-            columns[i].setWidth(root.getWidth()/3);
 
-            for (int j = 0; j < charts[i].length; j++) {
-                String type =
-                    ((OutputMode)relModes.values()
-                        .toArray()[j + i * charts[i].length]).getName();
-                Canvas[] children = charts[i][j].getChildren();
-                for (int k = 0; k < children.length; k++) {
-                    charts[i][j].removeChild(children[k]);
-                }
-                charts[i][j].addChild(new Img(
-                        getImgUrl(
-                            charts[i][j].getWidth(),
-                            charts[i][j].getHeight(),
-                            type),
-                        charts[i][j].getWidth(),
-                        charts[i][j].getHeight()
-                        ));
-            }
-        }
+    public OverviewOutputTab(
+        String         title,
+        Collection     collection,
+        OutputMode     mode,
+        CollectionView collectionView
+        ){
+        super(title, collection, mode, collectionView);
+        left.setVisible(false);
     }
 
 
-    /**
-     * Returns the column count for the grid.
-     *
-     * @param count all fields
-     * @return the column count
-     */
-    protected int getRowCount(int count) {
-        if (count <= 3) {
-            return 1;
-        }
-        else if (count > 3 && count < 9) {
-            return 2;
-        }
-        else {
-            return 3;
-        }
+    @Override
+    public ChartThemePanel createThemePanel(
+        OutputMode mode, CollectionView view
+        ) {
+        return new NoChartThemePanel(mode, view);
     }
 
-
-    /**
-     * Returns the row count for the grid.
-     *
-     * @param count all fields
-     * @return the row count
-     */
-    protected int getColumnCount(int count) {
-        if(count <= 3) {
-            return count;
-        }
-        else if(count > 3 && count < 9) {
-            return ((count + (count % 2))/getRowCount(count));
-        }
-        else {
-            return (count + (3 - (count % 3))/getRowCount(count));
-        }
-    }
-
-
-    /**
-     * 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.
-     * @param xr Optional x range (used for zooming).
-     * @param yr Optional y range (used for zooming).
-     *
-     * @return the URL to the chart image.
-     */
-    protected String getImgUrl(int width, int height, String type) {
-        Config config = Config.getInstance();
-
-        String imgUrl = GWT.getModuleBaseURL();
-        imgUrl += "chart";
-        imgUrl += "?uuid=" + collection.identifier();
-        imgUrl += "&type=" + type;
-        imgUrl += "&locale=" + config.getLocale();
-        imgUrl += "&timestamp=" + new Date().getTime();
-        imgUrl += "&width=" + Integer.toString(width);
-        imgUrl += "&height=" + Integer.toString(height);
-
-        return imgUrl;
+    @Override
+    public ChartToolbar createChartToolbar(ChartOutputTab tab) {
+        return new MinimumChartToolbar(tab);
     }
 }
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixEventSelect.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixEventSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -122,7 +122,7 @@
                     arr[i] = new IntDataItem("id", "id", v.intValue());
                 }
                 catch (NumberFormatException nfe) {
-                    return  (Data[]) data.toArray(new Data[data.size()]);
+                    return  data.toArray(new Data[data.size()]);
                 }
             }
 
@@ -132,7 +132,7 @@
             data.add(iad);
         }
 
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixFunctionSelect.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,173 @@
+package de.intevation.flys.client.client.ui.fixation;
+
+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.SelectItem;
+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 java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class FixFunctionSelect extends FixationPanel {
+    private static final Map<String, String> funcDesc = new HashMap<String, String>();
+
+    static {
+        funcDesc.put("log", "W(Q) = m*ln(Q + b)");
+        funcDesc.put("linear", "W(Q) = m * Q + b");
+        funcDesc.put("log-linear", "W(Q) = a*ln(m*Q+b)");
+        funcDesc.put("exp", "W(Q) = m * a^Q + b");
+        funcDesc.put("quad", "W(Q) = n*Q^2+m*Q+b");
+        funcDesc.put("pow", "W(Q) = a * Q^c + d");
+        funcDesc.put("sq-pow", "S(Q) = a * Q^b");
+    }
+
+    /** The combobox.*/
+    protected DynamicForm form;
+
+    @Override
+    public Canvas createWidget(DataList data) {
+        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);
+            label.setWidth(400);
+
+            SelectItem combobox = new SelectItem(d.getLabel());
+            combobox.setWidth(250);
+
+            LinkedHashMap<String, String> funcTypes = new LinkedHashMap<String, String>();
+
+            boolean  defaultSet = false;
+            boolean  first      = true;
+
+            DataItem def      = d.getDefault();
+            String   defValue = def != null ? def.getStringValue() : null;
+
+            if (defValue != null && defValue.length() > 0) {
+                initial.put(d.getLabel(), def.getStringValue());
+                defaultSet = true;
+            }
+
+            // I was here. Me 2.
+            for (DataItem item: d.getItems()) {
+                if (!defaultSet && first) {
+                    initial.put(d.getLabel(), item.getStringValue());
+                    first = false;
+                }
+
+                funcTypes.put(item.getStringValue(), item.getLabel());
+            }
+
+            label.setWidth(50);
+            combobox.setValueMap(funcTypes);
+            combobox.setShowTitle(false);
+            form.setItems(combobox);
+
+            layout.addMember(label);
+            layout.addMember(form);
+        }
+
+        form.setValues(initial);
+
+        layout.setAlign(VerticalAlignment.TOP);
+
+        return layout;
+    }
+
+
+    @Override
+    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();
+
+                String desc = funcDesc.containsKey(item.getLabel()) ?
+                        funcDesc.get(item.getLabel()) : item.getLabel();
+                hLayout.addMember(label);
+                hLayout.addMember(new Label(desc));
+
+                vLayout.addMember(hLayout);
+                vLayout.setWidth("130px");
+            }
+        }
+
+        Canvas back = getBackButton(dataList.getState());
+
+        layout.addMember(label);
+        layout.addMember(vLayout);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+
+    @Override
+    public 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;
+    }
+
+
+    @Override
+    public void setValues(String cid, boolean checked) {
+    }
+
+    @Override
+    public boolean renderCheckboxes() {
+        return false;
+    }
+
+    @Override
+    public void success() {
+    }
+
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixGaugeSelectPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixGaugeSelectPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,29 +1,26 @@
 package de.intevation.flys.client.client.ui.fixation;
 
-import java.util.List;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-
 import com.google.gwt.core.client.GWT;
 
 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.SelectItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
-import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.fields.SelectItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
 import de.intevation.flys.client.client.FLYSConstants;
-
 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 java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
 /**
  * This UIProvider creates a panel for location or distance input.
  *
@@ -41,17 +38,19 @@
     protected SelectItem from;
     protected SelectItem to;
 
-    protected LinkedHashMap mapValues;
+    protected LinkedHashMap<String, String> mapValues;
 
     public FixGaugeSelectPanel() {
         htmlOverview = "";
-        mapValues = new LinkedHashMap();
-        mapValues.put("0", "[0, (MNQ+MQ)/2)");
-        mapValues.put("1", "[(MNQ+MQ)/2, (MQ+MHQ)/2)");
-        mapValues.put("2", "[(MQ+MHQ)/2, HQ5)");
-        mapValues.put("3", "[HQ5, \u221e)");
+
+        mapValues = new LinkedHashMap<String, String>();
+        mapValues.put("0", MESSAGES.gauge_mnq());
+        mapValues.put("1", MESSAGES.gauge_mq());
+        mapValues.put("2", MESSAGES.gauge_mhq());
+        mapValues.put("3", MESSAGES.gauge_hq5());
     }
 
+    @Override
     public Canvas createWidget(DataList data) {
         instances.put(this.artifact.getUuid(), this);
 
@@ -121,6 +120,7 @@
      *
      * @return the selected/inserted data.
      */
+    @Override
     public Data[] getData() {
         List<Data> data = new ArrayList<Data>();
 
@@ -139,7 +139,7 @@
                 null,
                 new DataItem[] { secItem }));
         }
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
@@ -156,14 +156,15 @@
     }
 
 
+    @Override
     public void success() {}
 
     protected boolean saveClassValues() {
         String v1 = from.getValueAsString();
         String v2 = to.getValueAsString();
         try {
-            int v1i = Integer.valueOf(v1).intValue();
-            int v2i = Integer.valueOf(v2).intValue();
+            int v1i = Integer.parseInt(v1);
+            int v2i = Integer.parseInt(v2);
             if (v1i <= v2i) {
                 this.first = v1;
                 this.second = v2;
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixLocationPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixLocationPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -133,7 +133,7 @@
             data.add(new DefaultData("step", null, null, new DataItem[]{ si }));
         }
         // what else?
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixMultiPeriodPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixMultiPeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,38 +1,33 @@
 package de.intevation.flys.client.client.ui.fixation;
 
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Date;
-
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.i18n.client.DateTimeFormat;
 
-import com.smartgwt.client.data.Record;
-
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.Label;
-import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.events.ClickEvent;
 import com.smartgwt.client.widgets.events.ClickHandler;
-
 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.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
-import com.smartgwt.client.types.ListGridFieldType;
-
-import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
-
+import de.intevation.flys.client.client.FLYSConstants;
 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 java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
 /**
  * This UIProvider creates a panel for location or distance input.
  *
@@ -41,6 +36,8 @@
 public class FixMultiPeriodPanel
 extends      FixPeriodPanel
 {
+    /** The message class that provides i18n strings. */
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
 
     protected ListGrid elements;
 
@@ -54,12 +51,13 @@
         super(startName, endName);
     }
 
+    @Override
     public Canvas createWidget(DataList data) {
         HLayout input = new HLayout();
         VLayout root = new VLayout();
         VLayout grid = new VLayout();
         VLayout layout = (VLayout) super.createWidget(data);
-        Button add = new Button("Add");
+        Button add = new Button(MESSAGES.add());
         elements = new ListGrid();
 
         add.addClickHandler(new ClickHandler() {
@@ -169,6 +167,7 @@
      *
      * @return the selected/inserted data.
      */
+    @Override
     public Data[] getData() {
         List<Data> data = new ArrayList<Data>();
 
@@ -181,10 +180,11 @@
                         null,
                         new DataItem[] { item }));
         }
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
+    @Override
     protected boolean saveDateValues() {
         ListGridRecord[] lgr = elements.getRecords();
         if (lgr.length == 0) {
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixPeriodPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixPeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,26 +1,18 @@
 package de.intevation.flys.client.client.ui.fixation;
 
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Date;
-
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
 
 import com.smartgwt.client.util.SC;
-
 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.DateRangeItem;
 import com.smartgwt.client.widgets.layout.HLayout;
 import com.smartgwt.client.widgets.layout.VLayout;
 
-import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.fields.DateRangeItem;
-
+import de.intevation.flys.client.client.Config;
 import de.intevation.flys.client.client.FLYSConstants;
-
 import de.intevation.flys.client.shared.model.Data;
 import de.intevation.flys.client.shared.model.DataItem;
 import de.intevation.flys.client.shared.model.DataList;
@@ -28,6 +20,10 @@
 import de.intevation.flys.client.shared.model.DefaultDataItem;
 import de.intevation.flys.client.shared.model.FixingsOverviewInfo.FixEvent;
 
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
 /**
  * This UIProvider creates a panel for location or distance input.
  *
@@ -57,6 +53,7 @@
         htmlOverview = "";
     }
 
+    @Override
     public Canvas createWidget(DataList data) {
         instances.put(this.artifact.getUuid(), this);
 
@@ -133,6 +130,7 @@
      *
      * @return the selected/inserted data.
      */
+    @Override
     public Data[] getData() {
         List<Data> data = new ArrayList<Data>();
 
@@ -154,7 +152,7 @@
                 new DataItem[] { endItem }));
         }
 
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return data.toArray(new Data[data.size()]);
     }
 
 
@@ -170,23 +168,59 @@
         return false;
     }
 
+    protected String getLocaleDateFormat() {
+        String loc = Config.getInstance().getLocale();
+        if ("de".equals(loc)) {
+            return "yy.MM.yyyy";
+        }
+        else {
+            return "MM/dd/yyyy";
+        }
+    }
 
+    @Override
     public void success() {
         List<FixEvent> list = fixInfo.getEvents();
-        DateTimeFormat df = DateTimeFormat.getFormat(
-                DateTimeFormat.PredefinedFormat.DATE_MEDIUM);
 
+        // The date in FixEvent is always "de" locale, so it seems...
+        DateTimeFormat df = DateTimeFormat.getFormat("yy.MM.yyyy");
+
+        if (!setFromAndToDate(list, df)) {
+            // or perhaps "en"?
+            df = DateTimeFormat.getFormat("MM/dd/yyyy");
+
+            if (!setFromAndToDate(list, df)) {
+                GWT.log("FixPeriodPanel::success(): could not set from and to dates!");
+            }
+        }
+    }
+
+    protected boolean setFromAndToDate(List<FixEvent> list, DateTimeFormat df) {
         try {
-            Date f = df.parse(list.get(0).getDate());
-            Date t = df.parse(list.get(list.size() - 1).getDate());
-            this.inputPanel.setFromDate(f);
-            this.inputPanel.setToDate(t);
+            setFromDate(list.get(0).getDate(), df);
+            setToDate(list.get(list.size() - 1).getDate(), df);
+            return true;
         }
-        catch(IllegalArgumentException pe) {
-            GWT.log(pe.toString());
+        catch(IllegalArgumentException ex) {
+            GWT.log("FixPeriodPanel::setFromAndToDate(): " + ex.toString());
+            return false;
         }
     }
 
+    protected void setFromDate(String date, DateTimeFormat df)
+        throws IllegalArgumentException
+    {
+        Date from = df.parse(date);
+        this.inputPanel.setFromDate(from);
+    }
+
+    protected void setToDate(String date, DateTimeFormat df)
+        throws IllegalArgumentException
+    {
+        Date to = df.parse(date);
+        this.inputPanel.setToDate(to);
+    }
+
     protected boolean saveDateValues() {
         Date st = inputPanel.getFromDate();
         Date en = inputPanel.getToDate();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixQSelectPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixQSelectPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,8 +1,5 @@
 package de.intevation.flys.client.client.ui.fixation;
 
-import java.util.List;
-import java.util.ArrayList;
-
 import com.google.gwt.core.client.GWT;
 
 import com.smartgwt.client.widgets.Canvas;
@@ -45,9 +42,7 @@
      * @return the selected/inserted data.
      */
     public Data[] getData() {
-        List<Data> data = new ArrayList<Data>();
-
-        return (Data[]) data.toArray(new Data[data.size()]);
+        return new Data[0];
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixationPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/fixation/FixationPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,51 +1,59 @@
 package de.intevation.flys.client.client.ui.fixation;
 
-import java.util.HashMap;
-import java.util.Date;
-
 import com.google.gwt.core.client.GWT;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.NumberFormat;
+
+import com.google.gwt.json.client.JSONNumber;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
-import com.google.gwt.json.client.JSONObject;
-import com.google.gwt.json.client.JSONNumber;
-import com.google.gwt.json.client.JSONString;
-import com.google.gwt.i18n.client.DateTimeFormat;
+import com.smartgwt.client.types.Alignment;
 
 import com.smartgwt.client.util.SC;
 
+import com.smartgwt.client.widgets.Button;
 import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.Button;
+import com.smartgwt.client.widgets.HTMLPane;
+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.events.ResizedEvent;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+
 import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.HTMLPane;
-import com.smartgwt.client.widgets.layout.VLayout;
-import com.smartgwt.client.widgets.layout.HLayout;
+
 import com.smartgwt.client.widgets.form.fields.TextItem;
-import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+
 import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
-import com.smartgwt.client.widgets.events.ClickHandler;
-import com.smartgwt.client.widgets.events.ClickEvent;
-import com.smartgwt.client.widgets.events.ResizedHandler;
-import com.smartgwt.client.widgets.events.ResizedEvent;
-import com.smartgwt.client.widgets.form.validator.IsFloatValidator;
-import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
 
 import com.smartgwt.client.widgets.tab.Tab;
 import com.smartgwt.client.widgets.tab.TabSet;
-import com.smartgwt.client.widgets.Img;
-
-import de.intevation.flys.client.client.FLYSConstants;
-import de.intevation.flys.client.client.ui.AbstractUIProvider;
 
 import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYSConstants;
+
+import de.intevation.flys.client.client.services.FixingsOverviewService;
+import de.intevation.flys.client.client.services.FixingsOverviewServiceAsync;
+
+import de.intevation.flys.client.client.ui.AbstractUIProvider;
 
 import de.intevation.flys.client.shared.model.Data;
 import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.FixAnalysisArtifact;
 import de.intevation.flys.client.shared.model.FixFilter;
 import de.intevation.flys.client.shared.model.FixingsOverviewInfo;
-import de.intevation.flys.client.shared.model.FixAnalysisArtifact;
 
-import de.intevation.flys.client.client.services.FixingsOverviewService;
-import de.intevation.flys.client.client.services.FixingsOverviewServiceAsync;
+import java.util.Date;
+import java.util.HashMap;
 
 
 /**
@@ -66,7 +74,7 @@
     protected FixingsOverviewServiceAsync overviewService =
         GWT.create(FixingsOverviewService.class);
 
-    protected String   htmlOverview;
+    protected String htmlOverview;
     protected FixingsOverviewInfo fixInfo;
     protected TabSet tabs;
     protected Tab events;
@@ -83,6 +91,8 @@
         htmlOverview = "";
     }
 
+    
+    /** Get the (master) artifact UUID. */
     protected String getArtifactUuid() {
         return this.artifact.getUuid();
     }
@@ -156,12 +166,19 @@
                     FixAnalysisArtifact art = (FixAnalysisArtifact)artifact;
                     FixFilter filter = art.getFilter();
                     filter.setRiver(info.getRiver());
-                    if (filter.getCurrentKm() == -Double.MAX_VALUE) {
+                    if (filter.getCurrentKm() == -Double.MAX_VALUE ||
+                        filter.getCurrentKm() == -1d) {
                         filter.setCurrentKm(info.getFrom());
                         filter.setToKm(info.getTo());
                     }
                     if (kmText != null) {
-                        kmText.setValue(filter.getCurrentKm());
+                        NumberFormat nf = NumberFormat.getDecimalFormat();
+                        try {
+                            double d = Double.valueOf(filter.getCurrentKm());
+                            kmText.setValue(nf.format(d));
+                        } catch (NumberFormatException e) {
+                            kmText.setValue(filter.getCurrentKm());
+                        }
                     }
                     eventPane.setContents(htmlOverview);
                     updateChartTab(fixInfo.getFrom());
@@ -186,33 +203,43 @@
         kmText = new TextItem();
         kmText.setWidth(60);
         kmText.setShowTitle(false);
-        kmText.setValidators(new IsFloatValidator());
+
 
         form.setFields(kmText);
         form.setWidth(60);
         lower.addClickHandler(new ClickHandler() {
             public void onClick(ClickEvent ce) {
                 FixFilter filter = updateChartTabLow();
-                FixAnalysisArtifact art = (FixAnalysisArtifact) artifact;
-                kmText.setValue(filter.getCurrentKm());
+                NumberFormat nf = NumberFormat.getDecimalFormat();
+                try {
+                    double d = Double.valueOf(filter.getCurrentKm());
+                    kmText.setValue(nf.format(d));
+                } catch (NumberFormatException e) {
+                    kmText.setValue(filter.getCurrentKm());
+                }
             }
         });
 
         upper.addClickHandler(new ClickHandler() {
             public void onClick(ClickEvent ce) {
                 FixFilter filter = updateChartTabUp();
-                FixAnalysisArtifact art = (FixAnalysisArtifact) artifact;
-                kmText.setValue(filter.getCurrentKm());
+                NumberFormat nf = NumberFormat.getDecimalFormat();
+                try {
+                    double d = Double.valueOf(filter.getCurrentKm());
+                    kmText.setValue(nf.format(d));
+                } catch (NumberFormatException e) {
+                    kmText.setValue(filter.getCurrentKm());
+                }
             }
         });
 
         kmText.addChangedHandler(new ChangedHandler() {
             public void onChanged(ChangedEvent ce) {
                 //TODO: get current value.
-                if(ce.getForm().validate() && ce.getItem().getValue() != null) {
+                if(ce.getItem().getValue() != null) {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
                     try {
-                        double d = Double.parseDouble(
-                            ce.getItem().getValue().toString());
+                        double d = nf.parse(ce.getItem().getValue().toString());
                         updateChartTab(d);
                     }
                     catch(NumberFormatException nfe) {
@@ -452,3 +479,4 @@
         return root;
     }
 }
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/FloodMap.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/FloodMap.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,6 +1,7 @@
 package de.intevation.flys.client.client.ui.map;
 
 import org.gwtopenmaps.openlayers.client.Bounds;
+import org.gwtopenmaps.openlayers.client.LonLat;
 import org.gwtopenmaps.openlayers.client.Map;
 import org.gwtopenmaps.openlayers.client.MapOptions;
 import org.gwtopenmaps.openlayers.client.MapWidget;
@@ -8,7 +9,6 @@
 import org.gwtopenmaps.openlayers.client.control.ScaleLine;
 import org.gwtopenmaps.openlayers.client.control.ScaleLineOptions;
 import org.gwtopenmaps.openlayers.client.event.VectorFeatureAddedListener;
-import org.gwtopenmaps.openlayers.client.event.VectorFeatureAddedListener.FeatureAddedEvent;
 import org.gwtopenmaps.openlayers.client.feature.VectorFeature;
 import org.gwtopenmaps.openlayers.client.format.GeoJSON;
 import org.gwtopenmaps.openlayers.client.layer.Layer;
@@ -17,7 +17,6 @@
 import org.gwtopenmaps.openlayers.client.util.Attributes;
 import org.gwtopenmaps.openlayers.client.util.JObjectArray;
 import org.gwtopenmaps.openlayers.client.util.JSObject;
-import org.gwtopenmaps.openlayers.client.LonLat;
 
 
 public class FloodMap implements VectorFeatureAddedListener {
@@ -38,7 +37,12 @@
     public FloodMap(String srid, Bounds maxExtent) {
         this.srid      = srid;
         this.maxExtent = maxExtent;
+        recreateWidget("100%", "99px");
+        getBarrierLayer();
+    }
 
+
+    public void recreateWidget(String width, String height) {
         MapOptions opts = new MapOptions();
         opts.setControls(new JObjectArray(new JSObject[] {}));
         opts.setNumZoomLevels(16);
@@ -47,10 +51,8 @@
         opts.setUnits("m");
         opts.setMaxResolution(500); // TODO DO THIS ON THE FLY
 
-        mapWidget = new MapWidget("510px", "635px", opts);
+        mapWidget = new MapWidget(width, height, opts);
         map       = mapWidget.getMap();
-
-        getBarrierLayer();
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/GetFeatureInfoWindow.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/GetFeatureInfoWindow.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,24 +1,22 @@
 package de.intevation.flys.client.client.ui.map;
 
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.shared.model.FeatureInfo;
+
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import com.google.gwt.core.client.GWT;
-
-import com.smartgwt.client.widgets.Label;
-import com.smartgwt.client.widgets.Window;
-import com.smartgwt.client.widgets.layout.HLayout;
-import com.smartgwt.client.widgets.layout.VLayout;
-
 import org.gwtopenmaps.openlayers.client.feature.VectorFeature;
 import org.gwtopenmaps.openlayers.client.util.Attributes;
 import org.gwtopenmaps.openlayers.client.util.JSObject;
 
-import de.intevation.flys.client.shared.model.FeatureInfo;
-
-import de.intevation.flys.client.client.FLYSConstants;
-
 
 public class GetFeatureInfoWindow extends Window {
 
@@ -50,8 +48,8 @@
 
         addItem(root);
 
-        setWidth(400);
-        setHeight(50 + rows * ROW_HEIGHT);
+        setWidth(500);
+        setHeight(500); // + rows * ROW_HEIGHT);
         setTitle(MSG.getFeatureInfoWindowTitle());
 
         setIsModal(true);
@@ -75,7 +73,7 @@
         Map<String, String> attrs = feature.getAttrs();
         Set<Map.Entry<String, String>> entries = attrs.entrySet();
 
-        for (Map.Entry entry: entries) {
+        for (Map.Entry<String, String> entry: entries) {
             Label attr = new Label(entry.getKey() + ": " + entry.getValue());
             attr.setHeight(ROW_HEIGHT);
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/MapOutputTab.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/MapOutputTab.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,7 +2,6 @@
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.HorizontalPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.smartgwt.client.util.SC;
 import com.smartgwt.client.widgets.Canvas;
@@ -86,6 +85,7 @@
     protected ThemePanel themePanel;
     protected Canvas     themePanelCanvas;
     protected Widget     mapPanel;
+    protected Canvas mapPanelCanvas;
 
     protected FloodMap floodMap;
 
@@ -139,21 +139,16 @@
         rootLayout.setMembersMargin(2);
 
         final HLayout hlayout = new HLayout();
-        hlayout.setHeight("*");
-        hlayout.setWidth100();
         hlayout.setMembersMargin(2);
 
         this.themePanelCanvas = createThemePanel();
 
         controlPanel = createControlPanel();
-        mapPanel     = floodMap.getMapWidget();
-        final HorizontalPanel layout = new HorizontalPanel();
-        layout.setWidth("99%");
-        layout.setHeight("99%");
-        layout.add(mapPanel);
-
+        //mapPanel     = new Image();
+        //((Image)mapPanel).setUrl("http://www.hedweb.com/animimag/cool-pony.jpg");
+        mapPanel = floodMap.getMapWidget();
         hlayout.addMember(themePanelCanvas);
-        hlayout.addMember(layout);
+        hlayout.addMember(mapPanel);
 
         rootLayout.addMember(controlPanel);
         rootLayout.addMember(hlayout);
@@ -161,8 +156,9 @@
         hlayout.addResizedHandler(new ResizedHandler() {
             @Override
             public void onResized(ResizedEvent e) {
-                Integer height = hlayout.getHeight();
-                Integer width  = hlayout.getWidth() - themePanelCanvas.getWidth();
+                int height = hlayout.getHeight();
+                int width  = hlayout.getWidth() -
+                        (themePanelCanvas.isVisible() ? themePanelCanvas.getWidth() : 0);
 
                 height = height * 99 / 100;
                 width  = width  * 99 / 100;
@@ -170,7 +166,7 @@
                 String w = String.valueOf(width) + "px";
                 String h = String.valueOf(height) + "px";
 
-                floodMap.setSize(w, h);
+                mapPanel.setSize(w, h);
             }
         });
 
@@ -568,6 +564,8 @@
 
     public void toogleThemePanel() {
         this.themePanelCanvas.setVisible(!themePanelCanvas.isVisible());
+        this.themePanelCanvas.setSize(themePanelCanvas.getWidthAsString(),
+                                      themePanelCanvas.getHeightAsString());
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/MapPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/MapPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,15 +1,14 @@
 package de.intevation.flys.client.client.ui.map;
 
 import com.google.gwt.user.client.ui.HorizontalPanel;
-
 import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.layout.VLayout;
 
-import org.gwtopenmaps.openlayers.client.Bounds;
-
 import de.intevation.flys.client.shared.model.BBox;
 import de.intevation.flys.client.shared.model.MapInfo;
 
+import org.gwtopenmaps.openlayers.client.Bounds;
+
 
 public class MapPanel extends VLayout {
 
@@ -55,7 +54,7 @@
         toolbar = new MapToolbar(floodMap, digitizeEnabled);
 
         addMember(toolbar);
-        addMember(mapArea);
+        addMember(wrapper);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/WMSLayersTree.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/map/WMSLayersTree.java	Fri Sep 28 12:15:40 2012 +0200
@@ -106,7 +106,7 @@
             }
         }
 
-        return (TreeNode[]) layerNodes.toArray(new TreeNode[layerNodes.size()]);
+        return layerNodes.toArray(new TreeNode[layerNodes.size()]);
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/BedCampaignChart.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,78 @@
+package de.intevation.flys.client.client.ui.minfo;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.json.client.JSONNumber;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.shared.model.Artifact;
+
+public class BedCampaignChart extends VLayout {
+
+    private final Artifact artifact;
+
+    protected Img chartImg;
+
+    public BedCampaignChart(Artifact artifact, ResizedHandler resizeHandler) {
+        super();
+
+        this.artifact = artifact;
+        this.chartImg = new Img();
+
+        addResizedHandler(resizeHandler);
+        setAlign(Alignment.CENTER);
+    }
+
+    public void update() {
+        Config config = Config.getInstance();
+        String locale = config.getLocale();
+
+        int hWidth = getWidth() - 12;
+        int hHeight = getHeight() - 12;
+
+        if ((int) (hHeight * 4f / 3) < hWidth) {
+            hWidth = (int) (hHeight * 4f / 3);
+        }
+        else {
+            hHeight = (int) (hWidth * 3f / 4);
+        }
+
+        String river = artifact.getArtifactDescription().getRiver();
+
+        JSONObject jfix = new JSONObject();
+        JSONObject jfilter = new JSONObject();
+        JSONObject jrName = new JSONObject();
+        JSONString jrValue = new JSONString(river);
+        JSONObject jextent = new JSONObject();
+        JSONNumber jwidth = new JSONNumber(hWidth);
+        JSONNumber jheight = new JSONNumber(hHeight);
+
+        jrName.put("name", jrValue);
+        jfilter.put("river", jrName);
+        jextent.put("width", jwidth);
+        jextent.put("height", jheight);
+        jfilter.put("extent", jextent);
+        jfix.put("bed", jfilter);
+        String filter = jfix.toString();
+
+        String imgUrl = GWT.getModuleBaseURL();
+        imgUrl += "bed-km-chart";
+        imgUrl += "?locale=" + locale;
+        imgUrl += "&filter=" + filter;
+
+        if (chartImg != null && hasMember(chartImg)) {
+            chartImg.setWidth(hWidth);
+            chartImg.setHeight(hHeight);
+            chartImg.setSrc(imgUrl);
+        }
+        else {
+            chartImg = new Img(imgUrl, hWidth, hHeight);
+            addMember(chartImg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/BedHeightsDatacagePanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,310 @@
+package de.intevation.flys.client.client.ui.minfo;
+
+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.events.ClickEvent;
+
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYSConstants;
+
+import de.intevation.flys.client.client.event.StepForwardEvent;
+
+import de.intevation.flys.client.client.services.LoadArtifactService;
+import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
+import de.intevation.flys.client.client.services.RemoveArtifactService;
+import de.intevation.flys.client.client.services.RemoveArtifactServiceAsync;
+
+import de.intevation.flys.client.client.ui.DatacagePairWidget;
+import de.intevation.flys.client.client.ui.DatacageTwinPanel;
+import de.intevation.flys.client.client.ui.RecommendationPairRecord;
+
+import de.intevation.flys.client.shared.model.Artifact;
+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.Recommendation.Facet;
+import de.intevation.flys.client.shared.model.Recommendation.Filter;
+
+import de.intevation.flys.client.shared.model.Recommendation;
+import de.intevation.flys.client.shared.model.User;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+// TODO Probably better to branch off AbstractUIProvider.
+// TODO Merge with other datacage-widget impls.
+/**
+ * Panel containing a Grid and a "next" button. The Grid is fed by a
+ * DatacagePairWidget which is put in the input-helper area.
+ */
+public class BedHeightsDatacagePanel
+extends      DatacageTwinPanel {
+
+    protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    /**
+     * List to track previously selected but now removed pairs. (Needed to
+     * be able to identify artifacts that can be removed from the collection.
+     */
+    protected List<RecommendationPairRecord> removedPairs =
+        new ArrayList<RecommendationPairRecord>();
+
+    /** Service handle to clone and add artifacts to collection. */
+    LoadArtifactServiceAsync loadArtifactService = GWT.create(
+            de.intevation.flys.client.client.services.LoadArtifactService.class);
+
+    /** Service to remove artifacts from collection. */
+    RemoveArtifactServiceAsync removeArtifactService = GWT.create(
+            de.intevation.flys.client.client.services.RemoveArtifactService.class);
+
+
+    public BedHeightsDatacagePanel(User user) {
+        super(user);
+    }
+
+
+    /**
+     * Create a recommendation from a string representation of it.
+     * @TODO describe format of input string
+     * @param from string in format as shown above.
+     * @return recommendation from input string.
+     */
+    public Recommendation createRecommendationFromString(String from) {
+        // TODO Construct "real" filter.
+        String[] parts = unbracket(from).split(";");
+        Recommendation.Filter filter = new Recommendation.Filter();
+        Recommendation.Facet  facet  = new Recommendation.Facet(
+                parts[1],
+                parts[2]);
+
+        List<Recommendation.Facet> facets = new ArrayList<Recommendation.Facet>
+            ();
+        facets.add(facet);
+        filter.add("longitudinal_section", facets);
+        Recommendation r = new Recommendation("bedheight", parts[0],
+            this.artifact.getUuid(), filter);
+        r.setDisplayName(parts[3]);
+        return r;
+    }
+
+
+    /**
+     * Creates the graphical representation and interaction widgets for the data.
+     * @param dataList the data.
+     * @return graphical representation and interaction widgets for data.
+     */
+    @Override
+    public Canvas create(DataList dataList) {
+        GWT.log("createData()");
+
+        Data       data  = dataList.get(0);
+        DataItem[] items = data.getItems();
+
+        String value = items[0].getStringValue();
+
+        String filter = "minfo-heights";
+        if (value.equals("epoch")) {
+            filter = "minfo-heights-epoch";
+        }
+        Canvas widget = createWidget();
+        Canvas submit = getNextButton();
+
+        VLayout layout       = new VLayout();
+        HLayout helperLayout = new HLayout();
+        helperLayout.addMember(new DatacagePairWidget(this.artifact,
+            user, filter, differencesList));
+
+        layout.addMember(widget);
+        layout.addMember(submit);
+        layout.setMembersMargin(10);
+        this.helperContainer.addMember(helperLayout);
+
+        this.dataName = "diffids";
+
+        return layout;
+    }
+
+
+    /**
+     * Add record to list of removed records.
+     */
+    public void trackRemoved(Record r) {
+        RecommendationPairRecord pr = (RecommendationPairRecord) r;
+        this.removedPairs.add(pr);
+    }
+
+
+    /**
+     * Validates data, does nothing if invalid, otherwise clones new selected
+     * waterlevels and add them to collection, forward the artifact.
+     */
+    @Override
+    public void onClick(ClickEvent e) {
+        GWT.log("DatacageTwinPanel.onClick");
+
+        List<String> errors = validate();
+        if (errors != null && !errors.isEmpty()) {
+            showErrors(errors);
+            return;
+        }
+
+        Config config = Config.getInstance();
+        String locale = config.getLocale();
+
+        ListGridRecord[] records = differencesList.getRecords();
+
+        List<Recommendation> ar  = new ArrayList<Recommendation>();
+        List<Recommendation> all = new ArrayList<Recommendation>();
+
+        for (ListGridRecord record : records) {
+            RecommendationPairRecord r =
+                (RecommendationPairRecord) record;
+            // Do not add "old" recommendations.
+            if (!r.isAlreadyLoaded()) {
+                // Check whether one of those is a dike or similar.
+                // TODO differentiate and merge: new clones, new, old.
+                Recommendation firstR = r.getFirst();
+                if(firstR.getIDs() != null) {
+                    GWT.log("First IDs: " + firstR.getIDs() + " factory: "
+                            + firstR.getFactory());
+                }
+                firstR.setFactory("bedheight");
+                Recommendation secondR = r.getSecond();
+                if(secondR.getIDs() != null) {
+                    GWT.log("Second IDs: " + secondR.getIDs() + " factory: "
+                            + secondR.getFactory());
+                }
+                secondR.setFactory("bedheight");
+
+                ar.add(firstR);
+                ar.add(secondR);
+            }
+            else {
+                all.add(r.getFirst());
+                all.add(r.getSecond());
+            }
+        }
+
+        final Recommendation[] toClone = ar.toArray(new Recommendation[ar.size()]);
+        final Recommendation[] toUse   = all.toArray(new Recommendation[all.size()]);
+
+        // Find out whether "old" artifacts have to be removed.
+        List<String> artifactIdsToRemove = new ArrayList<String>();
+        for (RecommendationPairRecord rp: this.removedPairs) {
+            Recommendation first  = rp.getFirst();
+            Recommendation second = rp.getSecond();
+
+            for (Recommendation recommendation: toUse) {
+                if (first != null && first.getIDs().equals(recommendation.getIDs())) {
+                    first = null;
+                }
+                if (second != null && second.getIDs().equals(recommendation.getIDs())) {
+                    second = null;
+                }
+
+                if (first == null && second == null) {
+                    break;
+                }
+            }
+            if (first != null) {
+                artifactIdsToRemove.add(first.getIDs());
+            }
+            if (second != null) {
+                artifactIdsToRemove.add(second.getIDs());
+            }
+        }
+
+        // Remove old artifacts, if any. Do this asychronously without much
+        // feedback.
+        for(final String uuid: artifactIdsToRemove) {
+            removeArtifactService.remove(this.collection,
+                uuid,
+                locale,
+                new AsyncCallback<Collection>() {
+                    public void onFailure(Throwable caught) {
+                        GWT.log("RemoveArtifact (" + uuid + ") failed.");
+                    }
+                    public void onSuccess(Collection collection) {
+                        GWT.log("RemoveArtifact succeeded");
+                    }
+                });
+        }
+
+        // Clone new ones (and spawn statics), go forward.
+        loadArtifactService.loadMany(
+            this.collection,
+            toClone,
+            //"staticwkms" and "waterlevel"
+            null,
+            locale,
+            new AsyncCallback<Artifact[]>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Failure of cloning with factories!");
+                }
+                public void onSuccess(Artifact[] artifacts) {
+                    GWT.log("Successfully cloned " + toClone.length +
+                        " with factories.");
+
+                    fireStepForwardEvent(new StepForwardEvent(
+                        getData(toClone, artifacts, toUse)));
+                }
+            });
+    }
+
+
+    /**
+     * Creates part of the String that encodes minuend or subtrahend.
+     * @param artifact Artifacts UUID.
+     * @param recommendation Recommendation to wrap in string.
+     */
+    protected String createDataString(
+        String artifact,
+        Recommendation recommendation)
+    {
+        Filter filter = recommendation.getFilter();
+        Facet  f      = null;
+
+        if(filter != null) {
+            Map<String, List<Facet>>               outs = filter.getOuts();
+            Set<Map.Entry<String, List<Facet>>> entries = outs.entrySet();
+
+            for (Map.Entry<String, List<Facet>> entry: entries) {
+                List<Facet> fs = entry.getValue();
+
+                f = fs.get(0);
+                if (f != null) {
+                    break;
+                }
+            }
+
+            return "[" + artifact + ";"
+                + f.getName()
+                + ";"
+                + f.getIndex()
+                + ";"
+                + recommendation.getDisplayName() + "]";
+        }
+        else {
+            return "["
+                + artifact
+                + ";bedheight;0;"
+                + recommendation.getDisplayName() + "]";
+        }
+    }
+}
+// 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/minfo/BedMultiPeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,34 @@
+package de.intevation.flys.client.client.ui.minfo;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.events.ResizedEvent;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.ui.MultiPeriodPanel;
+
+public class BedMultiPeriodPanel
+extends MultiPeriodPanel
+implements ResizedHandler {
+    protected BedCampaignChart chartContainer1;
+    protected BedloadCampaignChart chartContainer2;
+
+    public BedMultiPeriodPanel() {
+    }
+
+    @Override
+    protected Canvas createHelper() {
+        chartContainer1 = new BedCampaignChart(artifact, this);
+        chartContainer2 = new BedloadCampaignChart(artifact, this);
+        VLayout layout = new VLayout();
+        layout.addMember(chartContainer1);
+        layout.addMember(chartContainer2);
+        return layout;
+    }
+
+    @Override
+    public void onResized(ResizedEvent re) {
+        chartContainer1.update();
+        chartContainer2.update();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/BedloadCampaignChart.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,78 @@
+package de.intevation.flys.client.client.ui.minfo;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.json.client.JSONNumber;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.shared.model.Artifact;
+
+public class BedloadCampaignChart extends VLayout {
+
+    private final Artifact artifact;
+
+    protected Img chartImg;
+
+    public BedloadCampaignChart(Artifact artifact, ResizedHandler resizeHandler) {
+        super();
+
+        this.artifact = artifact;
+        this.chartImg = new Img();
+
+        addResizedHandler(resizeHandler);
+        setAlign(Alignment.CENTER);
+    }
+
+    public void update() {
+        Config config = Config.getInstance();
+        String locale = config.getLocale();
+
+        int hWidth = getWidth() - 12;
+        int hHeight = getHeight() - 12;
+
+        if ((int) (hHeight * 4f / 3) < hWidth) {
+            hWidth = (int) (hHeight * 4f / 3);
+        }
+        else {
+            hHeight = (int) (hWidth * 3f / 4);
+        }
+
+        String river = artifact.getArtifactDescription().getRiver();
+
+        JSONObject jfix = new JSONObject();
+        JSONObject jfilter = new JSONObject();
+        JSONObject jrName = new JSONObject();
+        JSONString jrValue = new JSONString(river);
+        JSONObject jextent = new JSONObject();
+        JSONNumber jwidth = new JSONNumber(hWidth);
+        JSONNumber jheight = new JSONNumber(hHeight);
+
+        jrName.put("name", jrValue);
+        jfilter.put("river", jrName);
+        jextent.put("width", jwidth);
+        jextent.put("height", jheight);
+        jfilter.put("extent", jextent);
+        jfix.put("bedload", jfilter);
+        String filter = jfix.toString();
+
+        String imgUrl = GWT.getModuleBaseURL();
+        imgUrl += "bedload-km-chart";
+        imgUrl += "?locale=" + locale;
+        imgUrl += "&filter=" + filter;
+
+        if (chartImg != null && hasMember(chartImg)) {
+            chartImg.setWidth(hWidth);
+            chartImg.setHeight(hHeight);
+            chartImg.setSrc(imgUrl);
+        }
+        else {
+            chartImg = new Img(imgUrl, hWidth, hHeight);
+            addMember(chartImg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/CheckboxPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,117 @@
+package de.intevation.flys.client.client.ui.minfo;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+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.CheckboxItem;
+import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
+import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.ui.AbstractUIProvider;
+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;
+
+public class CheckboxPanel extends AbstractUIProvider {
+
+    private String dataName;
+    HashMap<String, Boolean> values;
+
+    protected DynamicForm form;
+
+    public CheckboxPanel() {
+        super();
+        values = new HashMap<String, Boolean>();
+    }
+
+    @Override
+    public Canvas createOld(DataList dataList) {
+        Data       data  = dataList.get(0);
+        DataItem[] items = data.getItems();
+
+        HLayout layout = new HLayout();
+        Label   label  = new Label(dataList.getLabel());
+        Label   value  = new Label(items[0].getLabel());
+
+        layout.setHeight(35);
+        layout.setWidth(400);
+        label.setWidth(200);
+
+        layout.addMember(label);
+        layout.addMember(value);
+        layout.addMember(getBackButton(dataList.getState()));
+
+        return layout;
+    }
+
+    @Override
+    public Canvas create(DataList dataList) {
+        Data       data  = dataList.get(0);
+        DataItem[] items = data.getItems();
+
+        this.dataName = data.getLabel();
+        form = new DynamicForm();
+
+        VLayout layout = new VLayout();
+        Label   label  = new Label(data.getDescription());
+        LinkedList<CheckboxItem> cbItems = new LinkedList<CheckboxItem>();
+        for (int i = 0; i < items.length; i++) {
+            CheckboxItem item = new CheckboxItem(items[i].getLabel());
+            GWT.log(items[i].getStringValue() + "; " + items[i].getLabel());
+            item.addChangedHandler(new ChangedHandler() {
+                @Override
+                public void onChanged(ChangedEvent event) {
+                    values.put(
+                        event.getItem().getName(),
+                        (Boolean)event.getItem().getValue());
+                }
+            });
+            cbItems.add(item);
+        }
+
+        form.setFields(cbItems.toArray(new CheckboxItem[cbItems.size()]));
+        layout.setMembersMargin(10);
+        layout.setHeight(35);
+        label.setHeight(35);
+
+        layout.addMember(label);
+        layout.addMember(form);
+        layout.addMember(getNextButton());
+        layout.setMembersMargin(10);
+
+        return layout;
+    }
+
+    @Override
+    protected Data[] getData() {
+        String value = "";
+        Set<String> entries = values.keySet();
+        boolean first = true;
+        for (String s: values.keySet()) {
+            if (!first) {
+                value += ";";
+            }
+            if ((Boolean)values.get(s) == true) {
+                value += s;
+            }
+            first = false;
+        }
+        DataItem item = new DefaultDataItem("diameter", "diameter", value);
+
+        return new Data[] {new DefaultData(
+            "diameter",
+            null,
+            null,
+            new DataItem[]{item})};
+    }
+
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/range/LocationsTable.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/range/LocationsTable.java	Fri Sep 28 12:15:40 2012 +0200
@@ -24,7 +24,6 @@
 
 
     public LocationsTable() {
-
         String baseUrl = GWT.getHostPageBaseURL();
 
         setWidth100();
@@ -37,14 +36,14 @@
         setEmptyMessage(MSG.empty_filter());
         setCanReorderFields(false);
 
-        ListGridField addfrom = new ListGridField ("", "");
+        ListGridField addfrom = new ListGridField ("from", MSG.from());
         addfrom.setType(ListGridFieldType.ICON);
-        addfrom.setWidth(20);
+        addfrom.setWidth(30);
         addfrom.setCellIcon(baseUrl + MSG.markerGreen());
 
-        ListGridField addto = new ListGridField("", "");
+        ListGridField addto = new ListGridField("to", MSG.to());
         addto.setType(ListGridFieldType.ICON);
-        addto.setWidth(20);
+        addto.setWidth(30);
         addto.setCellIcon(baseUrl + MSG.markerRed());
 
         ListGridField ldescr = new ListGridField(
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/sq/SQCampaignChart.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,79 @@
+package de.intevation.flys.client.client.ui.sq;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.json.client.JSONNumber;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.shared.model.Artifact;
+
+
+public class SQCampaignChart extends VLayout {
+
+    private final Artifact artifact;
+
+    protected Img chartImg;
+
+    public SQCampaignChart(Artifact artifact, ResizedHandler resizeHandler) {
+        super();
+
+        this.artifact = artifact;
+        this.chartImg = new Img();
+
+        addResizedHandler(resizeHandler);
+        setAlign(Alignment.CENTER);
+    }
+
+    public void update() {
+        Config config = Config.getInstance();
+        String locale = config.getLocale();
+
+        int hWidth = getWidth() - 12;
+        int hHeight = getHeight() - 12;
+
+        if ((int) (hHeight * 4f / 3) < hWidth) {
+            hWidth = (int) (hHeight * 4f / 3);
+        }
+        else {
+            hHeight = (int) (hWidth * 3f / 4);
+        }
+
+        String river = artifact.getArtifactDescription().getRiver();
+
+        JSONObject jfix = new JSONObject();
+        JSONObject jfilter = new JSONObject();
+        JSONObject jrName = new JSONObject();
+        JSONString jrValue = new JSONString(river);
+        JSONObject jextent = new JSONObject();
+        JSONNumber jwidth = new JSONNumber(hWidth);
+        JSONNumber jheight = new JSONNumber(hHeight);
+
+        jrName.put("name", jrValue);
+        jfilter.put("river", jrName);
+        jextent.put("width", jwidth);
+        jextent.put("height", jheight);
+        jfilter.put("extent", jextent);
+        jfix.put("sq", jfilter);
+        String filter = jfix.toString();
+
+        String imgUrl = GWT.getModuleBaseURL();
+        imgUrl += "sq-km-chart";
+        imgUrl += "?locale=" + locale;
+        imgUrl += "&filter=" + filter;
+
+        if (chartImg != null && hasMember(chartImg)) {
+            chartImg.setWidth(hWidth);
+            chartImg.setHeight(hHeight);
+            chartImg.setSrc(imgUrl);
+        }
+        else {
+            chartImg = new Img(imgUrl, hWidth, hHeight);
+            addMember(chartImg);
+        }
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/sq/SQMultiPeriodPanel.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/sq/SQMultiPeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,100 +1,32 @@
 package de.intevation.flys.client.client.ui.sq;
 
-import com.google.gwt.json.client.JSONObject;
-import com.google.gwt.json.client.JSONNumber;
-import com.google.gwt.json.client.JSONString;
-
-import com.google.gwt.core.client.GWT;
-
-import com.smartgwt.client.types.Alignment;
-
-import com.smartgwt.client.widgets.Img;
 import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.events.ResizedEvent;
 import com.smartgwt.client.widgets.events.ResizedHandler;
-import com.smartgwt.client.widgets.events.ResizedEvent;
 
 import de.intevation.flys.client.client.ui.MultiPeriodPanel;
 
-import de.intevation.flys.client.client.Config;
+
 /**
  * This UIProvider creates helper panel for sq relation.
  *
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
-public class SQMultiPeriodPanel
-extends      MultiPeriodPanel
-implements   ResizedHandler
-{
-    protected VLayout chartContainer;
-
-    protected Img chartImg;
+public class SQMultiPeriodPanel extends MultiPeriodPanel implements
+    ResizedHandler {
+    protected SQCampaignChart chartContainer;
 
     public SQMultiPeriodPanel() {
-        chartImg = new Img();
     }
 
-
+    @Override
     protected Canvas createHelper() {
-        Config config    = Config.getInstance();
-        String locale    = config.getLocale ();
-
-        chartContainer = new VLayout();
-        chartContainer.addResizedHandler(this);
-        chartContainer.setAlign(Alignment.CENTER);
-
+        chartContainer = new SQCampaignChart(artifact, this);
         return chartContainer;
     }
 
-
-    protected void updateChart() {
-        Config config    = Config.getInstance();
-        String locale    = config.getLocale ();
-
-        int hWidth = chartContainer.getWidth() - 12;
-        int hHeight = chartContainer.getHeight() - 12;
-
-        if ((int)(hHeight *4f/3) < hWidth) {
-            hWidth = (int)(hHeight * 4f/3);
-        }
-        else {
-            hHeight = (int)(hWidth *3f/4);
-        }
-        String river = artifact.getArtifactDescription().getRiver();
-
-        JSONObject jfix = new JSONObject();
-        JSONObject jfilter = new JSONObject();
-        JSONObject jrName = new JSONObject();
-        JSONString jrValue = new JSONString(river);
-        JSONObject jextent = new JSONObject();
-        JSONNumber jwidth = new JSONNumber(hWidth);
-        JSONNumber jheight = new JSONNumber(hHeight);
-
-        jrName.put("name", jrValue);
-        jfilter.put("river", jrName);
-        jextent.put("width", jwidth);
-        jextent.put("height", jheight);
-        jfilter.put("extent", jextent);
-        jfix.put("sq", jfilter);
-        String filter = jfix.toString();
-
-        String imgUrl = GWT.getModuleBaseURL();
-        imgUrl += "sq-km-chart";
-        imgUrl += "?locale=" + locale;
-        imgUrl += "&filter=" + filter;
-        if (chartContainer.hasMember(chartImg)) {
-            chartImg.setWidth(hWidth);
-            chartImg.setHeight(hHeight);
-            chartImg.setSrc(imgUrl);
-        }
-        else {
-            chartImg = new Img(imgUrl, hWidth, hHeight);
-            chartContainer.addMember(chartImg);
-        }
-    }
-
-
+    @Override
     public void onResized(ResizedEvent re) {
-        updateChart();
+        chartContainer.update();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/sq/SQPeriodPanel.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,26 @@
+package de.intevation.flys.client.client.ui.sq;
+
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.events.ResizedEvent;
+import com.smartgwt.client.widgets.events.ResizedHandler;
+
+import de.intevation.flys.client.client.ui.PeriodPanel;
+
+public class SQPeriodPanel extends PeriodPanel implements ResizedHandler {
+
+    private SQCampaignChart chartLayout;
+
+    @Override
+    protected Canvas createHelper() {
+        GWT.log("Create new SQCampaignChart as Helper Widget");
+        chartLayout = new SQCampaignChart(artifact, this);
+        return chartLayout;
+    }
+
+
+    @Override
+    public void onResized(ResizedEvent re) {
+        chartLayout.update();
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/wq/QDTable.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/wq/QDTable.java	Fri Sep 28 12:15:40 2012 +0200
@@ -36,16 +36,21 @@
         setShowRecordComponentsByCell(true);
         setEmptyMessage(MESSAGE.empty_table());
 
-        ListGridField addMax = new ListGridField("max", "");
+        ListGridField addMax = new ListGridField("max", MESSAGE.from());
         addMax.setType(ListGridFieldType.ICON);
         addMax.setWidth(30);
         addMax.setCellIcon(baseUrl + MESSAGE.markerRed());
 
-        ListGridField addMin = new ListGridField("min", "");
+        ListGridField addMin = new ListGridField("min", MESSAGE.to());
         addMin.setType(ListGridFieldType.ICON);
         addMin.setWidth(30);
         addMin.setCellIcon(baseUrl + MESSAGE.markerGreen());
 
+        ListGridField select = new ListGridField("select", MESSAGE.selection());
+        select.setType(ListGridFieldType.ICON);
+        select.setWidth(70);
+        select.setCellIcon(baseUrl + MESSAGE.markerGreen());
+
         ListGridField name = new ListGridField("name", MESSAGE.discharge());
         name.setType(ListGridFieldType.TEXT);
         name.setWidth("*");
@@ -76,12 +81,13 @@
         });
         value.setWidth("20%");
 
-        setFields(addMax, addMin, name, type, value);
+        setFields(addMax, addMin, select, name, type, value);
     }
 
     public void hideIconFields () {
         hideField("max");
         hideField("min");
+        hideField("select");
         lockClick = true;
     }
 
@@ -89,9 +95,16 @@
     public void showIconFields() {
         showField("max");
         showField("min");
+        hideField("select");
         lockClick = false;
     }
 
+    public void showSelect() {
+        showField("select");
+        hideField("max");
+        hideField("min");
+    }
+
     public boolean isLocked() {
         return lockClick;
     }
--- a/flys-client/src/main/java/de/intevation/flys/client/client/utils/DoubleValidator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/utils/DoubleValidator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -43,8 +43,10 @@
 
     }
 
+
     /**
-     *
+     * @return true if items value can be converted to double, if false,
+     *         expect error message in \param errors map.
      */
     public boolean validate(FormItem item, Map errors) {
         boolean valid = true;
@@ -75,4 +77,5 @@
         return valid;
     }
 }
+// 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/widgets/KMSpinner.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,176 @@
+package de.intevation.flys.client.client.widgets;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
+
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.widgets.Button;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.FormItemValueFormatter;
+import com.smartgwt.client.widgets.form.FormItemValueParser;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
+import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
+import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
+import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import de.intevation.flys.client.shared.model.FacetRecord;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SpinnerItem-like element with text label and up/down buttons.
+ */
+public class KMSpinner extends HLayout {
+    protected List<KMSpinnerChangeListener> listeners = new ArrayList<KMSpinnerChangeListener>();
+
+    protected Label label;
+    protected FacetRecord facetRecord;
+    protected double value;
+
+    public KMSpinner(double initialValue, FacetRecord facetRecord) {
+        super(2);
+        this.facetRecord = facetRecord;
+        this.value = initialValue;
+
+        setWidth("99%");
+        setHeight(18);
+
+        // minusButton shall ask service for previous available cs.
+        Button minusButton = new Button("-");
+        minusButton.setWidth(18);
+        minusButton.setHeight(18);
+        minusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+            public void onClick(ClickEvent evt) {
+                fireChangedEvent(value - 0.1d, false);
+            }
+        });
+
+        DynamicForm form = new DynamicForm();
+        final TextItem kmField = new TextItem();
+        kmField.setValue(initialValue);
+        kmField.setWidth("*");
+        kmField.setTitle("");
+        kmField.setHeight(16);
+
+        FormItemValueFormatter doubleFormat = new FormItemValueFormatter() {
+            public String formatValue(Object value, Record record, DynamicForm form, FormItem item) {
+                if (value != null) {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
+                    try {
+                        double d = Double.valueOf(value.toString()).doubleValue();
+                        return nf.format(d);
+                    }
+                    catch (Exception e) {
+                        GWT.log("EditorValueFormatter exception: " + e.toString());
+
+                        // Remove junk chars from input string
+                        return doublefyString(value.toString());
+                    }
+                }
+                else {
+                    return null;
+                }
+            }
+        };
+        kmField.setEditorValueFormatter(doubleFormat);
+
+        FormItemValueParser doubleParser = new FormItemValueParser() {
+            public Object parseValue(String value, DynamicForm form, FormItem item) {
+                if (value == null)
+                    return null;
+                try {
+                    NumberFormat nf = NumberFormat.getDecimalFormat();
+                    double d = nf.parse(value.toString());
+                    return Double.toString(d);
+                }
+                catch(NumberFormatException nfe) {
+                    return value;
+                }
+            }
+        };
+        kmField.setEditorValueParser(doubleParser);
+
+        // Update on focus lost and enter-pressed.
+        kmField.addBlurHandler(new BlurHandler() {
+            @Override
+            public void onBlur(BlurEvent be) {
+                if (kmField.getValue() != null) {
+                    try {
+                        fireChangedEvent(Double.parseDouble(kmField.getValue().toString()), true);
+                    }
+                    catch(NumberFormatException nfe) {
+                        GWT.log("entered string cannot be parsed to double.");
+                    }
+                }
+            }
+        });
+        kmField.addKeyPressHandler(new KeyPressHandler() {
+            @Override
+            public void onKeyPress(KeyPressEvent kpe) {
+                if (kpe.getKeyName().equals("Enter")) {
+                    kmField.blurItem();
+                }
+            }
+        });
+
+        // TODO: i18n Now add all the validators, formatters, editors/parsers  etc.
+        form.setFields(kmField);
+        form.setTitle("");
+        form.setTitlePrefix("");
+        form.setTitleSuffix("");
+        form.setTitleWidth(0);
+        form.setWidth(50);
+        form.setHeight(18);
+
+        // PlusButton shall ask service for next available cs.
+        Button plusButton = new Button("+");
+        plusButton.setWidth(18);
+        plusButton.setHeight(18);
+        plusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+            public void onClick(ClickEvent evt) {
+                fireChangedEvent(value + 0.1d, true);
+            }
+        });
+
+        this.addMember(minusButton);
+        this.addMember(form);
+        this.addMember(plusButton);
+    }
+
+    public void addChangeListener(KMSpinnerChangeListener listener) {
+        this.listeners.add(listener);
+    }
+
+    protected void fireChangedEvent(double val, boolean up) {
+        for(KMSpinnerChangeListener listener : listeners) {
+            listener.spinnerValueEntered(this, val, facetRecord, up);
+        }
+    }
+
+    /**
+     * Remove junk chars from double string.
+     * This method should work for most locales, but not for
+     * exotic ones that do not use "." or "," as decimal
+     * separator.
+     * @return
+     */
+    protected String doublefyString(String str) {
+        StringBuilder buf = new StringBuilder(str.length());
+
+        for (int n = 0; n < str.length(); n++) {
+            char c = str.charAt(n);
+            if ((c >= '0' && c <= '9') || c == '.' || c == ',') {
+                buf.append(c);
+            }
+        }
+
+        return buf.toString();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/widgets/KMSpinnerChangeListener.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,9 @@
+package de.intevation.flys.client.client.widgets;
+
+import de.intevation.flys.client.client.widgets.KMSpinner;
+
+import de.intevation.flys.client.shared.model.FacetRecord;
+
+public interface KMSpinnerChangeListener {
+    public void spinnerValueEntered(KMSpinner spinner, double km, FacetRecord facetRecord, boolean up);
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/AdvanceServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -31,7 +31,6 @@
 {
     private static final Logger logger = Logger.getLogger(AdvanceService.class);
 
-
     public static final String XPATH_RESULT = "/art:result/text()";
 
     public static final String OPERATION_FAILURE = "FAILED";
@@ -47,7 +46,7 @@
     {
         logger.info("AdvanceServiceImpl.advance");
 
-        String url  = getServletContext().getInitParameter("server-url");
+        String url = getServletContext().getInitParameter("server-url");
 
         Document advance = ClientProtocolUtils.newAdvanceDocument(
             artifact.getUuid(),
--- a/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -278,7 +278,7 @@
             }
         }
 
-        return (DataItem[]) dataItems.toArray(new DataItem[count]);
+        return dataItems.toArray(new DataItem[count]);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactHelper.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactHelper.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,6 +1,7 @@
 package de.intevation.flys.client.server;
 
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 import org.apache.log4j.Logger;
 
@@ -14,13 +15,14 @@
 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.utils.ArtifactNamespaceContext;
+import de.intevation.artifacts.httpclient.utils.XMLUtils;
 
 import de.intevation.flys.client.shared.exceptions.ServerException;
 import de.intevation.flys.client.shared.model.Artifact;
 
 import de.intevation.flys.client.shared.model.Recommendation;
 
-
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
@@ -33,6 +35,11 @@
      * creation.*/
     public static final String ERROR_CREATE_ARTIFACT = "error_create_artifact";
 
+    /**
+     * Name of the factory to generate a GaugeDischargeCurveArtifact
+     */
+    private static final String GAUGE_DISCHARGE_CURVE_ARTIFACT = "gaugedischargecurve";
+
 
     private ArtifactHelper() {
     }
@@ -68,10 +75,58 @@
         Document create = ClientProtocolUtils.newCreateDocument(
             factory, uuid, ids, filter);
 
+        return sendCreate(serverUrl, locale, create);
+
+    }
+
+    /**
+     * Creates a new GaugeDischargeCurverArtifact
+     *
+     * @param river the name of the river
+     * @param reference the reference id of the gauge (official number)
+     */
+    public static Artifact createGaugeDischargeCurveArtifact(
+            String serverUrl,
+            String locale,
+            String river,
+            Long   reference)
+    throws ServerException
+    {
+        Document create = ClientProtocolUtils.newCreateDocument(
+                GAUGE_DISCHARGE_CURVE_ARTIFACT);
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            create,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element root = create.getDocumentElement();
+
+        Element eriver = ec.create("river");
+        ec.addAttr(eriver, "name", river);
+
+        Element egauge = ec.create("gauge");
+        ec.addAttr(egauge, "reference", reference.toString());
+
+        root.appendChild(eriver);
+        root.appendChild(egauge);
+
+        return sendCreate(serverUrl, locale, create);
+    }
+
+    /**
+     * Sends a create document to the artifact server
+     */
+    private static Artifact sendCreate(
+            String   serverUrl,
+            String   locale,
+            Document doc)
+    throws ServerException
+    {
         HttpClient client = new HttpClientImpl(serverUrl, locale);
 
         try {
-            return (Artifact) client.create(create, new FLYSArtifactCreator());
+            return (Artifact) client.create(doc, new FLYSArtifactCreator());
         }
         catch (ConnectionException ce) {
             logger.error(ce, ce);
--- a/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ArtifactServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,7 @@
 import de.intevation.flys.client.shared.model.Artifact;
 import de.intevation.flys.client.client.services.ArtifactService;
 
+import de.intevation.flys.client.shared.model.Collection;
 import de.intevation.flys.client.shared.model.Recommendation;
 
 /**
@@ -48,5 +49,34 @@
 
         return ArtifactHelper.createArtifact(url, locale, factory, recom);
     }
+
+    /**
+     * Create a new GaugeDischageCurveArtifact
+     *
+     * @param river    the river
+     * @param gaugeref reference id of the gauge
+     */
+    public Artifact createGaugeDischargeCurveArtifact(
+            Collection collection,
+            String locale,
+            String river,
+            Long   gaugeref)
+    throws ServerException
+    {
+        logger.info("ArtifactServiceImpl.createGaugeDischargeCurverArtifact");
+        String url  = getServletContext().getInitParameter("server-url");
+
+        Artifact artifact = ArtifactHelper.createGaugeDischargeCurveArtifact(url,
+                locale, river, gaugeref);
+        if (artifact == null) {
+            return null;
+        }
+        logger.info("GaugeDischargeCurveArtifact created successfully");
+
+        CollectionHelper.addArtifact(collection, artifact, url, locale);
+
+        return artifact;
+    }
+
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/server/BaseServlet.java	Fri Sep 28 12:14:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-package de.intevation.flys.client.server;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-
-import org.apache.log4j.Logger;
-
-/** Documentation goes here. */
-public class BaseServlet extends HttpServlet {
-
-    private static Logger logger = Logger.getLogger(BaseServlet.class);
-
-
-    public static final String LOG4J_PROPERTIES = "FLYS_CLIENT_LOG4J_PROPERIES";
-
-
-    @Override
-    public void init()
-    throws ServletException
-    {
-        System.out.println("BaseServlet.init");
-
-        initLogging();
-        initConfigParameters();
-    }
-
-
-    /** Init servlet wide logging. */
-    protected void initLogging() {
-        String log4jProperties = System.getenv(LOG4J_PROPERTIES);
-
-        if (log4jProperties == null || log4jProperties.length() == 0) {
-            String file = getInitParameter("log4j-properties");
-
-            if (file != null && file.length() > 0) {
-                log4jProperties = getServletContext().getRealPath(file);
-            }
-        }
-
-        LoggingConfigurator.init(log4jProperties);
-    }
-
-
-    /** Set Context Attribute (parameter) from config.xml file. */
-    protected void initConfigParameters() {
-        String url = getInitParameter("server-url");
-        logger.debug("Found server url: " + url);
-
-        getServletContext().setAttribute("server-url", 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/server/BaseServletContextListener.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,62 @@
+package de.intevation.flys.client.server;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.client.server.LoggingConfigurator;
+import de.intevation.flys.client.server.features.Features;
+import de.intevation.flys.client.server.features.XMLFileFeatures;
+
+/**
+ * ServletContextListenter to initalize the Features globally for
+ * all Servlets
+ */
+public class BaseServletContextListener implements ServletContextListener {
+
+    public static final String LOG4J_PROPERTIES = "FLYS_CLIENT_LOG4J_PROPERIES";
+
+    public static final Logger logger = Logger.getLogger(BaseServletContextListener.class);
+
+    @Override
+    public void  contextInitialized(ServletContextEvent sce) {
+        ServletContext sc = sce.getServletContext();
+
+        this.initLogging(sc);
+
+        String filename = sc.getInitParameter("features-file");
+
+        logger.debug("Initializing ServletContext");
+        try {
+            XMLFileFeatures features = new XMLFileFeatures(sc.getRealPath(filename));
+            sc.setAttribute(Features.CONTEXT_ATTRIBUTE, features);
+        } catch(IOException e) {
+            logger.error(e);
+        }
+    }
+
+    @Override
+    public void contextDestroyed(ServletContextEvent sce) {
+        //DO NOTHING
+    }
+
+
+    private void initLogging(ServletContext sc) {
+        String log4jProperties = System.getenv(LOG4J_PROPERTIES);
+
+        if (log4jProperties == null || log4jProperties.length() == 0) {
+            String file = sc.getInitParameter("log4j-properties");
+
+            if (file != null && file.length() > 0) {
+                log4jProperties = sc.getRealPath(file);
+            }
+        }
+        System.out.println(log4jProperties);
+
+        LoggingConfigurator.init(log4jProperties);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/BedKMChartServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,106 @@
+package de.intevation.flys.client.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+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.StreamResponseHandler;
+
+public class BedKMChartServiceImpl extends HttpServlet {
+    private static final Logger log =
+        Logger.getLogger(FixingsKMChartServiceImpl.class);
+
+    public static final String SERVICE_NAME = "bed-km-chart";
+
+    public BedKMChartServiceImpl() {
+    }
+
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
+
+        log.info("BedKMChartServiceImpl.doGet");
+
+        String url    = getServletContext().getInitParameter("server-url");
+        String locale = req.getParameter("locale");
+        String filter = req.getParameter("filter");
+
+        if (filter == null || filter.length() == 0) {
+            log.warn("Missing 'filter' parameter.");
+            return;
+        }
+
+        if (locale == null || locale.length() == 0) {
+            locale = "de";
+        }
+
+        Document filterDoc = XMLUtils.jsonToXML(filter);
+
+        if (filterDoc == null) {
+            log.warn("Creating filter document failed.");
+            return;
+        }
+
+        InputStream in;
+
+        try {
+            HttpClient client = new HttpClientImpl(url, locale);
+            in = (InputStream)client.callService(
+                url, // XXX: Why? The URL is passed by construction already.
+                SERVICE_NAME,
+                filterDoc,
+                new StreamResponseHandler());
+        }
+        catch (ConnectionException ce) {
+            log.error(ce);
+            return;
+        }
+
+        resp.setHeader("Content-Type", guessMIMEType(filterDoc));
+
+        try {
+            OutputStream out = resp.getOutputStream();
+
+            byte [] buf = new byte[4096];
+            int i = -1;
+            while ((i = in.read(buf)) >= 0) {
+                out.write(buf, 0, i);
+            }
+            out.flush();
+        }
+        catch (IOException ioe) {
+            log.error(ioe);
+        }
+        finally {
+            try { in.close(); }
+            catch (IOException ioe) { /* ignored */ }
+        }
+    }
+
+    protected static String guessMIMEType(Document document) {
+
+        NodeList formats = document.getElementsByTagName("format");
+
+        String format = "png";
+
+        if (formats.getLength() > 0) {
+            String type = ((Element)formats.item(0)).getAttribute("type");
+            if (type.length() > 0) {
+                format = type;
+            }
+        }
+
+        return "image/" + format;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/BedloadKMChartServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,106 @@
+package de.intevation.flys.client.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+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.StreamResponseHandler;
+
+public class BedloadKMChartServiceImpl extends HttpServlet {
+   private static final Logger log =
+        Logger.getLogger(FixingsKMChartServiceImpl.class);
+
+    public static final String SERVICE_NAME = "bedload-km-chart";
+
+    public BedloadKMChartServiceImpl() {
+    }
+
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
+
+        log.info("BedloadKMChartServiceImpl.doGet");
+
+        String url    = getServletContext().getInitParameter("server-url");
+        String locale = req.getParameter("locale");
+        String filter = req.getParameter("filter");
+
+        if (filter == null || filter.length() == 0) {
+            log.warn("Missing 'filter' parameter.");
+            return;
+        }
+
+        if (locale == null || locale.length() == 0) {
+            locale = "de";
+        }
+
+        Document filterDoc = XMLUtils.jsonToXML(filter);
+
+        if (filterDoc == null) {
+            log.warn("Creating filter document failed.");
+            return;
+        }
+
+        InputStream in;
+
+        try {
+            HttpClient client = new HttpClientImpl(url, locale);
+            in = (InputStream)client.callService(
+                url, // XXX: Why? The URL is passed by construction already.
+                SERVICE_NAME,
+                filterDoc,
+                new StreamResponseHandler());
+        }
+        catch (ConnectionException ce) {
+            log.error(ce);
+            return;
+        }
+
+        resp.setHeader("Content-Type", guessMIMEType(filterDoc));
+
+        try {
+            OutputStream out = resp.getOutputStream();
+
+            byte [] buf = new byte[4096];
+            int i = -1;
+            while ((i = in.read(buf)) >= 0) {
+                out.write(buf, 0, i);
+            }
+            out.flush();
+        }
+        catch (IOException ioe) {
+            log.error(ioe);
+        }
+        finally {
+            try { in.close(); }
+            catch (IOException ioe) { /* ignored */ }
+        }
+    }
+
+    protected static String guessMIMEType(Document document) {
+
+        NodeList formats = document.getElementsByTagName("format");
+
+        String format = "png";
+
+        if (formats.getLength() > 0) {
+            String type = ((Element)formats.item(0)).getAttribute("type");
+            if (type.length() > 0) {
+                format = type;
+            }
+        }
+
+        return "image/" + format;
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/server/CapabilitiesParser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/CapabilitiesParser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -98,7 +98,7 @@
     public static void main(String[] args) {
         logger.info("Do static Capabilities request/parsing.");
 
-        String log4jProperties = System.getenv(BaseServlet.LOG4J_PROPERTIES);
+        String log4jProperties = System.getenv(BaseServletContextListener.LOG4J_PROPERTIES);
         LoggingConfigurator.init(log4jProperties);
 
         try {
--- a/flys-client/src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -238,7 +238,7 @@
             transformer.add(t);
         }
 
-        return (Transform2D[]) transformer.toArray(new Transform2D[num]);
+        return transformer.toArray(new Transform2D[num]);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java	Fri Sep 28 12:15:40 2012 +0200
@@ -607,7 +607,8 @@
 
 
     /**
-     *
+     * From a document, parse the settings for an output and create an
+     * OutputSettings object.
      */
     protected static Settings parseSettings(String outName, Element node) {
         OutputSettings set = new OutputSettings(outName);
@@ -620,7 +621,7 @@
 
         Element settings = (Element)elements.item(0);
 
-        // get the categories
+        // Get the categories
         NodeList catNodes = settings.getChildNodes();
         for (int i = 0; i < catNodes.getLength(); i++) {
             Element catNode = (Element)catNodes.item(i);
@@ -634,7 +635,7 @@
             // iterate through all properties or groups.
             List<Property> props = new ArrayList<Property> ();
             for (int j = 0; j < list.getLength(); j++) {
-                Property p = new PropertySetting();
+                Property p;
                 Element e = (Element)list.item(j);
                 if (e.hasChildNodes() &&
                     e.getFirstChild().getNodeType() != Node.TEXT_NODE) {
@@ -669,7 +670,7 @@
 
 
     /**
-     *
+     * From a property element create a Property object.
      */
     protected static Property parseSetting(Element property){
         NamedNodeMap attrMap = property.getAttributes();
@@ -720,7 +721,7 @@
         Element node,
         boolean outs
     ) {
-        logger.debug("AddArtifactServiceImpl.parseCollectionItem");
+        logger.debug("CollectionHelper.parseCollectionItem");
 
         if (node == null) {
             logger.debug("The node for parsing CollectionItem is null!");
--- a/flys-client/src/main/java/de/intevation/flys/client/server/ExportServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ExportServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -4,6 +4,7 @@
 import java.io.IOException;
 
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 import org.apache.log4j.Logger;
 
@@ -12,6 +13,7 @@
 import javax.servlet.http.HttpServletResponse;
 
 import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.XMLUtils;
 
 import de.intevation.artifacts.httpclient.http.HttpClient;
 import de.intevation.artifacts.httpclient.http.HttpClientImpl;
@@ -37,20 +39,31 @@
         try {
             OutputStream out = resp.getOutputStream();
 
-            String url  = getServletContext().getInitParameter("server-url");
-
-            String uuid      = req.getParameter("uuid");
-            String mode      = req.getParameter("mode");
-            String type      = req.getParameter("type");
-            String locale    = req.getParameter("locale");
-            String fn        = mode + "." + type;
+            String url    = getServletContext().getInitParameter("server-url");
+            String uuid   = req.getParameter("uuid");
+            String mode   = req.getParameter("mode");
+            String type   = req.getParameter("type");
+            String locale = req.getParameter("locale");
+            String km     = req.getParameter("km");
+            String fn     = mode + "." + type;
 
             resp.setHeader("Content-Disposition", "attachment;filename=" + fn);
 
-            logger.debug("Request " + type + " export.");
+            if (logger.isDebugEnabled()) {
+                logger.debug("Request " + type + " export.");
+            }
+
+            Document attr = null;
+            if (km != null && km.length() > 0) {
+                attr = XMLUtils.newDocument();
+                XMLUtils.ElementCreator ec =
+                        new XMLUtils.ElementCreator(attr, null, null);
+                Element e = ec.create("km");
+                e.setTextContent(km);
+                attr.appendChild(e);
+            }
             Document request = ClientProtocolUtils.newOutCollectionDocument(
-                uuid, mode, type);
-
+                uuid, mode, type, attr);
             HttpClient client = new HttpClientImpl(url, locale);
             client.collectionOut(request, uuid, mode, out);
 
--- a/flys-client/src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/FLYSArtifactCreator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -18,12 +18,13 @@
 
 import de.intevation.flys.client.shared.model.Artifact;
 import de.intevation.flys.client.shared.model.CalculationMessage;
+import de.intevation.flys.client.shared.model.ChartArtifact;
 import de.intevation.flys.client.shared.model.DefaultArtifact;
+import de.intevation.flys.client.shared.model.FixAnalysisArtifact;
+import de.intevation.flys.client.shared.model.GaugeDischargeCurveArtifact;
+import de.intevation.flys.client.shared.model.MapArtifact;
 import de.intevation.flys.client.shared.model.MINFOArtifact;
 import de.intevation.flys.client.shared.model.WINFOArtifact;
-import de.intevation.flys.client.shared.model.MapArtifact;
-import de.intevation.flys.client.shared.model.ChartArtifact;
-import de.intevation.flys.client.shared.model.FixAnalysisArtifact;
 
 
 /**
@@ -144,6 +145,10 @@
             logger.debug("+++++ NEW FIXANALYSIS ARTIFACT.");
             return new FixAnalysisArtifact(uuid, hash, background, msg);
         }
+        else if (name.length() > 0 && name.equals("gaugedischargecurve")) {
+            logger.debug("+++++ NEW WINFO ARTIFACT.");
+            return new GaugeDischargeCurveArtifact(uuid, hash, background, msg);
+        }
 
         return new DefaultArtifact(uuid, hash, background, msg);
     }
--- a/flys-client/src/main/java/de/intevation/flys/client/server/FixingsOverviewServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/FixingsOverviewServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -58,8 +58,8 @@
         String  locale,
         String  uuid,
         String  filter,
-        boolean  checkboxes,
-        String   callback
+        boolean checkboxes,
+        String  callback
     )
     throws ServerException
     {
@@ -100,8 +100,8 @@
                 log.debug(XMLUtils.toString(resultDoc));
             }
 
-            FixingsOverviewInfo i =
-                getInfo(resultDoc, uuid, checkboxes, callback);
+            FixingsOverviewInfo i = getInfo(
+                locale, resultDoc, uuid, checkboxes, callback);
             return i;
         }
         catch (ConnectionException ce) {
@@ -112,11 +112,17 @@
 
 
     protected FixingsOverviewInfo getInfo(
+        String   locale,
         Document doc,
         String   uuid,
         boolean  checkboxes,
         String   callback
     ) {
+        // TODO: Find a more general solution.
+        locale = locale == null || locale.toLowerCase().startsWith("de")
+            ? "de"
+            : "en";
+
         InputStream transform = getServletContext()
             .getResourceAsStream(XSL_TRANSFORM);
 
@@ -128,6 +134,7 @@
         String result = null;
         try {
             XSLTransformer xformer = new XSLTransformer();
+            xformer.addParameter("locale", locale);
             xformer.addParameter("project-uuid", uuid);
             xformer.addParameter(
                 "render-checkboxes",
@@ -166,12 +173,12 @@
 
         List<FixEvent> fixEvents = getFixEvents(doc);
         return new FixingsOverviewInfo(
-                rid,
-                river,
-                from,
-                to,
-                fixEvents,
-                result);
+            rid,
+            river,
+            from,
+            to,
+            fixEvents,
+            result);
     }
 
 
--- a/flys-client/src/main/java/de/intevation/flys/client/server/GGInAFilter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/GGInAFilter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,10 +1,12 @@
 package de.intevation.flys.client.server;
 
 import java.io.IOException;
+import java.util.Enumeration;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -19,6 +21,7 @@
 import de.intevation.flys.client.server.auth.AuthenticationException;
 import de.intevation.flys.client.server.auth.AuthenticationFactory;
 import de.intevation.flys.client.server.auth.User;
+import de.intevation.flys.client.server.features.Features;
 
 
 /** ServletFilter used for GGInA authentification and certain authorisation. */
@@ -29,6 +32,11 @@
 
     private boolean deactivate = false;
     private String authmethod;
+    private ServletContext sc;
+
+    public static final String LOGIN_JSP     = "/login.jsp";
+    public static final String LOGIN_SERVLET = "/flys/login";
+    public static final String FLYS_CSS      = "/FLYS.css";
 
 
     /**
@@ -41,8 +49,9 @@
     throws ServletException
     {
         String deactivate = config.getInitParameter("deactivate");
-        this.authmethod = config.getServletContext().getInitParameter(
-                "authentication");
+        this.sc = config.getServletContext();
+        logger.debug("GGInAFilter context " + this.sc.getContextPath());
+        this.authmethod = sc.getInitParameter("authentication");
         if (deactivate != null && deactivate.equalsIgnoreCase("true")) {
             this.deactivate = true;
         }
@@ -69,13 +78,18 @@
         HttpServletRequest sreq = (HttpServletRequest) req;
 
         String requesturi = sreq.getRequestURI();
+        for (Enumeration e = req.getAttributeNames() ; e.hasMoreElements() ;) {
+            logger.debug(e.nextElement());
+        }
 
         logger.debug("Request for: " + requesturi);
 
         // Allow access to login pages
         // TODO Maybe replace with Filter <url-pattern>
-        if (requesturi.equals("/login.jsp") || requesturi.equals("/flys/login")
-                || requesturi.equals("/FLYS.css")) {
+        String path = this.sc.getContextPath();
+        if (requesturi.equals(path + "/login.jsp") ||
+                requesturi.equals(path + "/flys/login")
+                || requesturi.equals(path + "/FLYS.css")) {
             logger.debug("Request for login " + requesturi);
             chain.doFilter(req, resp);
             return;
@@ -120,7 +134,8 @@
 
     private void redirect(ServletResponse resp) throws IOException {
         logger.debug("Redirect to login");
-        ((HttpServletResponse) resp).sendRedirect("/login.jsp");
+        ((HttpServletResponse) resp).sendRedirect(this.sc.getContextPath() +
+            "/login.jsp");
     }
 
 
@@ -133,8 +148,9 @@
 
     private Authentication auth(User user, String encoding)
         throws AuthenticationException, IOException {
+        Features features = (Features)sc.getAttribute(Features.CONTEXT_ATTRIBUTE);
         return AuthenticationFactory.getInstance(this.authmethod).auth(
-                user.getName(), user.getPassword(), encoding);
+                user.getName(), user.getPassword(), encoding, features);
     }
 }
 // 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/GaugeOverviewInfoServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,207 @@
+package de.intevation.flys.client.server;
+
+import java.util.ArrayList;
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+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.GaugeOverviewInfoService;
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.DefaultGaugeInfo;
+import de.intevation.flys.client.shared.model.DefaultRiverInfo;
+import de.intevation.flys.client.shared.model.GaugeInfo;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeOverviewInfoServiceImpl
+extends      RemoteServiceServlet
+implements   GaugeOverviewInfoService
+{
+    private static final Logger logger =
+        Logger.getLogger(GaugeOverviewInfoServiceImpl.class);
+
+    public static final String ERROR_NO_RIVERINFO_FOUND =
+        "error_no_gaugeoverviewinfo_found";
+
+    private static final String XPATH_RIVER = "/art:gauge-info/art:river";
+
+    private static final String XPATH_GAUGES = "/art:gauge-info/art:gauges/art:gauge";
+
+    public RiverInfo getRiverInfo(String river) throws ServerException {
+        logger.info("RiverInfoServiceImpl.getRiverInfo");
+
+        String url = getServletContext().getInitParameter("server-url");
+
+        Document doc = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element riverele = ec.create("river");
+        riverele.setTextContent(river);
+
+        doc.appendChild(riverele);
+
+        HttpClient client = new HttpClientImpl(url);
+
+        try {
+            Document result = client.callService(url, "gaugeoverviewinfo", doc);
+
+            Element riverresp = (Element) XMLUtils.xpath(
+                    result,
+                    XPATH_RIVER,
+                    XPathConstants.NODE,
+                    ArtifactNamespaceContext.INSTANCE);
+
+            String rname = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "name");
+            String rkmup = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "kmup");
+            String rstart = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "start");
+            String rend = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "end");
+            String rwstunit = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "wstunit");
+            String rminq = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "minq");
+            String rmaxq = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "maxq");
+            String rofficial = riverresp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "official");
+
+            logger.debug("River is " + rname);
+
+            boolean kmup = rkmup.equalsIgnoreCase("true");
+
+            NodeList gaugenodes = (NodeList) XMLUtils.xpath(
+                result,
+                XPATH_GAUGES,
+                XPathConstants.NODESET,
+                ArtifactNamespaceContext.INSTANCE);
+
+            int num = gaugenodes == null ? 0 : gaugenodes.getLength();
+
+            ArrayList<GaugeInfo> gauges = new ArrayList<GaugeInfo>(num);
+
+            if (num == 0) {
+                logger.warn("No gauge info found.");
+            }
+            else {
+                logger.debug("Found " + num + " gauges.");
+
+                for (int i = 0; i < num; i++) {
+                    Element gaugeele = (Element)gaugenodes.item(i);
+
+                    String gname = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "name");
+                    String gstart = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "start");
+                    String gend = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "end");
+                    String gdatum = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "datum");
+                    String gaeo = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "aeo");
+                    String gminq = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "minq");
+                    String gminw = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "minw");
+                    String gmaxq = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "maxq");
+                    String gmaxw = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "maxw");
+                    String gstation = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "station");
+                    String gofficial = gaugeele.getAttributeNS(
+                            ArtifactNamespaceContext.NAMESPACE_URI, "official");
+
+                    logger.debug("Found gauge with name " + gname);
+
+                    GaugeInfo gaugeinfo = new DefaultGaugeInfo(
+                            rname,
+                            gname,
+                            kmup,
+                            parseDouble(gstation),
+                            parseDouble(gstart),
+                            parseDouble(gend),
+                            parseDouble(gdatum),
+                            parseDouble(gaeo),
+                            parseDouble(gminq),
+                            parseDouble(gmaxq),
+                            parseDouble(gminw),
+                            parseDouble(gmaxw),
+                            rwstunit,
+                            parseLong(gofficial)
+                            );
+
+                    gauges.add(gaugeinfo);
+                }
+            }
+
+            RiverInfo riverinfo = new DefaultRiverInfo(
+                    rname,
+                    kmup,
+                    parseDouble(rstart),
+                    parseDouble(rend),
+                    rwstunit,
+                    parseDouble(rminq),
+                    parseDouble(rmaxq),
+                    parseLong(rofficial),
+                    gauges);
+
+            logger.debug("Finished RiverInfoService.");
+
+            return riverinfo;
+        }
+        catch (ConnectionException ce) {
+            logger.error(ce, ce);
+        }
+
+        logger.warn("No gauge found");
+        throw new ServerException(ERROR_NO_RIVERINFO_FOUND);
+    }
+
+    /**
+     * Avoids NullPointerException when parsing double value
+     */
+    private Double parseDouble(String value) {
+        if (value == null || value.isEmpty()) {
+            return null;
+        }
+        try {
+            return Double.valueOf(value);
+        }
+        catch(NumberFormatException e) {
+            logger.error(e, e);
+            return null;
+        }
+    }
+
+    private Long parseLong(String value) {
+        if (value == null || value.isEmpty()) {
+            return null;
+        }
+        try {
+            return Long.valueOf(value);
+        }
+        catch(NumberFormatException e) {
+            logger.error(e, e);
+            return null;
+        }
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/server/LoginServlet.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/LoginServlet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,6 +3,7 @@
 import java.io.IOException;
 
 import javax.servlet.ServletException;
+import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -15,25 +16,31 @@
 import de.intevation.flys.client.server.auth.AuthenticationFactory;
 import de.intevation.flys.client.server.auth.User;
 import de.intevation.flys.client.server.auth.UserClient;
+import de.intevation.flys.client.server.features.Features;
 
 public class LoginServlet extends HttpServlet {
 
     private static Logger logger = Logger.getLogger(LoginServlet.class);
 
-    private void redirectFailure(HttpServletResponse resp) throws IOException {
-        resp.sendRedirect("/login.jsp");
+    private void redirectFailure(HttpServletResponse resp, String path)
+        throws IOException {
+        resp.sendRedirect(path + "/login.jsp");
     }
 
-    private void redirectFailure(HttpServletResponse resp, Exception e) throws IOException {
-        this.redirectFailure(resp, e.getMessage());
+    private void redirectFailure(HttpServletResponse resp, String path,
+            Exception e) throws IOException {
+        this.redirectFailure(resp, path, e.getMessage());
     }
 
-    private void redirectFailure(HttpServletResponse resp, String message) throws IOException {
-        resp.sendRedirect("/login.jsp?error=" + message);
+    private void redirectFailure(HttpServletResponse resp, String path,
+            String message) throws IOException {
+        resp.sendRedirect(path + "/login.jsp?error=" + message);
     }
-    private void redirectSuccess(HttpServletResponse resp, String uri) throws IOException {
+
+    private void redirectSuccess(HttpServletResponse resp, String path,
+            String uri) throws IOException {
         if (uri == null) {
-            uri = "/FLYS.html";
+            uri = path + "/FLYS.html";
         }
         resp.sendRedirect(uri);
     }
@@ -42,12 +49,13 @@
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     throws ServletException, IOException {
         logger.debug("Processing get request");
-        this.redirectFailure(resp);
+        this.redirectFailure(resp, req.getContextPath());
     }
 
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
-    throws ServletException, IOException {
+    throws ServletException, IOException
+    {
         String encoding = req.getCharacterEncoding();
         String username = req.getParameter("username");
         String password = req.getParameter("password");
@@ -56,21 +64,25 @@
 
         if (username == null || password == null) {
             logger.debug("No username or password provided");
-            this.redirectFailure(resp);
+            this.redirectFailure(resp, req.getContextPath());
+            return;
         }
+
         try {
             Authentication aresp = this.auth(username, password, encoding);
             if (aresp == null || !aresp.isSuccess()) {
-                logger.debug("Athentication not successful");
-                this.redirectFailure(resp);
+                logger.debug("Authentication not successful");
+                this.redirectFailure(resp, req.getContextPath());
             }
             User user = aresp.getUser();
 
             String url = getServletContext().getInitParameter("server-url");
             UserClient client = new UserClient(url);
             if (!client.userExists(user)) {
+                logger.debug("Creating db user");
                 if (!client.createUser(user)) {
-                    this.redirectFailure(resp, "Could not create new user");
+                    this.redirectFailure(resp, req.getContextPath(),
+                            "Could not create new user");
                 }
             }
 
@@ -79,17 +91,20 @@
 
             String uri = (String)session.getAttribute("requesturi");
 
-            this.redirectSuccess(resp, uri);
+            this.redirectSuccess(resp, req.getContextPath(), uri);
         }
         catch(AuthenticationException e) {
             logger.error(e);
-            this.redirectFailure(resp, e);
+            this.redirectFailure(resp, req.getContextPath(), e);
         }
     }
 
     private Authentication auth(String username, String password, String encoding)
-        throws AuthenticationException, IOException {
-        String auth = this.getServletContext().getInitParameter("authentication");
-        return AuthenticationFactory.getInstance(auth).auth(username, password, encoding);
+        throws AuthenticationException, IOException
+    {
+        ServletContext sc = this.getServletContext();
+        Features features = (Features)sc.getAttribute(Features.CONTEXT_ATTRIBUTE);
+        String auth = sc.getInitParameter("authentication");
+        return AuthenticationFactory.getInstance(auth).auth(username, password, encoding, features);
     }
 }
--- a/flys-client/src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/MetaDataServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -24,17 +24,29 @@
 
 import de.intevation.flys.client.server.meta.Converter;
 
+/**
+ * Service that returns certain meta-data from the backends data, polished to
+ * inclusion into current project.
+ */
 public class MetaDataServiceImpl
 extends      RemoteServiceServlet
 implements   MetaDataService
 {
+    /** Our very own logger. */
     private static final Logger logger =
         Logger.getLogger(MetaDataServiceImpl.class);
 
-
     public static final String ERROR_NO_META_DATA_FOUND =
         "error_no_meta_data_found";
 
+
+    /**
+     * @param locale needed for i18n.
+     * @param artifactId ID of masterartifact (can be null)
+     * @param userId can be null
+     * @param outs can be null
+     * @param parameters can be null
+     */
     @Override
     public DataCageTree getMetaData(
         String locale,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ModuleServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,99 @@
+package de.intevation.flys.client.server;
+
+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.ModuleService;
+import de.intevation.flys.client.server.auth.User;
+import de.intevation.flys.client.shared.exceptions.ServerException;
+import de.intevation.flys.client.shared.model.DefaultModule;
+import de.intevation.flys.client.shared.model.Module;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class ModuleServiceImpl
+extends      RemoteServiceServlet
+implements   ModuleService
+{
+    private static final Logger logger =
+        Logger.getLogger(ModuleServiceImpl.class);
+
+    public static final String XPATH_MODULES = "/art:modules/art:module";
+
+    public static final String ERROR_NO_MODULES_FOUND =
+        "error_no_module_found";
+
+    @Override
+    public Module[] list(String locale) throws ServerException {
+        User user = this.getUser();
+
+        logger.info("ModuleService.list");
+
+        String url = getServletContext().getInitParameter("server-url");
+
+        // create dummy xml
+        Document doc = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
+            doc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element dummy = ec.create("modules");
+        doc.appendChild(dummy);
+
+        HttpClient client = new HttpClientImpl(url, locale);
+        try {
+            Document result = client.callService(url, "modules", doc);
+
+            NodeList list = (NodeList) XMLUtils.xpath(
+                result,
+                XPATH_MODULES,
+                XPathConstants.NODESET,
+                ArtifactNamespaceContext.INSTANCE);
+
+            if (list == null) {
+                logger.warn("No modules found.");
+
+                throw new ServerException(ERROR_NO_MODULES_FOUND);
+            }
+
+            int num = list.getLength();
+
+            List<Module> modules = new ArrayList<Module>(list.getLength());
+            for(int i =0; i < num; i++) {
+                Element em = (Element)list.item(i);
+                String name = em.getAttributeNS(
+                        ArtifactNamespaceContext.NAMESPACE_URI, "name");
+                String localname = em.getAttributeNS(
+                        ArtifactNamespaceContext.NAMESPACE_URI, "localname");
+                String strselected = em.getAttributeNS(
+                        ArtifactNamespaceContext.NAMESPACE_URI, "selected");
+                boolean selected = strselected == null ? false :
+                        strselected.equalsIgnoreCase("true");
+                logger.debug("Found module " + name + " " + localname);
+                if (user == null || user.canUseFeature("module:" + name)) {
+                    modules.add(new DefaultModule(name, localname, selected));
+                }
+            }
+            return modules.toArray(new Module[modules.size()]);
+        }
+        catch (ConnectionException ce) {
+            logger.error(ce, ce);
+        }
+
+        throw new ServerException(ERROR_NO_MODULES_FOUND);
+    }
+}
+
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ProxyServlet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,113 @@
+package de.intevation.flys.client.server;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.client.server.auth.User;
+
+/**
+ * Implements a Proxy for HTTP Requests
+ */
+public class ProxyServlet
+extends HttpServlet
+{
+    private static Logger logger = Logger.getLogger(ProxyServlet.class);
+    private String remoteurl;
+
+    @Override
+    public void init(ServletConfig config) {
+        this.remoteurl = config.getInitParameter("remoteurl");
+    }
+
+    @Override
+    public void doPost(HttpServletRequest req, HttpServletResponse resp) {
+    }
+
+    @Override
+    public void doGet(HttpServletRequest req, HttpServletResponse resp)
+    throws IOException {
+        HttpClient httpclient = new DefaultHttpClient();
+
+        String requesturi = req.getRequestURI();
+        String query = req.getQueryString();
+
+        HttpGet httpget = new HttpGet(this.remoteurl + "?" + query);
+
+        boolean debug = logger.isDebugEnabled();
+
+        for (Enumeration e = req.getHeaderNames(); e.hasMoreElements();) {
+            String name = (String)e.nextElement();
+            for (Enumeration f = req.getHeaders(name); f.hasMoreElements();) {
+                String value = (String)f.nextElement();
+                if (debug) {
+                    logger.debug(
+                        "Adding request header " + name + " : " + value);
+                }
+                httpget.addHeader(name, value);
+            }
+        }
+
+        HttpResponse response = httpclient.execute(httpget);
+
+        StatusLine statusline = response.getStatusLine();
+        if (debug) {
+            logger.debug("Response statuscode " + statusline.getStatusCode());
+        }
+        resp.setStatus(statusline.getStatusCode());
+
+        Header[] headers = response.getAllHeaders();
+        for(Header header : headers) {
+            if (debug) {
+                logger.debug(
+                    "Adding response header " + header.getName() +
+                    " : " + header.getValue());
+            }
+            resp.setHeader(header.getName(), header.getValue());
+        }
+
+        HttpEntity entity = response.getEntity();
+        if (entity != null) {
+            InputStream instream = entity.getContent();
+            byte [] buf = new byte[4096];
+            try {
+                OutputStream outstream = resp.getOutputStream();
+                try {
+                    int read;
+                    while ((read = instream.read(buf)) >= 0) {
+                        outstream.write(buf, 0, read);
+                    }
+                    outstream.flush();
+                }
+                finally {
+                    outstream.close();
+                }
+            }
+            finally {
+                instream.close();
+            }
+        }
+    }
+
+    private User getUser(HttpServletRequest req) {
+            HttpSession session = req.getSession();
+            return (User)session.getAttribute("user");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/RemoteServiceServlet.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,18 @@
+package de.intevation.flys.client.server;
+
+import de.intevation.flys.client.server.auth.User;
+
+import javax.servlet.http.HttpSession;
+
+public class RemoteServiceServlet
+extends      com.google.gwt.user.server.rpc.RemoteServiceServlet
+{
+    /**
+     * Return the current logged in user from the HTTP Session
+     */
+    public User getUser() {
+        HttpSession session = this.getThreadLocalRequest().getSession();
+        return (User)session.getAttribute("user");
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/RiverServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,29 +1,25 @@
 package de.intevation.flys.client.server;
 
+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.RiverService;
+import de.intevation.flys.client.server.auth.User;
+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 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 org.apache.log4j.Logger;
-
-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;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
 
 
 /**
@@ -49,6 +45,7 @@
 
 
     /** Get river list. */
+    @Override
     public River[] list(String locale)
     throws ServerException
     {
@@ -81,17 +78,21 @@
             int count = rivers.getLength();
 
             List<River> theRivers = new ArrayList<River>(count);
+            User user = this.getUser();
 
             for (int i = 0; i < count; i++) {
-                Node tmp = rivers.item(i);
+                Element tmp = (Element)rivers.item(i);
 
-                String name = XMLUtils.xpathString(
-                    tmp, "@art:name", ArtifactNamespaceContext.INSTANCE);
+                String name = tmp.getAttributeNS(
+                    ArtifactNamespaceContext.NAMESPACE_URI, "name");
 
-                theRivers.add(new DefaultRiver(name));
+                if (name.length() > 0
+                && (user == null || user.canUseFeature("river:" + name))) {
+                    theRivers.add(new DefaultRiver(name));
+                }
             }
 
-            return (River[]) theRivers.toArray(new River[count]);
+            return theRivers.toArray(new River[theRivers.size()]);
         }
         catch (ConnectionException ce) {
             logger.error(ce, ce);
--- a/flys-client/src/main/java/de/intevation/flys/client/server/StyleHelper.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/StyleHelper.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,19 +1,14 @@
 package de.intevation.flys.client.server;
 
+import de.intevation.flys.client.shared.model.Style;
+import de.intevation.flys.client.shared.model.StyleSetting;
+
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import org.apache.log4j.Logger;
-
-import de.intevation.flys.client.shared.model.Style;
-import de.intevation.flys.client.shared.model.StyleSetting;
-
 
 public class StyleHelper {
 
-    private static final Logger logger = Logger.getLogger(StyleHelper.class);
-
-
     public static Style getStyle (Element element) {
         if (!element.getTagName().equals("theme")) {
             return null;
--- a/flys-client/src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/UserCollectionsServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -76,7 +76,7 @@
 
             logger.debug("User has " + all.size() + " collections.");
 
-            return (Collection[]) all.toArray(new Collection[all.size()]);
+            return all.toArray(new Collection[all.size()]);
         }
         catch (ConnectionException ce) {
             logger.error(ce, ce);
--- a/flys-client/src/main/java/de/intevation/flys/client/server/UserServiceImpl.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/UserServiceImpl.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,28 +1,19 @@
 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 org.w3c.dom.Element;
 
 import org.apache.log4j.Logger;
 
-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.server.auth.UserClient;
 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>
  */
@@ -30,36 +21,34 @@
 extends      RemoteServiceServlet
 implements   UserService
 {
+    /** Private logger. */
     private static final Logger logger = Logger.getLogger(UserServiceImpl.class);
 
+    public static final String ERROR_NO_SUCH_USER = "error_no_such_user";
 
-    public static final String ERROR_NO_SUCH_USER = "error_no_such_user";
+    public static final String ERROR_NO_USERS = "error_no_users";
 
     public User getCurrentUser(String locale)
     throws AuthenticationException
     {
         String url = getServletContext().getInitParameter("server-url");
 
-        HttpClient client = new HttpClientImpl(url);
+        UserClient client = new UserClient(url);
+        de.intevation.flys.client.server.auth.User loginuser = getUser();
+
+        if (loginuser == null) {
+            logger.debug("no session user");
+            throw new AuthenticationException(ERROR_NO_SUCH_USER);
+        }
 
         try {
-            Document users = (Document) client.listUsers();
-
-            String XPATH_USERS = "/art:users/art:user";
+            Element user = client.findUser(loginuser);
 
-            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);
+            if (user != null) {
+                String uuid = user.getAttributeNS(
+                        ArtifactNamespaceContext.NAMESPACE_URI, "uuid");
+                String name = user.getAttributeNS(
+                        ArtifactNamespaceContext.NAMESPACE_URI, "name");
 
                 return new DefaultUser(uuid, name);
             }
@@ -69,7 +58,7 @@
         }
 
         logger.error("No users existing in the server.");
-        throw new AuthenticationException(ERROR_NO_SUCH_USER);
+        throw new AuthenticationException(ERROR_NO_USERS);
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/AuthenticationFactory.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/AuthenticationFactory.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,19 +8,24 @@
         Logger.getLogger(AuthenticationFactory.class);
 
     public static Authenticator getInstance(String name)
-        throws IllegalArgumentException {
-        if (name == null
-        || name.equalsIgnoreCase("was")
-        || name.equalsIgnoreCase("ggina")) {
+        throws IllegalArgumentException
+    {
+        if (name == null) {
+            throw new IllegalArgumentException("Authentication type name is null");
+        }
+
+        if (name.equalsIgnoreCase("was") ||
+            name.equalsIgnoreCase("ggina")) {
             log.debug("Using GGinA authenticator.");
             return
                 new de.intevation.flys.client.server.auth.was.Authenticator();
         }
-        if (name.equalsIgnoreCase("plain")) {
+        else if (name.equalsIgnoreCase("plain")) {
             log.debug("Using plain authenticator.");
             return
                 new de.intevation.flys.client.server.auth.plain.Authenticator();
         }
+
         throw new IllegalArgumentException("Unkown Authentication " + name);
     }
 }
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/Authenticator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/Authenticator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,9 +2,11 @@
 
 import java.io.IOException;
 
+import de.intevation.flys.client.server.features.Features;
+
 public interface Authenticator {
 
-    public Authentication auth(String username, String password, String encoding)
+    public Authentication auth(String username, String password, String encoding, Features features)
         throws AuthenticationException, IOException;
 
 }
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/DefaultUser.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/DefaultUser.java	Fri Sep 28 12:15:40 2012 +0200
@@ -6,9 +6,11 @@
 implements   User
 {
     protected String  name;
+    protected String  account;
     protected String  password;
     protected boolean expired;
     protected List<String> roles;
+    protected List<String> features;
 
     public DefaultUser() {
     }
@@ -16,13 +18,16 @@
     public DefaultUser(
         String       name,
         String       password,
-        boolean      expired, 
-        List<String> roles
+        boolean      expired,
+        List<String> roles,
+        List<String> features
     ) {
         this.name     = name;
         this.password = password;
         this.expired  = expired;
         this.roles    = roles;
+        this.features = features;
+        this.account  = name;
     }
 
     @Override
@@ -61,5 +66,23 @@
     public void setRoles(List<String> roles) {
         this.roles = roles;
     }
+
+    @Override
+    public boolean canUseFeature(String feature) {
+        return this.features.contains(feature);
+    }
+
+    public void setAllowedFeatures(List<String> features) {
+        this.features = features;
+    }
+
+    @Override
+    public String getAccount() {
+        return this.account;
+    }
+
+    public void setAccount(String account) {
+        this.account = account;
+    }
 }
 // vim:set ts=4 sw=4 si et fenc=utf8 tw=80:
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/User.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/User.java	Fri Sep 28 12:15:40 2012 +0200
@@ -27,5 +27,16 @@
      * Returns a list of roles corresponsing the the user
      */
     public List<String> getRoles();
+
+
+    /**
+     * Returns true if the user is allowed access the feature
+     */
+    public boolean canUseFeature(String feature);
+
+    /**
+     * Returns the users account name
+     */
+    public String getAccount();
 }
 // vim:set ts=4 sw=4 si et fenc=utf8 tw=80:
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/UserClient.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/UserClient.java	Fri Sep 28 12:15:40 2012 +0200
@@ -31,23 +31,30 @@
     }
 
     public boolean userExists(User user) throws ConnectionException {
-        NodeList users = this.listUsers();
-
-        if (users == null || users.getLength() == 0) {
+        if (user == null) {
             return false;
         }
-        for(int i=0; i < users.getLength(); i++) {
-            Node usernode = users.item(i);
-            String name = XMLUtils.xpathString(
-                usernode, "@art:name", ArtifactNamespaceContext.INSTANCE);
-            if (name.equals(user.getName())) {
-                return true;
-            }
+
+        Element data = this.findUser(user);
+
+        String XPATH_USERACCOUNT = "/art:user/art:account/@art:name";
+
+        String account = XMLUtils.xpathString(
+            data, XPATH_USERACCOUNT, ArtifactNamespaceContext.INSTANCE);
+
+        if (account == null) {
+            return false;
         }
-        return false;
+
+        return account.equals(user.getAccount());
     }
 
     public boolean createUser(User user) throws ConnectionException {
+        if(user == null) {
+            logger.warn("createUser: given user is null");
+            return false;
+        }
+
         logger.debug("Creating new user " + user.getName());
         HttpClient client = new HttpClientImpl(this.url);
 
@@ -65,8 +72,11 @@
         type.setAttribute("name", "create");
         Element artuser = creator.create("user");
         artuser.setAttribute("name", user.getName());
+        Element account = creator.create("account");
+        account.setAttribute("name", user.getAccount());
 
         //TODO create roles
+        artuser.appendChild(account);
         action.appendChild(type);
         action.appendChild(artuser);
         document.appendChild(action);
@@ -100,6 +110,49 @@
             XPathConstants.NODESET,
             ArtifactNamespaceContext.INSTANCE);
     }
+
+    public Element findUser(User user) throws ConnectionException {
+        if(user == null) {
+            throw new IllegalArgumentException("user is null");
+        }
+
+        HttpClient client = new HttpClientImpl(this.url);
+
+        Document document = XMLUtils.newDocument();
+
+        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
+            document,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX
+        );
+
+        Element action = creator.create("action");
+
+        Element type = creator.create("type");
+        type.setAttribute("name", "find");
+        Element account = creator.create("account");
+        account.setAttribute("name", user.getAccount());
+
+        action.appendChild(type);
+        action.appendChild(account);
+        document.appendChild(action);
+
+        boolean debug = logger.isDebugEnabled();
+
+        if (debug) {
+            logger.debug("Find user request xml: " +
+                XMLUtils.toString(document));
+        }
+
+        Document resp = client.findUser(document);
+
+        if (debug) {
+            logger.debug("Find user request response xml: " +
+                XMLUtils.toString(resp));
+        }
+
+        return resp.getDocumentElement();
+    }
 }
 // vim: set si et fileencoding=utf-8 ts=4 sw=4 tw=80:
 
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/plain/Authenticator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -14,6 +14,11 @@
 
 import org.apache.log4j.Logger;
 
+import de.intevation.flys.client.server.features.Features;
+
+/**
+ * Authenticator that uses a local file as user backend.
+ */
 public class Authenticator
 implements   de.intevation.flys.client.server.auth.Authenticator
 {
@@ -26,15 +31,18 @@
         protected String       user;
         protected String       password;
         protected List<String> roles;
+        protected Features     features;
 
         public Authentication(
             String       user,
             String       password,
-            List<String> roles
+            List<String> roles,
+            Features features
         ) {
             this.user     = user;
             this.password = password;
             this.roles    = roles;
+            this.features = features;
         }
 
         @Override
@@ -45,7 +53,7 @@
         @Override
         public User getUser() {
             return isSuccess()
-                ? new DefaultUser(user, password, false, roles)
+                ? new DefaultUser(user, password, false, roles, this.features.getFeatures(roles))
                 : null;
         }
     } // class Authentication
@@ -62,6 +70,7 @@
                 + System.getProperty("file.separator")
                 + "flys_user_file");
         }
+        log.debug("Using credentials file " + env);
         return new File(env);
 
     }
@@ -70,14 +79,15 @@
     public de.intevation.flys.client.server.auth.Authentication auth(
         String username,
         String password,
-        String encoding
+        String encoding,
+        Features features
     )
     throws AuthenticationException, IOException
     {
         File file = credentialsFile();
         if (!file.canRead() || !file.isFile()) {
             log.error("cannot find user file '" + file + "'");
-            return new Authentication(null, null, new ArrayList<String>(0));
+            return new Authentication(null, null, new ArrayList<String>(0), features);
         }
 
         BufferedReader reader =
@@ -90,10 +100,12 @@
                 || line.startsWith("#")) {
                     continue;
                 }
-                String [] parts = line.split("\\s+");
+
+                String[] parts = line.split("\\s+");
                 if (parts.length < 2) {
                     continue;
                 }
+
                 if (parts[0].equals(username)) {
                     log.debug("user '" + username + "' found.");
                     if (parts[1].equals(password)) {
@@ -105,7 +117,7 @@
                         }
 
                         log.debug("success");
-                        return new Authentication(username, password, roles);
+                        return new Authentication(username, password, roles, features);
                     }
                     // Stop: user found, wrong password
                     break;
@@ -116,7 +128,7 @@
             reader.close();
         }
         log.debug("failed");
-        return new Authentication(null, null, new ArrayList<String>(0));
+        return null;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/was/Authenticator.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/was/Authenticator.java	Fri Sep 28 12:15:40 2012 +0200
@@ -13,17 +13,28 @@
 import de.intevation.flys.client.server.GGInATrustStrategy;
 import de.intevation.flys.client.server.auth.Authentication;
 import de.intevation.flys.client.server.auth.AuthenticationException;
+import de.intevation.flys.client.server.features.Features;
 
-public class Authenticator implements de.intevation.flys.client.server.auth.Authenticator {
+public class Authenticator
+implements de.intevation.flys.client.server.auth.Authenticator {
 
-    public Authentication auth(String username, String password, String encoding)
-        throws AuthenticationException, IOException {
+    @Override
+    public Authentication auth(
+        String username,
+        String password,
+        String encoding,
+        Features features
+    ) throws
+        AuthenticationException,
+        IOException
+    {
             try {
                 SSLSocketFactory sf = new SSLSocketFactory(
                         new GGInATrustStrategy());
                 Scheme https = new Scheme("https", 443, sf);
                 HttpClient httpclient = new DefaultHttpClient();
-                httpclient.getConnectionManager().getSchemeRegistry().register(https);
+                httpclient.getConnectionManager().getSchemeRegistry().register(
+                        https);
 
                 Request httpget = new Request("https://geoportal.bafg.de/" +
                         "administration/WAS", username, password, encoding);
@@ -34,7 +45,7 @@
                     return null;
                 }
                 else {
-                    return new Response(entity, username, password);
+                    return new Response(entity, username, password, features);
                 }
             }
             catch(GeneralSecurityException e) {
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/was/Response.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/was/Response.java	Fri Sep 28 12:15:40 2012 +0200
@@ -2,6 +2,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 
 import org.apache.commons.codec.binary.Base64InputStream;
 
@@ -17,6 +18,8 @@
 import de.intevation.flys.client.server.auth.Authentication;
 import de.intevation.flys.client.server.auth.AuthenticationException;
 
+import de.intevation.flys.client.server.features.Features;
+
 public class Response implements Authentication {
 
     private static Logger logger = Logger.getLogger(Response.class);
@@ -25,9 +28,10 @@
     private Assertion assertion;
     private String username;
     private String password;
+    private Features features;
 
 
-    public Response(HttpEntity entity, String username, String password) throws AuthenticationException, IOException {
+    public Response(HttpEntity entity, String username, String password, Features features) throws AuthenticationException, IOException {
 
         if (entity == null) {
             throw new ServiceException("Invalid response");
@@ -55,6 +59,7 @@
             this.root = root;
             this.username = username;
             this.password = password;
+            this.features = features;
 
         }
         catch(JDOMException e) {
@@ -102,7 +107,12 @@
         if (assertion == null) {
             throw new AuthenticationException("Response doesn't contain an assertion");
         }
-        return new User(this.username, this.password, this.assertion.getRoles(), assertion);
+        List<String> features = this.features.getFeatures(
+                this.assertion.getRoles());
+        logger.debug("User " + this.username + " with features " + features +
+                     " successfully authenticated.");
+        return new User(this.username, this.password, assertion.getNameID(),
+                this.assertion.getRoles(), assertion, features);
     }
 }
 // vim: set si et fileencoding=utf-8 ts=4 sw=4 tw=80:
--- a/flys-client/src/main/java/de/intevation/flys/client/server/auth/was/User.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/auth/was/User.java	Fri Sep 28 12:15:40 2012 +0200
@@ -11,11 +11,19 @@
 
     private Assertion assertion;
 
-    public User(String name, String password, List<String> roles, Assertion assertion) {
+    public User(String name,
+        String       password,
+        String       account,
+        List<String> roles,
+        Assertion    assertion,
+        List<String> features
+    ) {
         this.setName(name);
         this.setPassword(password);
         this.setRoles(roles);
         this.assertion = assertion;
+        this.setAllowedFeatures(features);
+        this.setAccount(account);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/features/Features.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,13 @@
+package de.intevation.flys.client.server.features;
+
+import java.util.List;
+
+public interface Features {
+
+    public static final String CONTEXT_ATTRIBUTE = "de.intevation.flys.client.server.features";
+
+    /**
+     * Returns all allowed features to a list of roles
+     */
+    public List<String> getFeatures(List<String> roles);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/features/FeaturesNamespaceContext.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,80 @@
+package de.intevation.flys.client.server.features;
+
+import java.util.Iterator;
+
+import javax.xml.XMLConstants;
+
+import javax.xml.namespace.NamespaceContext;
+
+public class FeaturesNamespaceContext
+implements   NamespaceContext {
+
+    /**
+     * The URI of the namespace of the features.
+     */
+    public final static String NAMESPACE_URI =
+        "http://www.intevation.de/2012/flys/features";
+
+    /**
+     * The XML prefix for the features namespace.
+     */
+    public final static String NAMESPACE_PREFIX = "ftr";
+
+    /**
+     * Final instance to be easily used to avoid creation
+     * of instances.
+     */
+    public static final FeaturesNamespaceContext INSTANCE =
+        new FeaturesNamespaceContext();
+
+    /**
+     * The default constructor.
+     */
+    public FeaturesNamespaceContext() {
+    }
+
+    /**
+     * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(String)
+     * @param prefix The prefix
+     * @return The corresponing URI
+     */
+    @Override
+    public String getNamespaceURI(String prefix) {
+
+        if (prefix == null) {
+            throw new NullPointerException("Null prefix");
+        }
+
+        if (NAMESPACE_PREFIX.equals(prefix)) {
+            return NAMESPACE_URI;
+        }
+
+        if ("xml".equals(prefix)) {
+            return XMLConstants.XML_NS_URI;
+        }
+
+        return XMLConstants.NULL_NS_URI;
+    }
+
+    /**
+     * @see javax.xml.namespace.NamespaceContext#getPrefix(String)
+     * @param uri The URI
+     * @return nothing.
+     * @throws java.lang.UnsupportedOperationException
+     */
+    @Override
+    public String getPrefix(String uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String)
+     * @param uri The URI
+     * @return nothing
+     * @throws java.lang.UnsupportedOperationException
+     */
+    @Override
+    public Iterator getPrefixes(String uri) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/features/XMLFileFeatures.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,96 @@
+package de.intevation.flys.client.server.features;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+public class XMLFileFeatures implements Features {
+
+    private static final Logger logger =
+        Logger.getLogger(XMLFileFeatures.class);
+
+    private Map<String, List<String>> featuremap =
+        new HashMap<String, List<String>>();
+
+    private final static String XPATH_FEATURES = "ftr:feature/child::text()";
+    private final static String XPATH_ROLES    = "/ftr:features/ftr:role";
+
+    public XMLFileFeatures(String filename) throws IOException {
+        FileInputStream finput = new FileInputStream(filename);
+
+        try {
+            Document doc = XMLUtils.parseDocument(finput);
+
+            NodeList roles = (NodeList) XMLUtils.xpath(
+                doc,
+                XPATH_ROLES,
+                XPathConstants.NODESET,
+                FeaturesNamespaceContext.INSTANCE);
+
+            for(int i = 0, m = roles.getLength(); i < m; i++) {
+                Element rolenode = (Element)roles.item(i);
+
+                String name = rolenode.getAttribute("name");
+
+                logger.debug("Found role: " + name);
+
+                NodeList features = (NodeList) XMLUtils.xpath(
+                    rolenode,
+                    XPATH_FEATURES,
+                    XPathConstants.NODESET,
+                    FeaturesNamespaceContext.INSTANCE);
+
+                if (features == null) {
+                    continue;
+                }
+
+                int N = features.getLength();
+
+                if (N > 0) {
+                    List<String> allowed = new ArrayList<String>(N);
+                    for (int j = 0; j < N; j++) {
+                        Node featurenode = features.item(j);
+                        String featurename = featurenode.getNodeValue();
+
+                        logger.debug("Found feature: " + featurename);
+
+                        allowed.add(featurename);
+                    }
+                    featuremap.put(name, allowed);
+                }
+            }
+            logger.debug("Loaded all features");
+        }
+        finally {
+            finput.close();
+        }
+    }
+
+    @Override
+    public List<String> getFeatures(List<String> roles) {
+        List<String> features = new ArrayList<String>();
+
+        for (String role: roles) {
+            List<String> allowed = this.featuremap.get(role);
+            if (allowed != null) {
+                features.addAll(allowed);
+            }
+        }
+        return features;
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/server/meta/Converter.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/meta/Converter.java	Fri Sep 28 12:15:40 2012 +0200
@@ -19,6 +19,10 @@
 
 import de.intevation.artifacts.common.utils.XMLUtils;
 
+/**
+ * Converts document parts (meta-data xml) to datacagenodes/trees,
+ * which are shown in datacage widgets.
+ */
 public class Converter
 {
     private static final Logger logger = Logger.getLogger(Converter.class);
@@ -58,42 +62,24 @@
         }
     } // 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) {
-                    converter = I18N_CONVERTER;
-                }
-                DataCageNode son = converter.convert(
-                    (Element)child, this);
-                parent.addChild(son);
-            }
-        } // for all children
-    }
-
-    public Converter() {
-        converters = new HashMap<String, NodeConverter>();
-        registerConverters();
-    }
+    private static Map<String, NodeConverter> converters = new HashMap<String, NodeConverter>();
 
     public static final NodeConverter NAME_CONVERTER = new NameConverter();
     public static final NodeConverter I18N_CONVERTER = new I18NConverter();
 
-    protected void registerConverters() {
-        logger.debug("register converters called");
+    static {
         converters.put("river",      NAME_CONVERTER);
         converters.put("gauge",      NAME_CONVERTER);
         converters.put("historical", NAME_CONVERTER);
         converters.put("column",     NAME_CONVERTER);
     }
 
+
+    /** Trivial constructor. */
+    public Converter() {
+    }
+
+
     public DataCageTree convert(Document document) {
         logger.debug("convert called");
         //System.err.println(XMLUtils.toString(document));
@@ -116,6 +102,31 @@
             : new DataCageTree(roots.get(0));
     }
 
+    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) {
+                    converter = I18N_CONVERTER;
+                }
+                DataCageNode son = converter.convert(
+                    (Element)child, this);
+                parent.addChild(son);
+
+            if (((Element)child).hasAttribute("description"))
+                logger.debug("nwd: " + ((Element)child).getAttribute("description"));
+            }
+        } // for all children
+    }
+
+
+    /**
+     * Creates key/value pairs from Nodes Attributes.
+     */
     public static AttrList toAttrList(NamedNodeMap nodeMap) {
         if (nodeMap == null) {
             return null;
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/Artifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Artifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -30,8 +30,9 @@
 
     /**
      * Returns the name of the artifact.
+     * This happens to be the factory name, too.
      *
-     * @return the name-
+     * @return the name.
      */
     public String getName();
 
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java	Fri Sep 28 12:15:40 2012 +0200
@@ -8,6 +8,8 @@
 
 
 /**
+ * Give information about chart dimension and transform of chart<->pixel
+ * space.
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class ChartInfo implements Serializable {
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartMode.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartMode.java	Fri Sep 28 12:15:40 2012 +0200
@@ -38,7 +38,8 @@
     public OutputTab createOutputTab(String t, Collection c, CollectionView p) {
         if (this.getName().equals("fix_wq_curve") ||
             this.getName().equals("fix_deltawt_curve") ||
-            this.getName().equals("fix_derivate_curve")) {
+            this.getName().equals("fix_derivate_curve") ||
+            this.getName().equals("fix_vollmer_wq_curve")){
             return new NaviChartOutputTab(t, c, this, p);
         }
         return new ChartOutputTab(t, c, this, p);
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultArtifactDescription.java	Fri Sep 28 12:15:40 2012 +0200
@@ -116,6 +116,7 @@
     }
 
 
+    /** Get [min,max] of data items. */
     public double[] getKMRange() {
         Double[] mm = new Double[2];
 
@@ -126,14 +127,14 @@
                 String dataName = data.getLabel();
                 DataItem item   = data.getItems()[0];
 
-                if (dataName.equals("ld_from")) {
+                if (dataName.equals("ld_from") || dataName.equals("from")) {
                     Double d = DoubleUtils.getDouble(item.getStringValue());
 
                     if (d != null) {
                         mm[0] = d;
                     }
                 }
-                else if (dataName.equals("ld_to")) {
+                else if (dataName.equals("ld_to") || dataName.equals("to")) {
                     Double d = DoubleUtils.getDouble(item.getStringValue());
 
                     if (d != null) {
@@ -160,6 +161,9 @@
 
 
     public String getDataValueAsString(String name) {
+        if (oldData == null) {
+            return null;
+        }
         for (DataList list: oldData) {
             List<Data> dataList = list.getAll();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultGaugeInfo.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,151 @@
+package de.intevation.flys.client.shared.model;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class DefaultGaugeInfo implements GaugeInfo {
+
+    private String name;
+    private Double start;
+    private Double end;
+    private Double aeo;
+    private Double datum;
+    private Double minq;
+    private Double maxq;
+    private Double minw;
+    private Double maxw;
+    private boolean kmup;
+    private Double station;
+    private String wstunit;
+    private Long officialnumber;
+    private String rivername;
+
+    public DefaultGaugeInfo() {
+    }
+
+    public DefaultGaugeInfo(
+            String rivername,
+            String name,
+            boolean kmup,
+            Double station,
+            Double start,
+            Double end,
+            Double datum,
+            Double aeo,
+            Double minq,
+            Double maxq,
+            Double minw,
+            Double maxw,
+            String wstunit,
+            Long official)
+    {
+        this.rivername      = rivername;
+        this.name           = name;
+        this.kmup           = kmup;
+        this.station        = station;
+        this.start          = start;
+        this.end            = end;
+        this.datum          = datum;
+        this.aeo            = aeo;
+        this.minq           = minq;
+        this.maxq           = maxq;
+        this.minw           = minw;
+        this.maxw           = maxw;
+        this.wstunit        = wstunit;
+        this.officialnumber = official;
+    }
+    /**
+     * Returns the name of the gauge
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Returns the start KM of the gauge or null if not available
+     */
+    public Double getKmStart() {
+        return this.start;
+    }
+
+    /**
+     * Returns the end KM of the gauge or null if not available
+     */
+    public Double getKmEnd() {
+        return this.end;
+    }
+
+    /**
+     * Returns the mimimum Q value at this gauge or null if not available
+     */
+    public Double getMinQ() {
+        return this.minq;
+    }
+
+    /**
+     * Returns the maximum Q value at this gauge or null if not available
+     */
+    public Double getMaxQ() {
+        return this.maxq;
+    }
+
+    /**
+     * Returns the mimimum W value at this gauge or null if not available
+     */
+    public Double getMinW() {
+        return this.minw;
+    }
+
+    /**
+     * Returns the maximim W value at this gauge or null if not available
+     */
+    public Double getMaxW() {
+        return this.maxw;
+    }
+
+    /**
+     * Returns the datum value or null if not available
+     */
+    public Double getDatum() {
+        return this.datum;
+    }
+
+    /**
+     * Returns the aeo value or null if not available
+     */
+    public Double getAeo() {
+        return this.aeo;
+    }
+
+    public boolean isKmUp() {
+        return this.kmup;
+    }
+
+    /**
+     * Returns the station km of the gauge or null if not available
+     */
+    public Double getStation() {
+        return this.station;
+    }
+
+    /**
+     * Returns the wst unit as a String
+     */
+    public String getWstUnit() {
+        return this.wstunit;
+    }
+
+    /**
+     * Returns the official number of this gauge
+     */
+    public Long getOfficialNumber() {
+        return this.officialnumber;
+    }
+
+    /**
+     * Returns the river to which this gauge belongs
+     */
+    public String getRiverName() {
+        return this.rivername;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultModule.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,39 @@
+package de.intevation.flys.client.shared.model;
+
+public class DefaultModule implements Module {
+
+    private String name;
+    private String localname;
+    private boolean selected = false;
+
+    public DefaultModule() {
+    }
+
+    public DefaultModule(String name, String localname, boolean selected) {
+        this.name = name;
+        this.localname = localname;
+        this.selected = selected;
+    }
+
+    /**
+     * Returns the name of the module
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Returns the localized name of the module
+     */
+    public String getLocalizedName() {
+        return this.localname;
+    }
+
+    /**
+     * Returns true if the module should be selected
+     */
+    public boolean isSelected() {
+        return this.selected;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultRiverInfo.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,107 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+
+public class DefaultRiverInfo implements RiverInfo {
+
+    private String name;
+    private boolean kmup;
+    private Double start;
+    private Double end;
+    private String wstunit;
+    private Double minq;
+    private Double maxq;
+    private Long officialnumber;
+
+    private List<GaugeInfo> gaugeinfo;
+
+    public DefaultRiverInfo() {
+    }
+
+    public DefaultRiverInfo(
+            String name,
+            boolean kmup,
+            Double start,
+            Double end,
+            String wstunit,
+            Double minq,
+            Double maxq,
+            Long official,
+            List<GaugeInfo> gaugeinfo)
+    {
+        this.name           = name;
+        this.kmup           = kmup;
+        this.start          = start;
+        this.end            = end;
+        this.wstunit        = wstunit;
+        this.minq           = minq;
+        this.maxq           = maxq;
+        this.officialnumber = official;
+        this.gaugeinfo      = gaugeinfo;
+    }
+
+
+    public boolean isKmUp() {
+        return this.kmup;
+    }
+
+    /**
+     * Start KM of the river
+     */
+    public Double getKmStart() {
+        return this.start;
+    }
+
+    /**
+     * End KM of the river
+     */
+    public Double getKmEnd() {
+        return this.end;
+    }
+
+    /**
+     * Returns the name of the river
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Returns the name of the WST unit
+     */
+    public String getWstUnit() {
+        return this.wstunit;
+    }
+
+    /**
+     * Return all gauge info of the river
+     */
+    public List<GaugeInfo> getGauges() {
+        return this.gaugeinfo;
+    }
+
+    /**
+     * Returns the min q value of the river
+     */
+    public Double getMinQ() {
+        return this.minq;
+    }
+
+    /**
+     * Returns the max q value of the river
+     */
+    public Double getMaxQ() {
+        return maxq;
+    }
+
+    /**
+     * Returns the official number of the river
+     */
+    public Long getOfficialNumber() {
+        return this.officialnumber;
+    }
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/DoubleProperty.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DoubleProperty.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,10 +1,10 @@
 package de.intevation.flys.client.shared.model;
 
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
+
 import java.util.HashMap;
 
-import com.google.gwt.i18n.client.NumberFormat;
-import com.google.gwt.core.client.GWT;
-
 /**
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
@@ -35,8 +35,9 @@
     @Override
     public Double getValue() {
         try {
-            GWT.log("returning: " + Double.valueOf(this.value));
-            return Double.valueOf(this.value);
+            Double value = Double.valueOf(this.value);
+            GWT.log("returning: " + value);
+            return value;
         }
         catch(NumberFormatException nfe) {
             //Should never happen, if property is used correctly.
@@ -65,7 +66,7 @@
         double dv;
         NumberFormat nf = NumberFormat.getDecimalFormat();
         try {
-            dv = Double.valueOf(this.value).doubleValue();
+            dv = Double.parseDouble(this.value);
         }
         catch (NumberFormatException nfe) {
             return null;
@@ -73,6 +74,7 @@
         return nf.format(dv);
     }
 
+    @Override
     public Object clone() {
         DoubleProperty clone = new DoubleProperty(this.getName(),
                                                   this.getValue());
@@ -81,5 +83,4 @@
         }
         return clone;
     }
-
 }
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/FacetRecord.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/FacetRecord.java	Fri Sep 28 12:15:40 2012 +0200
@@ -3,6 +3,7 @@
 import com.smartgwt.client.widgets.grid.ListGridRecord;
 
 /**
+ * ListGridRecord for Facets.
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class FacetRecord extends ListGridRecord {
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/FixAnalysisArtifact.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/FixAnalysisArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -12,7 +12,7 @@
  */
 public class FixAnalysisArtifact extends DefaultArtifact {
 
-    /** The name of this artifact: 'minfo'.*/
+    /** The name of this artifact: 'fixanalysis'.*/
     public static final String NAME = "fixanalysis";
 
     protected FixFilter filter;
@@ -62,7 +62,7 @@
         String from = artifactDescription.getDataValueAsString("from");
         if (from != null) {
             try {
-                double fkm = Double.valueOf(from).doubleValue();
+                double fkm = Double.parseDouble(from);
                 this.filter.setFromKm(fkm);
             }
             catch(NumberFormatException nfe) {
@@ -73,7 +73,7 @@
         String to = artifactDescription.getDataValueAsString("to");
         if (to != null) {
             try {
-                double tkm = Double.valueOf(to).doubleValue();
+                double tkm = Double.parseDouble(to);
                 this.filter.setToKm(tkm);
             }
             catch(NumberFormatException nfe) {
@@ -106,7 +106,7 @@
         String q1 = artifactDescription.getDataValueAsString("q1");
         if (q1 != null) {
             try {
-                int q1i = Integer.valueOf(q1).intValue();
+                int q1i = Integer.parseInt(q1);
                 this.filter.setFromClass(q1i);
             }
             catch(NumberFormatException nfe) {
@@ -117,7 +117,7 @@
         String q2 = artifactDescription.getDataValueAsString("q2");
         if (q2 != null) {
             try {
-                int q2i =Integer.valueOf(q2).intValue();
+                int q2i = Integer.parseInt(q2);
                 this.filter.setToClass(q2i);
             }
             catch(NumberFormatException nfe) {
@@ -146,7 +146,5 @@
         }
         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/GaugeDischargeCurveArtifact.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,39 @@
+package de.intevation.flys.client.shared.model;
+
+import java.util.List;
+
+/**
+ * The GaugeDischargeCurveArtifact implementation of an Artifact.
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeDischargeCurveArtifact extends DefaultArtifact {
+
+    /** The name of this artifact */
+    public static final String NAME = "gauge_discharge_curve";
+
+
+    public GaugeDischargeCurveArtifact() {
+    }
+
+
+    public GaugeDischargeCurveArtifact(String uuid, String hash) {
+        super(uuid, hash);
+    }
+
+
+    public GaugeDischargeCurveArtifact(
+        String                   uuid,
+        String                   hash,
+        boolean                  inBackground,
+        List<CalculationMessage> messages
+    ) {
+        super(uuid, hash, inBackground, messages);
+    }
+
+
+    public String getName() {
+        return NAME;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/GaugeInfo.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,76 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public interface GaugeInfo extends Serializable {
+
+    /**
+     * Returns the name of the gauge
+     */
+    String getName();
+
+    /**
+     * Returns the start KM of the gauge or null if not available
+     */
+    Double getKmStart();
+
+    /**
+     * Returns the end KM of the gauge or null if not available
+     */
+    Double getKmEnd();
+
+    /**
+     * Returns the mimimum Q value at this gauge or null if not available
+     */
+    Double getMinQ();
+
+    /**
+     * Returns the maximum Q value at this gauge or null if not available
+     */
+    Double getMaxQ();
+
+    /**
+     * Returns the mimimum W value at this gauge or null if not available
+     */
+    Double getMinW();
+
+    /**
+     * Returns the maximim W value at this gauge or null if not available
+     */
+    Double getMaxW();
+
+    /**
+     * Returns the datum value or null if not available
+     */
+    Double getDatum();
+
+    /**
+     * Returns the aeo value or null if not available
+     */
+    Double getAeo();
+
+    boolean isKmUp();
+
+    /**
+     * Returns the station km of the gauge or null if not available
+     */
+    Double getStation();
+
+    /**
+     * Returns the wst unit as a String
+     */
+    String getWstUnit();
+
+    /**
+     * Returns the official number of this gauge
+     */
+    Long getOfficialNumber();
+
+    /**
+     * Returns the river to which this gauge belongs
+     */
+    String getRiverName();
+}
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/IntegerOptionsData.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/IntegerOptionsData.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,6 +1,7 @@
 package de.intevation.flys.client.shared.model;
 
 
+/** Data matching to labelled integer(s). */
 public class IntegerOptionsData implements Data {
 
     public static final String TYPE = "intoptions";
@@ -87,5 +88,6 @@
         }
         return data;
     }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
 
-}
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/MapMode.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/MapMode.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,21 +1,23 @@
 package de.intevation.flys.client.shared.model;
 
-import java.util.List;
-
 import de.intevation.flys.client.client.ui.CollectionView;
 import de.intevation.flys.client.client.ui.OutputTab;
 import de.intevation.flys.client.client.ui.map.MapOutputTab;
 
+import java.util.List;
+
 
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
 public class MapMode extends DefaultOutputMode {
 
+    /**
+     * Default constructor required for serialization.
+     */
     public MapMode() {
     }
 
-
     public MapMode(String name, String desc, String mimeType) {
         super(name, desc, mimeType);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Module.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,13 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+
+public interface Module extends Serializable {
+
+    String getName();
+
+    String getLocalizedName();
+
+    boolean isSelected();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 tw=80 :
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/OutputSettings.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/OutputSettings.java	Fri Sep 28 12:15:40 2012 +0200
@@ -27,11 +27,13 @@
     }
 
 
+    /** Set output name. */
     public void setName(String name) {
         this.name = name;
     }
 
 
+    /** Get output name. */
     public String getName() {
         return this.name;
     }
@@ -68,3 +70,5 @@
         return clone;
     }
 }
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/PropertyGroup.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/PropertyGroup.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,9 +1,10 @@
 package de.intevation.flys.client.shared.model;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.ArrayList;
 
 /**
+ * A group of properties.
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
 public class PropertyGroup implements Property, Cloneable {
@@ -14,7 +15,6 @@
     protected List<Property> properties;
 
     public PropertyGroup() {
-
     }
 
     public PropertyGroup(String name) {
@@ -51,7 +51,7 @@
         return null;
     }
 
-
+    @Override
     public Object clone() {
         PropertyGroup clone = new PropertyGroup(this.getName());
         List<Property> cloneList = new ArrayList<Property>();
@@ -61,4 +61,20 @@
         clone.setProperties(cloneList);
         return clone;
     }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+
+        for(Property p : properties) {
+            buf.append(p.getName());
+            buf.append("=");
+            if(p instanceof PropertySetting) {
+                buf.append(((PropertySetting)p).getValue().toString());
+            }
+            buf.append(" ");
+        }
+
+        return buf.toString();
+    }
 }
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/PropertySetting.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/PropertySetting.java	Fri Sep 28 12:15:40 2012 +0200
@@ -1,7 +1,8 @@
 package de.intevation.flys.client.shared.model;
 
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
@@ -63,11 +64,11 @@
         return attributes.get(key);
     }
 
-    public ArrayList<String> getAttributeList() {
+    public List<String> getAttributeList() {
         return new ArrayList<String>(attributes.keySet());
     }
 
-
+    @Override
     public Object clone() {
         PropertySetting clone = new PropertySetting(this.getName(),
                                                     this.getValue().toString());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/RiverInfo.java	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,55 @@
+package de.intevation.flys.client.shared.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+
+public interface RiverInfo extends Serializable {
+
+    boolean isKmUp();
+
+    /**
+     * Start KM of the river
+     */
+    Double getKmStart();
+
+    /**
+     * End KM of the river
+     */
+    Double getKmEnd();
+
+    /**
+     * Returns the name of the river
+     */
+    String getName();
+
+    /**
+     * Returns the name of the WST unit
+     */
+    String getWstUnit();
+
+    /**
+     * Return all gauge info of the river
+     */
+    List<GaugeInfo> getGauges();
+
+    /**
+     * Returns the min q value of the river
+     */
+    Double getMinQ();
+
+    /**
+     * Returns the max q value of the river
+     */
+    Double getMaxQ();
+
+    /**
+     * Returns the official number of the river
+     */
+    Long getOfficialNumber();
+}
+
+
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/StringOptionsData.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/StringOptionsData.java	Fri Sep 28 12:15:40 2012 +0200
@@ -17,7 +17,7 @@
 
     public StringOptionsData(String label, String desc, DataItem[] opts) {
         this.label       = label;
-        this.description = description;
+        this.description = desc;
         this.opts        = opts;
     }
 
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/StringProperty.java	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/StringProperty.java	Fri Sep 28 12:15:40 2012 +0200
@@ -44,5 +44,6 @@
         }
         return clone;
     }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
 
-}
--- a/flys-client/src/main/webapp/FLYS.css	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/webapp/FLYS.css	Fri Sep 28 12:15:40 2012 +0200
@@ -171,3 +171,16 @@
 #authentication table {
     margin-bottom: 1em;
 }
+
+.riverinfopanel {
+    border: 3px solid #CFE1F1;
+    padding: 8px;
+    margin-top: 10px;
+    margin-left: 10px;
+    margin-bottom: 10px;
+    font-size: 1.3em;
+}
+
+.riverinfopanel .gwt-Label {
+    margin-right: 10px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/webapp/WEB-INF/features.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ftr:features xmlns:ftr="http://www.intevation.de/2012/flys/features">
+    <ftr:role name="flys_bfg">
+        <ftr:feature>module:winfo</ftr:feature>
+        <ftr:feature>module:minfo</ftr:feature>
+        <ftr:feature>module:new_map</ftr:feature>
+        <ftr:feature>module:new_chart</ftr:feature>
+        <ftr:feature>module:fixanalysis</ftr:feature>
+        <ftr:feature>river:Saar</ftr:feature>
+        <ftr:feature>river:Rhein</ftr:feature>
+        <ftr:feature>river:Mosel</ftr:feature>
+        <ftr:feature>river:Elbe</ftr:feature>
+    </ftr:role>
+    <ftr:role name="flys_wsa_koblenz">
+        <ftr:feature>module:winfo</ftr:feature>
+        <ftr:feature>module:minfo</ftr:feature>
+        <ftr:feature>module:new_map</ftr:feature>
+        <ftr:feature>module:new_chart</ftr:feature>
+        <ftr:feature>module:fixanalysis</ftr:feature>
+        <ftr:feature>river:Rhein</ftr:feature>
+        <ftr:feature>river:Mosel</ftr:feature>
+    </ftr:role>
+    <ftr:role name="flys_wsa_trier">
+        <ftr:feature>module:winfo</ftr:feature>
+        <ftr:feature>module:minfo</ftr:feature>
+        <ftr:feature>module:new_map</ftr:feature>
+        <ftr:feature>module:new_chart</ftr:feature>
+        <ftr:feature>module:fixanalysis</ftr:feature>
+        <ftr:feature>river:Saar</ftr:feature>
+        <ftr:feature>river:Mosel</ftr:feature>
+    </ftr:role>
+    <ftr:role name="flys_wsa_schweinfurt">
+        <ftr:feature>module:winfo</ftr:feature>
+        <ftr:feature>module:minfo</ftr:feature>
+        <ftr:feature>module:new_map</ftr:feature>
+        <ftr:feature>module:new_chart</ftr:feature>
+        <ftr:feature>module:fixanalysis</ftr:feature>
+        <ftr:feature>river:Saar</ftr:feature>
+        <ftr:feature>river:Mosel</ftr:feature>
+        <ftr:feature>river:Elbe</ftr:feature>
+    </ftr:role>
+    <ftr:role name="flys_user_extern">
+        <ftr:feature>module:winfo</ftr:feature>
+        <ftr:feature>module:minfo</ftr:feature>
+        <ftr:feature>river:Elbe</ftr:feature>
+    </ftr:role>
+</ftr:features>
+
+
+
+
--- a/flys-client/src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/webapp/WEB-INF/stylesheets/fixoverview2html.xsl	Fri Sep 28 12:15:40 2012 +0200
@@ -9,6 +9,79 @@
   <xsl:param name="render-checkboxes" select="true()"/>
   <xsl:param name="callback"/>
 
+  <xsl:param name="locale">de</xsl:param>
+
+  <xsl:decimal-format name="de" decimal-separator=',' grouping-separator='.'/>
+  <xsl:decimal-format name="en" decimal-separator='.' grouping-separator=','/>
+
+  <!-- XXX: This kind of i18n is cheesy.
+            It should be better done in an external resource. -->
+
+  <xsl:variable name="km-pattern">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">0,##</xsl:when>
+      <xsl:otherwise>0.##</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-event">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Ereignis</xsl:when>
+      <xsl:otherwise>Event</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-legend">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Legende</xsl:when>
+      <xsl:otherwise>Caption</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-color">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Farbe</xsl:when>
+      <xsl:otherwise>Color</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-meaning">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">Bedeutung</xsl:when>
+      <xsl:otherwise>Meaning</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-around-mnq">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">um MNQ</xsl:when>
+      <xsl:otherwise>around MNQ</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-around-mq">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">um MQ</xsl:when>
+      <xsl:otherwise>around MQ</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-around-mhq">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">um MHQ</xsl:when>
+      <xsl:otherwise>around MHQ</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="i18n-above-hq5">
+    <xsl:choose>
+      <xsl:when test="$locale = 'de'">über HQ5</xsl:when>
+      <xsl:otherwise>above HQ5</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- TODO: Format dates according locale. -->
+
   <xsl:template match="@*" mode="min">
     <xsl:if test="position() = 1">
       <xsl:value-of select="number(.)"/>
@@ -21,7 +94,7 @@
     </xsl:if>
   </xsl:template>
 
-  <xsl:variable name="events-min">
+  <xsl:variable name="global-min">
     <xsl:choose>
       <xsl:when test="count(/fixings/events/event/sector) &gt; 0">
         <xsl:apply-templates mode="min" select="/fixings/events/event/sector/@from">
@@ -34,7 +107,7 @@
     </xsl:choose>
   </xsl:variable>
 
-  <xsl:variable name="events-max">
+  <xsl:variable name="global-max">
     <xsl:choose>
       <xsl:when test="count(/fixings/events/event/sector) &gt; 0">
         <xsl:apply-templates mode="max" select="/fixings/events/event/sector/@to">
@@ -49,48 +122,105 @@
 
   <xsl:template name="percent">
     <xsl:param name="sector"/>
-    <xsl:variable name="rfrom" select="number($events-min)"/>
-    <xsl:variable name="rto" select="number($events-max)"/>
-    <xsl:variable name="rlength" select="$rto - $rfrom"/>
 
-    <xsl:variable name="sfrom" select="number($sector/@from)"/>
-    <xsl:variable name="sto" select="number($sector/@to)"/>
-    <xsl:variable name="slength" select="$sto - $sfrom"/>
-    <xsl:value-of select="100.0 * ($slength div $rlength)"/>
+    <xsl:variable name="start">
+      <xsl:choose>
+        <xsl:when test="number($sector/@from) &lt; $global-min">
+          <xsl:value-of select="$global-min"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="number($sector/@from)"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="end">
+      <xsl:choose>
+        <xsl:when test="number($sector/@to) &gt; $global-max">
+          <xsl:value-of select="$global-max"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="number($sector/@to)"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$end &lt; $start">
+        <xsl:value-of select="number(0)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="100.0 * (($end - $start) div ($global-max - $global-min))"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="emit-gap-gauge">
+    <xsl:param name="gauge"/>
+    <xsl:call-template name="internal-emit-gap">
+      <xsl:with-param name="sector" select="$gauge"/>
+      <xsl:with-param name="preds" select="$gauge/preceding-sibling::gauge"/>
+    </xsl:call-template>
   </xsl:template>
 
   <xsl:template name="emit-gap">
     <xsl:param name="sector"/>
-    <xsl:variable name="preds" select="$sector/preceding-sibling::sector"/>
-    <xsl:variable name="num-preds" select="count($preds)"/>
-    <xsl:variable name="glength">
+    <xsl:call-template name="internal-emit-gap">
+      <xsl:with-param name="sector" select="$sector"/>
+      <xsl:with-param name="preds" select="$sector/preceding-sibling::sector"/>
+    </xsl:call-template>
+  </xsl:template>
+
+  <xsl:template name="internal-emit-gap">
+    <xsl:param name="sector"/>
+    <xsl:param name="preds"/>
+
+    <xsl:variable name="start">
       <xsl:choose>
-        <xsl:when test="$num-preds &lt; 1">
-          <xsl:variable name="rfrom" select="number($events-min)"/>
-          <xsl:value-of select="number($sector/@from) - $rfrom"/>
+        <xsl:when test="number($sector/@from) &lt; $global-min">
+          <xsl:value-of select="$global-min"/>
         </xsl:when>
         <xsl:otherwise>
-          <xsl:variable name="bend" select="number($preds[last()]/@to)"/>
-          <xsl:value-of select="number($sector/@from) - $bend"/>
+          <xsl:value-of select="$sector/@from"/>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:variable>
-    <xsl:choose>
-      <xsl:when test="number($glength) &lt; 0.05 "/>
-      <xsl:otherwise>
-        <div>
-          <xsl:attribute name="style">
-            <xsl:text>width:</xsl:text>
-              <xsl:variable name="rfrom" select="number($events-min)"/>
-              <xsl:variable name="rto" select="number($events-max)"/>
-              <xsl:variable name="rlength" select="$rto - $rfrom"/>
-              <xsl:value-of select="100.0 * ($glength div $rlength)"/>
-            <xsl:text>%;float:left</xsl:text>
-          </xsl:attribute>
-          <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
-        </div>
-      </xsl:otherwise>
-    </xsl:choose>
+
+    <xsl:if test="$start &lt; $global-max">
+      <xsl:variable name="num-preds" select="count($preds)"/>
+      <xsl:variable name="prev-end">
+        <xsl:choose>
+          <xsl:when test="count($preds) &lt; 1">
+            <xsl:value-of select="$global-min"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:variable name="prev-to" select="number($preds[last()]/@to)"/>
+            <xsl:choose>
+              <xsl:when test="$prev-to &lt; $global-min">
+                <xsl:value-of select="$global-min"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="$prev-to"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:if test="$prev-end &lt; $global-max">
+        <xsl:variable name="gap-len" select="$start - $prev-end"/>
+        <xsl:if test="$gap-len &gt; 0.005">
+          <div>
+            <xsl:attribute name="style">
+              <xsl:text>width:</xsl:text>
+                <xsl:value-of select="100.0 * ($gap-len div ($global-max - $global-min))"/>
+              <xsl:text>%;float:left</xsl:text>
+            </xsl:attribute>
+            <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
+          </div>
+        </xsl:if>
+      </xsl:if>
+    </xsl:if>
   </xsl:template>
 
   <xsl:template match="sector" mode="sectors">
@@ -116,14 +246,14 @@
       </xsl:attribute>
       <xsl:attribute name="title">
         <xsl:text>km </xsl:text>
-        <xsl:value-of select="@from"/>
+        <xsl:value-of select="format-number(@from, $km-pattern, $locale)"/>
         <xsl:text> - </xsl:text>
-        <xsl:value-of select="@to"/>
+        <xsl:value-of select="format-number(@to, $km-pattern, $locale)"/>
         <xsl:choose>
-          <xsl:when test="@class = '0'"> / Q &#8712; [0, (MNQ+MQ)/2) </xsl:when>
-          <xsl:when test="@class = '1'"> / Q &#8712; [(MNQ+MQ)/2, (MQ+MHQ)/2)</xsl:when>
-          <xsl:when test="@class = '2'"> / Q &#8712; [(MQ+MHQ)/2, HQ5)</xsl:when>
-          <xsl:when test="@class = '3'"> / Q &#8712; [HQ5, &#8734;)</xsl:when>
+          <xsl:when test="@class = '0'"> / Q <xsl:value-of select="$i18n-around-mnq"/></xsl:when>
+          <xsl:when test="@class = '1'"> / Q <xsl:value-of select="$i18n-around-mq"/></xsl:when>
+          <xsl:when test="@class = '2'"> / Q <xsl:value-of select="$i18n-around-mhq"/></xsl:when>
+          <xsl:when test="@class = '3'"> / Q <xsl:value-of select="$i18n-above-hq5"/></xsl:when>
         </xsl:choose>
       </xsl:attribute>
       <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
@@ -147,6 +277,59 @@
     </tr>
   </xsl:template>
 
+  <xsl:template match="gauge" mode="gauges">
+    <xsl:call-template name="emit-gap-gauge">
+      <xsl:with-param name="gauge" select="."/>
+    </xsl:call-template>
+
+    <div>
+      <xsl:attribute name="style">
+        <xsl:text>overflow:hidden;background:</xsl:text>
+        <xsl:choose>
+          <xsl:when test="(count(preceding::*) mod 2) = 0">#ada96e</xsl:when>
+          <xsl:otherwise>silver</xsl:otherwise>
+        </xsl:choose>
+        <xsl:text>;width:</xsl:text>
+        <xsl:call-template name="percent">
+          <xsl:with-param name="sector" select="."/>
+        </xsl:call-template>
+        <xsl:text>%</xsl:text>
+        <xsl:text>;float:left</xsl:text>
+      </xsl:attribute>
+
+      <xsl:attribute name="title">
+        <xsl:variable name="start">
+          <xsl:choose>
+            <xsl:when test="number(@from) &lt; $global-min">
+              <xsl:value-of select="$global-min"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="number(@from)"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+
+        <xsl:variable name="end">
+          <xsl:choose>
+            <xsl:when test="number(@to) &gt; $global-max">
+              <xsl:value-of select="$global-max"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="number(@to)"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+
+        <xsl:value-of select="@name"/>
+        <xsl:text>: km </xsl:text>
+        <xsl:value-of select="format-number($start, $km-pattern, $locale)"/>
+        <xsl:text> - </xsl:text>
+        <xsl:value-of select="format-number($end, $km-pattern, $locale)"/>
+      </xsl:attribute>
+      <nobr><xsl:value-of select="@name"/></nobr>
+    </div>
+  </xsl:template>
+
   <xsl:template match="events">
     <table width="97%" border="1" cellspacing="0" cellpadding="0"
            style="font-size: 10pt;font-family:Arial;Verdana,sans-serif">
@@ -161,8 +344,8 @@
         <xsl:if test="$render-checkboxes">
           <th>&#160;</th>
         </xsl:if>
-        <th>km <xsl:value-of select="$events-min"/> - <xsl:value-of select="$events-max"/></th>
-        <th>Ereignis</th>
+        <th><xsl:apply-templates mode="gauges" select="/fixings/gauges"/></th>
+        <th><xsl:value-of select="$i18n-event"/></th>
       </tr>
       <xsl:apply-templates/>
     </table>
@@ -170,9 +353,46 @@
 
   <xsl:template match="/">
     <xsl:apply-templates/>
+    <hr/>
+    <table border="1" cellspacing="0" cellpadding="0">
+      <caption><xsl:value-of select="$i18n-legend"/></caption>
+      <tr>
+        <th><xsl:value-of select="$i18n-color"/></th>
+        <th colspan="2"><xsl:value-of select="$i18n-meaning"/></th>
+      </tr>
+      <xsl:if test="count(/fixings/events/event/sector[@class = '0']) &gt; 0">
+      <tr>
+        <td style="background: green">&#160;</td>
+        <td><xsl:value-of select="$i18n-around-mnq"/></td>
+        <td>Q &#8712; [0, (MNQ+MQ)/2)</td>
+      </tr>
+      </xsl:if>
+      <xsl:if test="count(/fixings/events/event/sector[@class = '1']) &gt; 0">
+      <tr>
+        <td style="background: blue">&#160;</td>
+        <td><xsl:value-of select="$i18n-around-mq"/></td>
+        <td>Q &#8712; [(MNQ+MQ)/2, (MQ+MHQ)/2)</td>
+      </tr>
+      </xsl:if>
+      <xsl:if test="count(/fixings/events/event/sector[@class = '2']) &gt; 0">
+      <tr>
+        <td style="background: magenta">&#160;</td>
+        <td><xsl:value-of select="$i18n-around-mhq"/></td>
+        <td>Q &#8712; [(MQ+MHQ)/2, HQ5)</td>
+      </tr>
+      </xsl:if>
+      <xsl:if test="count(/fixings/events/event/sector[@class = '3']) &gt; 0">
+      <tr>
+        <td style="background: red">&#160;</td>
+        <td><xsl:value-of select="$i18n-above-hq5"/></td>
+        <td>Q &#8712; [HQ5, &#8734;)</td>
+      </tr>
+      </xsl:if>
+    </table>
   </xsl:template>
 
   <xsl:template match="text()"/>
   <xsl:template match="text()" mode="sectors"/>
+  <xsl:template match="text()" mode="gauges"/>
 
 </xsl:stylesheet>
--- a/flys-client/src/main/webapp/WEB-INF/web.xml	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/webapp/WEB-INF/web.xml	Fri Sep 28 12:15:40 2012 +0200
@@ -15,19 +15,22 @@
         <param-value>GGInA</param-value>
     </context-param>
 
-  <!-- Servlets -->
-  <servlet>
-    <servlet-name>BaseServlet</servlet-name>
-    <servlet-class>de.intevation.flys.client.server.BaseServlet</servlet-class>
+    <context-param>
+        <param-name>features-file</param-name>
+        <param-value>/WEB-INF/features.xml</param-value>
+    </context-param>
 
-    <init-param>
+    <context-param>
         <param-name>log4j-properties</param-name>
         <param-value>/WEB-INF/log4j.properties</param-value>
-    </init-param>
+    </context-param>
 
-    <load-on-startup>1</load-on-startup>
-  </servlet>
+    <listener>
+        <listener-class>de.intevation.flys.client.server.BaseServletContextListener</listener-class>
+    </listener>
 
+
+  <!-- Servlets -->
   <servlet>
     <servlet-name>user</servlet-name>
     <servlet-class>de.intevation.flys.client.server.UserServiceImpl</servlet-class>
@@ -89,6 +92,16 @@
   </servlet-mapping>
 
   <servlet>
+    <servlet-name>gaugeoverviewinfo</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.GaugeOverviewInfoServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>gaugeoverviewinfo</servlet-name>
+    <url-pattern>/flys/gaugeoverviewinfo</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
     <servlet-name>forward</servlet-name>
     <servlet-class>de.intevation.flys.client.server.StepForwardServiceImpl</servlet-class>
   </servlet>
@@ -484,6 +497,26 @@
   </servlet-mapping>
 
   <servlet>
+    <servlet-name>BedKMChart</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.BedKMChartServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>BedKMChart</servlet-name>
+    <url-pattern>/flys/bed-km-chart</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>BedloadKMChart</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.BedloadKMChartServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>BedloadKMChart</servlet-name>
+    <url-pattern>/flys/bedload-km-chart</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
     <servlet-name>login</servlet-name>
     <servlet-class>de.intevation.flys.client.server.LoginServlet</servlet-class>
   </servlet>
@@ -493,6 +526,16 @@
     <url-pattern>/flys/login</url-pattern>
   </servlet-mapping>
 
+  <servlet>
+    <servlet-name>modules</servlet-name>
+    <servlet-class>de.intevation.flys.client.server.ModuleServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>modules</servlet-name>
+    <url-pattern>/flys/modules</url-pattern>
+  </servlet-mapping>
+
   <filter>
     <filter-name>GGInAFilter</filter-name>
     <filter-class>de.intevation.flys.client.server.GGInAFilter</filter-class>
Binary file flys-client/src/main/webapp/images/logo-bfg.gif has changed
Binary file flys-client/src/main/webapp/images/logo-intevation.png has changed
--- a/flys-client/src/main/webapp/login.jsp	Fri Sep 28 12:14:36 2012 +0200
+++ b/flys-client/src/main/webapp/login.jsp	Fri Sep 28 12:15:40 2012 +0200
@@ -6,7 +6,7 @@
     </head>
 
     <body>
-        <form method="POST" action="/flys/login" id="authentication">
+        <form method="POST" action="<%= request.getContextPath() + "/flys/login" %>" id="authentication">
             <h1>FLYS Anmeldung</h1>
             <% String error = request.getParameter("error"); %>
             <% if (error != null) { %>

http://dive4elements.wald.intevation.org