changeset 9148:48d87af1243e

Unit testing flowdepthdevelopment added
author gernotbelger
date Tue, 12 Jun 2018 15:04:40 +0200
parents 28fe5e654495
children 5be112fba832
files gwt-client/src/test/java/test/AbstractModuleRunner.java gwt-client/src/test/java/test/BerechnungsartenTester.java gwt-client/src/test/java/test/ModuleRunner.java gwt-client/src/test/java/test/RunnerCreatorHelper.java gwt-client/src/test/java/test/SimpleRecommendation.java gwt-client/src/test/java/test/SinfoFlowdepthDevelopmentRunner.java gwt-client/src/test/java/test/SinfoFlowdepthMinMaxRunner.java gwt-client/src/test/java/test/SinfoFlowdepthRunner.java gwt-client/src/test/resources/sinfo/flowdepthdevelopment/sinfo_fte_01.csv gwt-client/src/test/resources/sinfo/flowdepthdevelopment/sinfo_fte_02.csv
diffstat 10 files changed, 942 insertions(+), 412 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/java/test/AbstractModuleRunner.java	Tue Jun 12 15:04:40 2018 +0200
@@ -0,0 +1,344 @@
+package test;
+
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
+import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
+import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
+import org.dive4elements.artifacts.httpclient.http.HttpClient;
+import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
+import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler;
+import org.dive4elements.artifacts.httpclient.utils.XMLUtils;
+import org.dive4elements.river.client.server.AdvanceServiceImpl;
+import org.dive4elements.river.client.server.ArtifactHelper;
+import org.dive4elements.river.client.server.CollectionHelper;
+import org.dive4elements.river.client.server.CreateCollectionServiceImpl;
+import org.dive4elements.river.client.server.FLYSArtifactCreator;
+import org.dive4elements.river.client.server.FeedServiceImpl;
+import org.dive4elements.river.client.server.auth.DefaultUser;
+import org.dive4elements.river.client.server.auth.User;
+import org.dive4elements.river.client.server.auth.UserClient;
+import org.dive4elements.river.client.shared.exceptions.ServerException;
+import org.dive4elements.river.client.shared.model.Artifact;
+import org.dive4elements.river.client.shared.model.Collection;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DefaultCollection;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.OutputMode;
+import org.dive4elements.river.client.shared.model.StringOptionsData;
+import org.junit.Assert;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import test.BerechnungsartenTester.CalcMode;
+import test.BerechnungsartenTester.FilenameMapper;
+import test.BerechnungsartenTester.River;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public abstract class AbstractModuleRunner {
+
+    public enum Infotype {
+        sinfo
+    }
+
+    private final String serverUrl = "http://localhost:8181";
+    private final String locale = "de";
+    private final HttpClient client;
+
+    private static final String exportFileDir = "D:" + File.separator;
+    private static final String IGNORE_ERSTELLDATUM = "# Datum der Erstellung";
+    private static final String IGNORE_FLYS_VERSION = "# FLYS-Version:";
+    private static final String IGNORE_BEARBEITER = "# Bearbeiter:";
+
+    private final String username;
+    private final String password;
+    private final Infotype infotype;
+    private final String userUuid;
+    private Collection collection;
+    private Artifact artifact;
+    private final FilenameMapper fileName;
+
+    // common attributes
+    private final CalcMode calcMode;
+    private final double from;
+    private final double to;
+    private final River river;
+
+    public AbstractModuleRunner(final String username, final String password, final Infotype infotype, final CalcMode sinfoCalcFlowDepth,
+            final FilenameMapper helloWorldFile, final double from, final double to, final River beispielfluss) throws ConnectionException, ServerException {
+        // common attributes (evtl. doch in subklassen, evtl. Zwischenhierarchiestufe einführen
+
+        this.calcMode = sinfoCalcFlowDepth;
+        this.river = beispielfluss;
+        this.from = from;
+        this.to = to;
+
+        this.username = username;
+        this.password = password;
+        this.infotype = infotype;
+        this.fileName = helloWorldFile;
+
+        // init
+        this.client = new HttpClientImpl(this.serverUrl, this.locale);
+        this.userUuid = makeUserUuid();
+        this.collection = getCollection();
+        this.artifact = getArtifact();
+    }
+
+    private String makeUserUuid() throws ConnectionException {
+        final User user = new DefaultUser(this.username, this.password, null, false, new ArrayList<String>(), new ArrayList<String>());
+        final UserClient userClient = new UserClient(this.serverUrl);
+        Element userElement;
+
+        userElement = userClient.findUser(user);
+        return userElement.getAttributeNS(ArtifactNamespaceContext.NAMESPACE_URI, "uuid");
+
+    }
+
+    protected final Artifact getArtifact() throws ServerException, ConnectionException {
+        if (this.artifact == null) {
+            this.artifact = ArtifactHelper.createArtifact(this.serverUrl, this.locale, this.infotype.name(), null);
+            setCollection(CollectionHelper.addArtifact(getCollection(), this.artifact, this.serverUrl, this.locale)); // wichtig; sorgt für Persistenz
+        }
+        return this.artifact;
+    }
+
+    protected Collection getCollection() throws ConnectionException {
+
+        if (this.collection == null) {
+            // lazy-Loading
+            final Document create = ClientProtocolUtils.newCreateCollectionDocument(null);
+            final Document doc = (Document) this.client.createCollection(create, this.userUuid, new DocumentResponseHandler());
+            final String uuid = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE);
+            final String ttlStr = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_TTL, ArtifactNamespaceContext.INSTANCE);
+            this.collection = new DefaultCollection(uuid, Long.valueOf(ttlStr), uuid);
+        }
+        return this.collection;
+
+    }
+
+    private final void setCollection(final Collection collection) {
+        this.collection = collection;
+    }
+
+    private final void setArtifact(final Artifact artifact) {
+        this.artifact = artifact;
+    }
+
+    public abstract void runTest(final boolean exportToFile) throws ConnectionException, ServerException, IOException;
+
+    protected final void describeCollection() throws ConnectionException {
+
+        final String uuid = getCollection().identifier();
+        final Document describe = ClientProtocolUtils.newDescribeCollectionDocument(uuid);
+        final Document response = (Document) this.client.doCollectionAction(describe, uuid, new DocumentResponseHandler());
+        final Collection c = CollectionHelper.parseCollection(response);
+        setCollection(c);
+
+    }
+
+    protected final void feedAndGo(final Data[] data, final int reachableStateIndex) throws ConnectionException, ServerException {
+        feed(data);
+        advance(getReachableStateByIndex(getArtifact(), reachableStateIndex)); // reachablestate könnte auch String sein.
+
+    }
+
+    private final String getReachableStateByIndex(final Artifact artifact, final int index) {
+
+        final String[] states = artifact.getArtifactDescription().getReachableStates();
+        if (states != null) {
+            if (states.length > index) {
+                return states[index];
+            } else {
+                return states[0];
+            }
+        } else {
+            return "";
+        }
+    }
+
+    private final void feed(final Data[] data) throws ServerException, ConnectionException {
+        final Document feed = ClientProtocolUtils.newFeedDocument(getArtifact().getUuid(), getArtifact().getHash(), createKVP(data));
+        final Document description = (Document) this.client.feed(
+                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), feed,
+                new DocumentResponseHandler());
+
+        final String result = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
+
+        if (result == null || !result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
+            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
+        } else if (result != null && result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
+            final String msg = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT_MSG, ArtifactNamespaceContext.INSTANCE);
+            throw new ServerException(msg);
+        }
+    }
+
+    protected final Data[] extractPairData(final List<String> pairIds, final String dataName) {
+        final Data[] data = new Data[pairIds.size()];
+        int i = 0;
+        for (final String pairId : pairIds) {
+            final Data pair = new StringOptionsData(dataName, dataName, new DataItem[] { new DefaultDataItem(pairId, pairId, pairId) });
+            data[i] = pair;
+            i++;
+        }
+        return data;
+    }
+
+    private final String[][] createKVP(final Data[] data) {
+        if (data != null) {
+            final String[][] kvp = new String[data.length][];
+
+            int i = 0;
+
+            for (final Data d : data) {
+                final String key = d.getLabel();
+                final String value = d.getStringValue();
+
+                kvp[i++] = new String[] { key, value };
+            }
+
+            return kvp;
+        }
+        return null;
+    }
+
+    private final void advance(final String target) throws ConnectionException, ServerException {
+        final Document advance = ClientProtocolUtils.newAdvanceDocument(getArtifact().getUuid(), getArtifact().getHash(), target);
+        final Document description = (Document) this.client.advance(
+                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), advance,
+                new DocumentResponseHandler());
+
+        if (description == null) {
+            throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT);
+        }
+
+        final String result = XMLUtils.xpathString(description, AdvanceServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
+
+        if (result == null || !result.equals(AdvanceServiceImpl.OPERATION_FAILURE)) {
+            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
+        }
+    }
+
+    /// ExportServiceImpl
+    protected final void assertAndWriteToFile(final String mode, final boolean exportToFile) throws IOException {
+
+        final String type = "csv";
+
+        final String enc = "windows-1252";// req.getParameter("encoding");
+
+        final URL expectedResource = getClass().getResource(this.fileName.getFilename());
+        final Document attr = null;
+        final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
+
+        final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode);
+
+        final String actual = deleteErstelldatum(IOUtils.toString(response, "UTF-8"));
+
+        final String expected = deleteErstelldatum(FileUtils.readFileToString(new File(expectedResource.getFile()), enc));
+
+        // if (!actual.equals(expected)) {
+        if (exportToFile) {
+            doGetWriteToDisk(mode); // TODO: WENN der Test negativ ausfällt, Datei abspeichern -> Diskussion
+        }
+
+        Assert.assertEquals(expected, actual);
+    }
+
+    private final String deleteErstelldatum(final String input) {
+        String result = "";
+        final String[] lines = input.split(System.lineSeparator());
+        for (final String line : lines) {
+            if (!line.contains(AbstractModuleRunner.IGNORE_ERSTELLDATUM) && !line.contains(AbstractModuleRunner.IGNORE_FLYS_VERSION)
+                    && !line.contains(AbstractModuleRunner.IGNORE_BEARBEITER)) {
+                result = result + line + System.lineSeparator();
+            }
+        }
+        return result;
+    }
+
+    public final void doGetWriteToDisk(final String mode) throws FileNotFoundException, IOException {
+
+        final String name = mode;
+        final String type = "csv";
+
+        final String fn = name + System.currentTimeMillis() + "." + type;
+        final String enc = "windows-1252";
+
+        final String filepath = exportFileDir + fn;
+
+        final Document attr = null;
+        final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
+
+        final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode);
+        final InputStreamReader in = new InputStreamReader(response, "UTF-8");
+
+        IOUtils.copy(in, new FileOutputStream(filepath), enc);
+
+    }
+
+    protected final void selectCalcMode() throws ConnectionException, ServerException {
+
+        /* Select CalcMode */
+        final String calcmodeStr = this.calcMode.name();
+        final Data dataCalcMode = new StringOptionsData("calculation_mode", "calculation_mode",
+                new DataItem[] { new DefaultDataItem(calcmodeStr, calcmodeStr, calcmodeStr) });
+        feedAndGo(new Data[] { dataCalcMode }, 0);
+    }
+
+    protected final void selectRange() throws ConnectionException, ServerException {
+        final String fromStr = String.valueOf(this.from);
+        final String toStr = String.valueOf(this.to);
+        final Data dataFrom = new StringOptionsData("ld_from", "ld_from", new DataItem[] { new DefaultDataItem(fromStr, fromStr, fromStr) });
+        final Data dataTo = new StringOptionsData("ld_to", "ld_to", new DataItem[] { new DefaultDataItem(toStr, toStr, toStr) });
+        final Data[] rangeFromToDetermined = new Data[] { dataFrom, dataTo };
+
+        feedAndGo(rangeFromToDetermined, 0);
+    }
+
+    protected final void selectRiver() throws ConnectionException, ServerException {
+        final String riverStr = this.river.name();
+        final Data data = new StringOptionsData("river", "river", new DataItem[] { new DefaultDataItem(riverStr, riverStr, riverStr) });
+        feedAndGo(new Data[] { data }, 0);
+    }
+
+    protected final void export(final boolean exportToFile) throws IOException, ServerException {
+        final OutputMode[] modes = getArtifact().getArtifactDescription().getOutputModes();
+        if (modes != null) {
+            for (final OutputMode mode : modes) {
+                if (mode.getDescription().contains("_export"))
+                    assertAndWriteToFile(mode.getName(), exportToFile);
+            }
+        }
+    }
+
+    protected final String getRecommendationPairString(final SimpleRecommendation rec1, final SimpleRecommendation rec2)
+            throws ConnectionException, ServerException {
+
+        return rec1.getRecommendationPairString(rec2, getCollection(), this.serverUrl, this.locale);
+    }
+
+}
--- a/gwt-client/src/test/java/test/BerechnungsartenTester.java	Tue Jun 12 10:40:33 2018 +0200
+++ b/gwt-client/src/test/java/test/BerechnungsartenTester.java	Tue Jun 12 15:04:40 2018 +0200
@@ -28,7 +28,7 @@
     };
 
     public static enum River {
-        Beispielfluss, Rhein
+        Beispielfluss, Rhein, Elbe
     };
 
     public static enum FilenameMapper {
@@ -36,8 +36,11 @@
         HELLO_WORLD_FILE("/sinfo/flowdepthminmax/sinfo_flowdepthminmax_export.csv"), //
 
         // Schäfer-Tests:
-        RHEIN_1_FILE("/sinfo/flowdepth/sinfo_ft_01.csv"), //
-        RHEIN_3_FILE("/sinfo/flowdepth/sinfo_ft_03.csv"); //
+        FT_RHEIN_1_FILE("/sinfo/flowdepth/sinfo_ft_01.csv"), //
+        FT_RHEIN_3_FILE("/sinfo/flowdepth/sinfo_ft_03.csv"), //
+
+        FTE_ELBE_FILE("/sinfo/flowdepthdevelopment/sinfo_fte_01.csv"), //
+        FTE_RHEIN_FILE("/sinfo/flowdepthdevelopment/sinfo_fte_02.csv");
 
         private final String filename;
 
@@ -54,6 +57,7 @@
         return null;
     }
 
+    /* FLOWDEPTH MIN MAX */
     @Test
     public void testHelloWorld() throws ServerException, IOException {
 
@@ -62,11 +66,12 @@
                 .runTest(overrideFileExport() != null ? overrideFileExport() : true);
     }
 
+    /* FLOWDEPTH */
     @Test
-    public void testRhein1() throws ConnectionException, ServerException, IOException {
+    public void testRhein1FT() throws ConnectionException, ServerException, IOException {
 
         RunnerCreatorHelper
-                .createSinfoFlowdepthTest(FilenameMapper.RHEIN_1_FILE, 350, 380, River.Rhein, false,
+                .createSinfoFlowdepthTest(FilenameMapper.FT_RHEIN_1_FILE, 350, 380, River.Rhein, false,
                         new SimpleRecommendation("staticwqkms", "additionals-wstv-0-415", "longitudinal_section"),
                         new SimpleRecommendation("bedheight", "bedheight-soundings-79-2004-DGM-2004_Epoche_NHN", "longitudinal_section"))
                 .runTest(overrideFileExport() != null ? overrideFileExport() : true);
@@ -74,12 +79,48 @@
     }
 
     @Test
-    public void testRhein3() throws ConnectionException, ServerException, IOException {
+    public void testRhein3FT() throws ConnectionException, ServerException, IOException {
         RunnerCreatorHelper
-                .createSinfoFlowdepthTest(FilenameMapper.RHEIN_3_FILE, 655, 675, River.Rhein, true,
+                .createSinfoFlowdepthTest(FilenameMapper.FT_RHEIN_3_FILE, 655, 675, River.Rhein, true,
                         new SimpleRecommendation("staticwqkms", "fixations-wstv-0-323", "longitudinal_section"),
                         new SimpleRecommendation("bedheight", "bedheight-soundings-92-2004-NIEDERRHEIN_QP-2004_Epoche_NHN", "longitudinal_section"))
                 .runTest(overrideFileExport() != null ? overrideFileExport() : true);
     }
 
+    /* FLOWDEPTH DEVELOPMENT */
+
+    @Test
+    public void testElbeFTE() throws ConnectionException, ServerException, IOException {
+        RunnerCreatorHelper.createSinfoFlowdepthDevelopmentTest(FilenameMapper.FTE_ELBE_FILE, 210, 230, River.Elbe,
+                // current
+                new SimpleRecommendation("staticwqkms", "fixations-wstv-0-196", "longitudinal_section", "05.05.2008"), // sicher
+                new SimpleRecommendation("bedheight", "bedheight-soundings-66-2008-FP-QP-2008",
+                        // "bedheight-single-66-2008-MW-FP-QP-2008",
+                        "longitudinal_section"),
+
+                // historical
+                new SimpleRecommendation("staticwqkms", "fixations-wstv-0-186", "longitudinal_section", "18.03.1997"), // sicher
+                new SimpleRecommendation("bedheight", "bedheight-soundings-70-1995-QP-1995",
+                        // "bedheight-single-70-1995-MW-QP-1995",
+                        "longitudinal_section"))
+                .runTest(overrideFileExport() != null ? overrideFileExport() : true);
+    }
+
+    @Test
+    public void testRheinFTE() throws ConnectionException, ServerException, IOException {
+        RunnerCreatorHelper.createSinfoFlowdepthDevelopmentTest(FilenameMapper.FTE_RHEIN_FILE, 655, 665, River.Rhein,
+                // current
+                new SimpleRecommendation("staticwqkms", "fixations-wstv-0-372", "longitudinal_section", "23.09.2009-1"), // sicher
+                new SimpleRecommendation("bedheight", "bedheight-soundings-80-2008-FP-2008_NHN",
+                        // "bedheight-single....",
+                        "longitudinal_section"),
+
+                // historical
+                new SimpleRecommendation("staticwqkms", "fixations-wstv-0-374", "longitudinal_section", "18.03.1997"), // sicher
+                new SimpleRecommendation("bedheight", "bedheight-single-89-1991-MW-NIEDERRHEIN_QP-1991_Epoche_NHN",
+                        // "bedheight-soundings-89-1991-NIEDERRHEIN_QP-1991_Epoche_NHN",
+                        "longitudinal_section"))
+                .runTest(overrideFileExport() != null ? overrideFileExport() : true);
+    }
+
 }
\ No newline at end of file
--- a/gwt-client/src/test/java/test/ModuleRunner.java	Tue Jun 12 10:40:33 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +0,0 @@
-package test;
-
-/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
-import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
-import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
-import org.dive4elements.artifacts.httpclient.http.HttpClient;
-import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
-import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler;
-import org.dive4elements.artifacts.httpclient.utils.XMLUtils;
-import org.dive4elements.river.client.client.ui.NilDatacageTwinPanelInfo;
-import org.dive4elements.river.client.client.ui.RecommandationUtils;
-import org.dive4elements.river.client.server.AdvanceServiceImpl;
-import org.dive4elements.river.client.server.ArtifactHelper;
-import org.dive4elements.river.client.server.CollectionHelper;
-import org.dive4elements.river.client.server.CreateCollectionServiceImpl;
-import org.dive4elements.river.client.server.FLYSArtifactCreator;
-import org.dive4elements.river.client.server.FeedServiceImpl;
-import org.dive4elements.river.client.server.LoadArtifactServiceImpl;
-import org.dive4elements.river.client.server.auth.DefaultUser;
-import org.dive4elements.river.client.server.auth.User;
-import org.dive4elements.river.client.server.auth.UserClient;
-import org.dive4elements.river.client.shared.exceptions.ServerException;
-import org.dive4elements.river.client.shared.model.Artifact;
-import org.dive4elements.river.client.shared.model.Collection;
-import org.dive4elements.river.client.shared.model.Data;
-import org.dive4elements.river.client.shared.model.DataItem;
-import org.dive4elements.river.client.shared.model.DefaultCollection;
-import org.dive4elements.river.client.shared.model.DefaultDataItem;
-import org.dive4elements.river.client.shared.model.OutputMode;
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.dive4elements.river.client.shared.model.StringOptionsData;
-import org.junit.Assert;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import test.BerechnungsartenTester.CalcMode;
-import test.BerechnungsartenTester.FilenameMapper;
-import test.BerechnungsartenTester.River;
-
-/**
- * @author Domenico Nardi Tironi
- *
- */
-public abstract class ModuleRunner {
-
-    public enum Infotype {
-        sinfo
-    }
-
-    private final String serverUrl = "http://localhost:8181";
-    private final String locale = "de";
-    private final HttpClient client;
-
-    private static final String exportFileDir = "D:" + File.separator;
-    private static final String IGNORE_ERSTELLDATUM = "# Datum der Erstellung";
-    private static final String IGNORE_FLYS_VERSION = "# FLYS-Version:";
-    private static final String IGNORE_BEARBEITER = "# Bearbeiter:";
-
-    private final String username;
-    private final String password;
-    private final Infotype infotype;
-    private final String userUuid;
-    private Collection collection;
-    private Artifact artifact;
-    private final FilenameMapper fileName;
-
-    // common attributes
-    private final CalcMode calcMode;
-    private final double from;
-    private final double to;
-    private final River river;
-
-    private final List<String> pairIds = new ArrayList<String>(); // TODO in Subklassen
-
-    public ModuleRunner(final String username, final String password, final Infotype infotype, final CalcMode sinfoCalcFlowDepth,
-            final FilenameMapper helloWorldFile, final double from, final double to, final River beispielfluss) throws ConnectionException, ServerException {
-        // common attributes (evtl. doch in subklassen, evtl. Zwischenhierarchiestufe einführen
-
-        this.calcMode = sinfoCalcFlowDepth;
-        this.river = beispielfluss;
-        this.from = from;
-        this.to = to;
-
-        this.username = username;
-        this.password = password;
-        this.infotype = infotype;
-        this.fileName = helloWorldFile;
-
-        // init
-        this.client = new HttpClientImpl(this.serverUrl, this.locale);
-        this.userUuid = makeUserUuid();
-        this.collection = getCollection();
-        this.artifact = getArtifact();
-    }
-
-    private String makeUserUuid() throws ConnectionException {
-        final User user = new DefaultUser(this.username, this.password, null, false, new ArrayList<String>(), new ArrayList<String>());
-        final UserClient userClient = new UserClient(this.serverUrl);
-        Element userElement;
-
-        userElement = userClient.findUser(user);
-        return userElement.getAttributeNS(ArtifactNamespaceContext.NAMESPACE_URI, "uuid");
-
-    }
-
-    protected final Artifact getArtifact() throws ServerException, ConnectionException {
-        if (this.artifact == null) {
-            this.artifact = ArtifactHelper.createArtifact(this.serverUrl, this.locale, this.infotype.name(), null);
-            setCollection(CollectionHelper.addArtifact(getCollection(), this.artifact, this.serverUrl, this.locale)); // wichtig; sorgt für Persistenz
-        }
-        return this.artifact;
-    }
-
-    private Collection getCollection() throws ConnectionException {
-
-        if (this.collection == null) {
-            // lazy-Loading
-            final Document create = ClientProtocolUtils.newCreateCollectionDocument(null);
-            final Document doc = (Document) this.client.createCollection(create, this.userUuid, new DocumentResponseHandler());
-            final String uuid = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE);
-            final String ttlStr = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_TTL, ArtifactNamespaceContext.INSTANCE);
-            this.collection = new DefaultCollection(uuid, Long.valueOf(ttlStr), uuid);
-        }
-        return this.collection;
-
-    }
-
-    private final void setCollection(final Collection collection) {
-        this.collection = collection;
-    }
-
-    private final void setArtifact(final Artifact artifact) {
-        this.artifact = artifact;
-    }
-
-    public abstract void runTest(final boolean exportToFile) throws ConnectionException, ServerException, IOException;
-
-    protected final void describeCollection() throws ConnectionException {
-
-        final String uuid = getCollection().identifier();
-        final Document describe = ClientProtocolUtils.newDescribeCollectionDocument(uuid);
-        final Document response = (Document) this.client.doCollectionAction(describe, uuid, new DocumentResponseHandler());
-        final Collection c = CollectionHelper.parseCollection(response);
-        setCollection(c);
-
-    }
-
-    protected final void feedAndGo(final Data[] data, final int reachableStateIndex) throws ConnectionException, ServerException {
-        feed(data);
-        advance(getReachableStateByIndex(getArtifact(), reachableStateIndex)); // reachablestate könnte auch String sein.
-
-    }
-
-    private final String getReachableStateByIndex(final Artifact artifact, final int index) {
-
-        final String[] states = artifact.getArtifactDescription().getReachableStates();
-        if (states != null) {
-            if (states.length > index) {
-                return states[index];
-            } else {
-                return states[0];
-            }
-        } else {
-            return "";
-        }
-    }
-
-    private final void feed(final Data[] data) throws ServerException, ConnectionException {
-        final Document feed = ClientProtocolUtils.newFeedDocument(getArtifact().getUuid(), getArtifact().getHash(), createKVP(data));
-        final Document description = (Document) this.client.feed(
-                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), feed,
-                new DocumentResponseHandler());
-
-        final String result = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
-
-        if (result == null || !result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
-            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
-        } else if (result != null && result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
-            final String msg = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT_MSG, ArtifactNamespaceContext.INSTANCE);
-            throw new ServerException(msg);
-        }
-    }
-
-    private final String[][] createKVP(final Data[] data) {
-        if (data != null) {
-            final String[][] kvp = new String[data.length][];
-
-            int i = 0;
-
-            for (final Data d : data) {
-                // final DataItem[] items = d.getItems();
-                final String key = d.getLabel();
-                final String value = d.getStringValue();
-
-                kvp[i++] = new String[] { key, value };
-            }
-
-            return kvp;
-        }
-        return null;
-    }
-
-    private final void advance(final String target) throws ConnectionException, ServerException {
-        final Document advance = ClientProtocolUtils.newAdvanceDocument(getArtifact().getUuid(), getArtifact().getHash(), target);
-        final Document description = (Document) this.client.advance(
-                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), advance,
-                new DocumentResponseHandler());
-
-        if (description == null) {
-            throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT);
-        }
-
-        final String result = XMLUtils.xpathString(description, AdvanceServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
-
-        if (result == null || !result.equals(AdvanceServiceImpl.OPERATION_FAILURE)) {
-            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
-        }
-    }
-
-    protected final Artifact[] loadMany(final Recommendation[] recoms, final String factory) throws ServerException, ConnectionException {
-        final ArrayList<Artifact> artifacts = new ArrayList<Artifact>();
-        final HashMap<Recommendation, Artifact> cloneMap = new HashMap<Recommendation, Artifact>();
-
-        for (final Recommendation recom : recoms) {
-
-            final Artifact prevClone = cloneMap.get(recom);
-            if (prevClone != null) {
-
-                artifacts.add(prevClone);
-            } else {
-                // Not already cloned.
-                final String realFactory = factory != null ? factory : recom.getFactory();
-
-                final Artifact clone = ArtifactHelper.createArtifact(this.serverUrl, this.locale, realFactory, recom);
-
-                if (clone != null) {
-                    final Collection c = CollectionHelper.addArtifact(getCollection(), clone, this.serverUrl, this.locale);
-
-                    if (c != null) {
-                        artifacts.add(clone);
-                        // Remember we cloned a recommendation like this.
-                        cloneMap.put(recom, clone);
-                    } else {
-                        throw new ServerException(LoadArtifactServiceImpl.ERROR_LOAD_ARTIFACT);
-                    }
-                }
-            }
-        }
-        return artifacts.toArray(new Artifact[artifacts.size()]);
-
-    }
-
-    /// ExportServiceImpl
-    protected final void doGet(final String mode, final boolean exportToFile) throws IOException {
-
-        final String type = "csv";
-
-        final String enc = "windows-1252";// req.getParameter("encoding");
-
-        final URL expectedResource = getClass().getResource(this.fileName.getFilename());
-        final Document attr = null;
-        final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
-
-        final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode);
-
-        final String actual = deleteErstelldatum(IOUtils.toString(response, "UTF-8"));
-
-        final String expected = deleteErstelldatum(FileUtils.readFileToString(new File(expectedResource.getFile()), enc));
-
-        // if (!actual.equals(expected)) {
-        if (exportToFile) {
-            doGetWriteToDisk(mode); // TODO: WENN der Test negativ ausfällt, Datei abspeichern -> Diskussion
-        }
-
-        Assert.assertEquals(expected, actual);
-    }
-
-    private final String deleteErstelldatum(final String input) {
-        String result = "";
-        final String[] lines = input.split(System.lineSeparator());
-        for (final String line : lines) {
-            if (!line.contains(ModuleRunner.IGNORE_ERSTELLDATUM) && !line.contains(ModuleRunner.IGNORE_FLYS_VERSION)
-                    && !line.contains(ModuleRunner.IGNORE_BEARBEITER)) {
-                result = result + line + System.lineSeparator();
-            }
-        }
-        return result;
-    }
-
-    public final void doGetWriteToDisk(final String mode) throws FileNotFoundException, IOException {
-
-        final String name = mode;
-        final String type = "csv";
-
-        final String fn = name + System.currentTimeMillis() + "." + type;
-        final String enc = "windows-1252";
-
-        final String filepath = exportFileDir + fn;
-
-        final Document attr = null;
-        final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
-
-        final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode);
-        final InputStreamReader in = new InputStreamReader(response, "UTF-8");
-
-        IOUtils.copy(in, new FileOutputStream(filepath), enc);
-
-    }
-
-    public final void addRecommendationPair(final SimpleRecommendation rec1, final SimpleRecommendation rec2) throws ConnectionException, ServerException {
-        final Recommendation recom1 = new Recommendation(rec1.getFactory(), rec1.getIds(), rec1.getTarget());
-        final Recommendation recom2 = new Recommendation(rec2.getFactory(), rec2.getIds(), rec2.getTarget());
-        final Artifact[] artifacts = loadMany(new Recommendation[] { recom1, recom2 }, null);
-        final String rec1String = RecommandationUtils.createDataString(artifacts[0].getUuid(), recom1, new NilDatacageTwinPanelInfo("xxxx"));
-        final String rec2String = RecommandationUtils.createDataString(artifacts[1].getUuid(), recom2, new NilDatacageTwinPanelInfo("xxxx"));
-        final String combinedIdNeu = rec1String + "#" + rec2String;
-        this.pairIds.add(combinedIdNeu);
-    }
-
-    protected Data[] getPairData() {
-        final Data[] data = new Data[this.pairIds.size()];
-        int i = 0;
-        for (final String pairId : this.pairIds) {
-            final Data pair = new StringOptionsData("diffids", "diffids", new DataItem[] { new DefaultDataItem(pairId, pairId, pairId) });
-            data[i] = pair;
-            i++;
-        }
-        return data;
-    }
-
-    protected final void selectCalcMode() throws ConnectionException, ServerException {
-
-        /* Select CalcMode */
-        // final DataList calcModes = getArtifact().getArtifactDescription().getCurrentData(); // AUSWAHL-Möglichkeiten
-        // final DataItem minMaxFlowdepth = calcModes.get(0).getItems()[2]; // CalcMode
-        final String calcmodeStr = this.calcMode.name();
-        final Data dataCalcMode = new StringOptionsData("calculation_mode", "calculation_mode",
-                new DataItem[] { new DefaultDataItem(calcmodeStr, calcmodeStr, calcmodeStr) });
-        feedAndGo(new Data[] { dataCalcMode }, 0);
-    }
-
-    protected final void selectRange() throws ConnectionException, ServerException {
-        final String fromStr = String.valueOf(this.from);
-        final String toStr = String.valueOf(this.to);
-        final Data dataFrom = new StringOptionsData("ld_from", "ld_from", new DataItem[] { new DefaultDataItem(fromStr, fromStr, fromStr) });
-        final Data dataTo = new StringOptionsData("ld_to", "ld_to", new DataItem[] { new DefaultDataItem(toStr, toStr, toStr) });
-        final Data[] rangeFromToDetermined = new Data[] { dataFrom, dataTo };
-
-        feedAndGo(rangeFromToDetermined, 0);
-    }
-
-    // private final void seletMaxRange() throws ConnectionException, ServerException {
-    // final DataList list = getArtifact().getArtifactDescription().getCurrentData();
-    // final Data[] rangeMax = new Data[] { list.get(0), list.get(1) };
-    // feedAndGo(rangeMax, 0);
-    // }
-
-    protected final void selectRiver() throws ConnectionException, ServerException {
-        final String riverStr = this.river.name();
-        final Data data = new StringOptionsData("river", "river", new DataItem[] { new DefaultDataItem(riverStr, riverStr, riverStr) });
-        feedAndGo(new Data[] { data }, 0);
-    }
-
-    protected final void export(final boolean exportToFile) throws IOException, ServerException {
-        final OutputMode[] modes = getArtifact().getArtifactDescription().getOutputModes(); // TODO: CHECK IF THIS WORKS ALSO FOR FUTURE CALC_MODES
-        if (modes != null) {
-            final OutputMode mode = modes[1];
-            doGet(mode.getName(), exportToFile);
-        }
-    }
-
-}
--- a/gwt-client/src/test/java/test/RunnerCreatorHelper.java	Tue Jun 12 10:40:33 2018 +0200
+++ b/gwt-client/src/test/java/test/RunnerCreatorHelper.java	Tue Jun 12 15:04:40 2018 +0200
@@ -32,21 +32,32 @@
 
     // HELPER-Methods:
 
-    public final static ModuleRunner createSinfoFlowdepthMinMaxTest(final FilenameMapper helloWorldFile, final double from, final double to,
+    public final static AbstractModuleRunner createSinfoFlowdepthMinMaxTest(final FilenameMapper helloWorldFile, final double from, final double to,
             final River beispielfluss) throws ConnectionException, ServerException {
         // TODO: make recommendationPair to method parameter if needed
-        final ModuleRunner proof = new SinfoFlowdepthMinMaxRunner(user, pw, CalcMode.sinfo_calc_flow_depth_minmax, helloWorldFile, from, to, beispielfluss);
+        final SinfoFlowdepthMinMaxRunner proof = new SinfoFlowdepthMinMaxRunner(user, pw, CalcMode.sinfo_calc_flow_depth_minmax, helloWorldFile, from, to,
+                beispielfluss);
         proof.addRecommendationPair(new SimpleRecommendation("staticwqkms", "additionals-wstv-0-103", "sinfo_flowdepth_waterlevels"),
                 new SimpleRecommendation("bedheight", "bedheight-single-36-2015-FP-2015_0-502", "sinfo_flowdepthminmax_heights"));
 
         return proof;
     }
 
-    public final static ModuleRunner createSinfoFlowdepthTest(final FilenameMapper file, final double from, final double to, final River river,
+    public final static AbstractModuleRunner createSinfoFlowdepthTest(final FilenameMapper file, final double from, final double to, final River river,
             final boolean useTkh, final SimpleRecommendation rec0, final SimpleRecommendation rec1) throws ConnectionException, ServerException {
-        final ModuleRunner proof = new SinfoFlowdepthRunner(user, pw, CalcMode.sinfo_calc_flow_depth, file, from, to, river, useTkh);
+        final SinfoFlowdepthRunner proof = new SinfoFlowdepthRunner(user, pw, CalcMode.sinfo_calc_flow_depth, file, from, to, river, useTkh);
         proof.addRecommendationPair(rec0, rec1);
 
         return proof;
     }
+
+    public final static AbstractModuleRunner createSinfoFlowdepthDevelopmentTest(final FilenameMapper file, final double from, final double to,
+            final River river, final SimpleRecommendation rec0_curr, final SimpleRecommendation rec1_curr, final SimpleRecommendation rec0_hist,
+            final SimpleRecommendation rec1_hist) throws ConnectionException, ServerException {
+        final SinfoFlowdepthDevelopmentRunner proof = new SinfoFlowdepthDevelopmentRunner(user, pw, CalcMode.sinfo_calc_flow_depth_development, file, from, to,
+                river);
+        proof.addCurrentRecommendationPair(rec0_curr, rec1_curr);
+        proof.addHistoricalRecommendationPair(rec0_hist, rec1_hist);
+        return proof;
+    }
 }
\ No newline at end of file
--- a/gwt-client/src/test/java/test/SimpleRecommendation.java	Tue Jun 12 10:40:33 2018 +0200
+++ b/gwt-client/src/test/java/test/SimpleRecommendation.java	Tue Jun 12 15:04:40 2018 +0200
@@ -9,6 +9,20 @@
  */
 package test;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
+import org.dive4elements.river.client.client.ui.NilDatacageTwinPanelInfo;
+import org.dive4elements.river.client.client.ui.RecommandationUtils;
+import org.dive4elements.river.client.server.ArtifactHelper;
+import org.dive4elements.river.client.server.CollectionHelper;
+import org.dive4elements.river.client.server.LoadArtifactServiceImpl;
+import org.dive4elements.river.client.shared.exceptions.ServerException;
+import org.dive4elements.river.client.shared.model.Artifact;
+import org.dive4elements.river.client.shared.model.Collection;
+import org.dive4elements.river.client.shared.model.Recommendation;
+
 /**
  * @author Domenico Nardi Tironi
  *
@@ -19,6 +33,7 @@
     private final String factory;
     private final String ids;
     private final String target;
+    private String displayName;
 
     public SimpleRecommendation(final String factory, final String ids, final String target) {
         this.factory = factory;
@@ -26,6 +41,11 @@
         this.target = target;
     }
 
+    public SimpleRecommendation(final String factory, final String ids, final String target, final String displayName) {
+        this(factory, ids, target);
+        this.displayName = displayName;
+    }
+
     public String getIds() {
         return this.ids;
     }
@@ -38,4 +58,56 @@
         return this.factory;
     }
 
+    private String getDisplayName() {
+        return this.displayName;
+    }
+
+    public final String getRecommendationPairString(final SimpleRecommendation rec2, final Collection collection, final String serverUrl, final String locale)
+            throws ConnectionException, ServerException {
+        final Recommendation recom1 = new Recommendation(this.getFactory(), this.getIds(), this.getTarget());
+        recom1.setDisplayName(this.displayName);
+        final Recommendation recom2 = new Recommendation(rec2.getFactory(), rec2.getIds(), rec2.getTarget());
+        recom2.setDisplayName(rec2.getDisplayName());
+        final Artifact[] artifacts = loadMany(new Recommendation[] { recom1, recom2 }, null, collection, serverUrl, locale);
+        final String rec1String = RecommandationUtils.createDataString(artifacts[0].getUuid(), recom1, new NilDatacageTwinPanelInfo("xxxx"));
+        final String rec2String = RecommandationUtils.createDataString(artifacts[1].getUuid(), recom2, new NilDatacageTwinPanelInfo("xxxx"));
+        final String combinedIdNeu = rec1String + "#" + rec2String;
+        return combinedIdNeu;
+
+    }
+
+    private final Artifact[] loadMany(final Recommendation[] recoms, final String factory, final Collection collection, final String serverUrl,
+            final String locale) throws ServerException, ConnectionException {
+        final ArrayList<Artifact> artifacts = new ArrayList<Artifact>();
+        final HashMap<Recommendation, Artifact> cloneMap = new HashMap<Recommendation, Artifact>();
+
+        for (final Recommendation recom : recoms) {
+
+            final Artifact prevClone = cloneMap.get(recom);
+            if (prevClone != null) {
+
+                artifacts.add(prevClone);
+            } else {
+                // Not already cloned.
+                final String realFactory = factory != null ? factory : recom.getFactory();
+
+                final Artifact clone = ArtifactHelper.createArtifact(serverUrl, locale, realFactory, recom);
+
+                if (clone != null) {
+                    final Collection c = CollectionHelper.addArtifact(collection, clone, serverUrl, locale);
+
+                    if (c != null) {
+                        artifacts.add(clone);
+                        // Remember we cloned a recommendation like this.
+                        cloneMap.put(recom, clone);
+                    } else {
+                        throw new ServerException(LoadArtifactServiceImpl.ERROR_LOAD_ARTIFACT);
+                    }
+                }
+            }
+        }
+        return artifacts.toArray(new Artifact[artifacts.size()]);
+
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/java/test/SinfoFlowdepthDevelopmentRunner.java	Tue Jun 12 15:04:40 2018 +0200
@@ -0,0 +1,67 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
+import org.dive4elements.river.client.shared.exceptions.ServerException;
+
+import test.BerechnungsartenTester.CalcMode;
+import test.BerechnungsartenTester.FilenameMapper;
+import test.BerechnungsartenTester.River;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class SinfoFlowdepthDevelopmentRunner extends AbstractModuleRunner {
+
+    private final List<String> pairIdsCurrent = new ArrayList<String>();
+    private final List<String> pairIdsHistorical = new ArrayList<String>();
+
+    public SinfoFlowdepthDevelopmentRunner(final String username, final String password, final CalcMode sinfoCalcFlowDepth, final FilenameMapper file,
+            final double from, final double to, final River river) throws ConnectionException, ServerException {
+        super(username, password, AbstractModuleRunner.Infotype.sinfo, sinfoCalcFlowDepth, file, from, to, river);
+
+    }
+
+    public void addCurrentRecommendationPair(final SimpleRecommendation rec1, final SimpleRecommendation rec2) throws ConnectionException, ServerException {
+        this.pairIdsCurrent.add(super.getRecommendationPairString(rec1, rec2));
+    }
+
+    public void addHistoricalRecommendationPair(final SimpleRecommendation rec1, final SimpleRecommendation rec2) throws ConnectionException, ServerException {
+        this.pairIdsHistorical.add(super.getRecommendationPairString(rec1, rec2));
+    }
+
+    @Override
+    public void runTest(final boolean exportToFile) throws ServerException, IOException {
+        /* Select River */
+        super.selectRiver();
+
+        /* Select CalcMode */
+        super.selectCalcMode();
+
+        /* Select Range */
+        super.selectRange();
+
+        /* Select current Fixpunkte */
+        feedAndGo(super.extractPairData(this.pairIdsCurrent, "diffid_current"), 0);
+
+        /* Select historical Fixpunkte */
+        feedAndGo(super.extractPairData(this.pairIdsHistorical, "diffid_historical"), 0);
+
+        describeCollection();
+
+        super.export(exportToFile);
+    }
+}
--- a/gwt-client/src/test/java/test/SinfoFlowdepthMinMaxRunner.java	Tue Jun 12 10:40:33 2018 +0200
+++ b/gwt-client/src/test/java/test/SinfoFlowdepthMinMaxRunner.java	Tue Jun 12 15:04:40 2018 +0200
@@ -10,6 +10,8 @@
 package test;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
 import org.dive4elements.river.client.shared.exceptions.ServerException;
@@ -22,11 +24,17 @@
  * @author Domenico Nardi Tironi
  *
  */
-public class SinfoFlowdepthMinMaxRunner extends ModuleRunner {
+public class SinfoFlowdepthMinMaxRunner extends AbstractModuleRunner {
+
+    private final List<String> pairIds = new ArrayList<String>();
 
     public SinfoFlowdepthMinMaxRunner(final String username, final String password, final CalcMode sinfoCalcFlowDepthMinmax,
             final FilenameMapper helloWorldFile, final double from, final double to, final River beispielfluss) throws ConnectionException, ServerException {
-        super(username, password, ModuleRunner.Infotype.sinfo, sinfoCalcFlowDepthMinmax, helloWorldFile, from, to, beispielfluss);
+        super(username, password, AbstractModuleRunner.Infotype.sinfo, sinfoCalcFlowDepthMinmax, helloWorldFile, from, to, beispielfluss);
+    }
+
+    public void addRecommendationPair(final SimpleRecommendation rec1, final SimpleRecommendation rec2) throws ConnectionException, ServerException {
+        this.pairIds.add(super.getRecommendationPairString(rec1, rec2));
     }
 
     @Override
@@ -42,7 +50,7 @@
         super.selectRange();
 
         /* Select Fixpunkte */
-        feedAndGo(super.getPairData(), 0);
+        feedAndGo(extractPairData(this.pairIds, "diffids"), 0);
 
         // Describe collection
         describeCollection(); // wichtig, damit die Facets erzeugt werden
--- a/gwt-client/src/test/java/test/SinfoFlowdepthRunner.java	Tue Jun 12 10:40:33 2018 +0200
+++ b/gwt-client/src/test/java/test/SinfoFlowdepthRunner.java	Tue Jun 12 15:04:40 2018 +0200
@@ -10,6 +10,7 @@
 package test;
 
 import java.io.IOException;
+import java.util.ArrayList;
 
 import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
 import org.dive4elements.river.client.shared.exceptions.ServerException;
@@ -26,16 +27,21 @@
  * @author Domenico Nardi Tironi
  *
  */
-public class SinfoFlowdepthRunner extends ModuleRunner {
+public class SinfoFlowdepthRunner extends AbstractModuleRunner {
 
     private final boolean useTkh;
+    private final ArrayList<String> pairIds = new ArrayList<String>();
 
     public SinfoFlowdepthRunner(final String username, final String password, final CalcMode sinfoCalcFlowDepth, final FilenameMapper file, final double from,
             final double to, final River river, final boolean useTkh) throws ConnectionException, ServerException {
-        super(username, password, ModuleRunner.Infotype.sinfo, sinfoCalcFlowDepth, file, from, to, river);
+        super(username, password, AbstractModuleRunner.Infotype.sinfo, sinfoCalcFlowDepth, file, from, to, river);
         this.useTkh = useTkh;
     }
 
+    public void addRecommendationPair(final SimpleRecommendation rec1, final SimpleRecommendation rec2) throws ConnectionException, ServerException {
+        this.pairIds.add(super.getRecommendationPairString(rec1, rec2));
+    }
+
     @Override
     public void runTest(final boolean exportToFile) throws ServerException, IOException {
         /* Select River */
@@ -48,7 +54,7 @@
         super.selectRange();
 
         /* Select Fixpunkte */
-        feedAndGo(super.getPairData(), 0);
+        feedAndGo(extractPairData(this.pairIds, "diffids"), 0);
 
         /* Select TRANSPORTKÖRPERHÖHHEN - einziger Unterschied zu FlowdepthMinMax */
         final String useTkhStr = String.valueOf(this.useTkh);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/resources/sinfo/flowdepthdevelopment/sinfo_fte_01.csv	Tue Jun 12 15:04:40 2018 +0200
@@ -0,0 +1,238 @@
+"##Ergebnisausgabe - Elbe - Fließtiefenentwicklung"
+"# FLYS-Version: 3.3.0"
+"# Bearbeiter: gbelger@localdb"
+"# Datum der Erstellung: 06.06.18"
+"# Gewässer: Elbe"
+"# Höhensystem des Flusses: NHN + m "
+"# Bereich (km): 210,000 - 230,000"
+""
+"Fluss-km";"Fließtiefenentwicklung																			 [m]";"Fließtiefenent-wicklung pro Jahr [cm/a]";"?WSPL [m] (05.05.2008 - 18.03.1997)";"?MSH [m] (FP-QP-2008 - QP-1995)";"Fließtiefe h-aktuell [m] (05.05.2008 - FP-QP-2008)";"Fließtiefe h-historisch [m] (18.03.1997 - QP-1995)";"Lage"
+""
+"##METADATEN PEILUNG aktuell"
+"# Jahr der Peilung: 2008"
+"# Aufnahmeart: Flächen- u. Querprofilpeilungen"
+"# Auswerter: BfG"
+"# Lagesystem: LS 150 und LS 100"
+"# Höhensystem: müNN "
+"# ursprüngliches Höhensystem: müNN"
+""
+"##METADATEN WASSERSPIEGELLAGE aktuell"
+"# Bezeichnung der Wasserspiegellage: 05.05.2008 "
+"# Bezugspegel: Schöna"
+"# Jahr/Zeitraum der Wasserspiegellage: 2008"
+""
+"##METADATEN PEILUNG historisch"
+"# Jahr der Peilung: 1995"
+"# Aufnahmeart: Querprofile"
+"# Auswerter: BfG"
+"# Lagesystem: LS 150"
+"# Höhensystem: müNN "
+"# ursprüngliches Höhensystem: müNN"
+""
+"##METADATEN WASSERSPIEGELLAGE historisch"
+"# Bezeichnung der Wasserspiegellage: 18.03.1997 "
+"# Bezugspegel: Torgau"
+"# Jahr/Zeitraum der Wasserspiegellage: 1997"
+""
+"210,000";"-61,6";"-5,13";"-74,0";"-12,4";"3,82";"4,44";""
+"210,100";"-56,0";"-4,66";"-75,2";"-19,2";"3,64";"4,20";""
+"210,200";"-48,4";"-4,04";"-76,3";"-27,9";"3,65";"4,14";""
+"210,300";"-52,0";"-4,33";"-77,5";"-25,5";"3,58";"4,10";""
+"210,400";"-52,6";"-4,38";"-77,7";"-25,1";"3,58";"4,10";""
+"210,500";"-68,4";"-5,70";"-77,8";"-9,4";"3,54";"4,23";""
+"210,600";"-62,5";"-5,21";"-77,0";"-14,5";"3,77";"4,39";""
+"210,700";"-46,2";"-3,85";"-76,5";"-30,3";"3,98";"4,45";""
+"210,800";"-55,3";"-4,61";"-77,0";"-21,7";"3,97";"4,52";""
+"210,900";"-53,2";"-4,43";"-76,5";"-23,3";"3,99";"4,52";""
+"211,000";"-45,3";"-3,77";"-76,0";"-30,7";"3,94";"4,39";""
+"211,100";"-36,3";"-3,03";"-75,3";"-39,0";"3,84";"4,20";""
+"211,200";"-43,4";"-3,61";"-74,7";"-31,3";"3,88";"4,32";""
+"211,300";"-46,1";"-3,84";"-75,0";"-28,9";"3,93";"4,39";""
+"211,400";"-55,2";"-4,60";"-74,3";"-19,1";"3,67";"4,22";""
+"211,500";"-41,9";"-3,49";"-72,7";"-30,8";"3,71";"4,13";""
+"211,600";"-60,6";"-5,05";"-73,0";"-12,4";"3,59";"4,20";""
+"211,700";"-62,8";"-5,23";"-72,5";"-9,7";"3,58";"4,21";""
+"211,800";"-57,6";"-4,80";"-73,0";"-15,4";"3,45";"4,03";""
+"211,900";"-69,7";"-5,81";"-72,5";"-2,8";"3,38";"4,08";""
+"212,000";"-82,3";"-6,86";"-73,0";"9,3";"3,69";"4,51";""
+"212,100";"-63,1";"-5,26";"-71,0";"-7,9";"4,07";"4,70";""
+"212,200";"-60,7";"-5,06";"-70,0";"-9,3";"3,96";"4,57";""
+"212,300";"-62,9";"-5,24";"-70,0";"-7,1";"3,91";"4,54";""
+"212,400";"-79,4";"-6,62";"-70,0";"9,4";"3,82";"4,62";""
+"212,500";"-86,7";"-7,23";"-72,0";"14,7";"3,85";"4,72";""
+"212,600";"-80,9";"-6,74";"-70,0";"10,9";"3,73";"4,54";""
+"212,700";"-68,1";"-5,68";"-71,5";"-3,4";"3,69";"4,37";""
+"212,800";"-61,2";"-5,10";"-72,0";"-10,8";"3,59";"4,20";""
+"212,900";"-69,1";"-5,76";"-72,5";"-3,4";"3,49";"4,18";""
+"213,000";"-62,0";"-5,17";"-72,0";"-10,0";"3,69";"4,31";""
+"213,100";"-57,7";"-4,81";"-72,0";"-14,3";"3,67";"4,25";""
+"213,200";"-60,5";"-5,04";"-73,0";"-12,5";"3,70";"4,30";""
+"213,300";"-67,2";"-5,60";"-73,0";"-5,8";"3,70";"4,37";""
+"213,400";"-69,3";"-5,78";"-73,0";"-3,7";"3,76";"4,46";""
+"213,500";"-73,9";"-6,16";"-73,0";"0,9";"3,85";"4,59";""
+"213,600";"-77,9";"-6,49";"-72,0";"5,9";"4,02";"4,80";""
+"213,700";"-61,7";"-5,14";"-71,3";"-9,6";"4,14";"4,75";""
+"213,800";"-112,8";"-9,40";"-72,4";"40,4";"4,12";"5,25";""
+"213,900";"-96,0";"-8,00";"-72,8";"23,2";"4,04";"5,00";""
+"214,000";"-84,2";"-7,02";"-73,0";"11,2";"4,07";"4,92";""
+"214,100";"-87,2";"-7,27";"-70,5";"16,7";"4,02";"4,89";""
+"214,200";"-87,5";"-7,29";"-70,7";"16,8";"4,03";"4,90";""
+"214,300";"-76,8";"-6,40";"-70,0";"6,8";"4,04";"4,81";""
+"214,400";"-69,7";"-5,81";"-70,3";"-0,6";"4,06";"4,76";""
+"214,500";"-60,0";"-5,00";"-70,7";"-10,7";"3,96";"4,56";""
+"214,600";"-73,5";"-6,12";"-71,0";"2,5";"3,85";"4,59";""
+"214,700";"-72,3";"-6,02";"-71,0";"1,3";"3,72";"4,45";""
+"214,800";"-83,8";"-6,98";"-71,0";"12,8";"3,80";"4,64";"Schwebstoffmessstelle: Wittenberg"
+"214,900";"-73,6";"-6,13";"-70,0";"3,6";"3,83";"4,57";""
+"215,000";"-50,6";"-4,22";"-70,0";"-19,4";"3,92";"4,42";""
+"215,100";"-37,5";"-3,13";"-72,0";"-34,5";"3,97";"4,35";""
+"215,200";"-52,1";"-4,34";"-72,0";"-19,9";"3,96";"4,49";""
+"215,300";"-60,2";"-5,02";"-71,0";"-10,8";"3,82";"4,42";""
+"215,400";"-55,5";"-4,63";"-71,0";"-15,5";"3,83";"4,39";""
+"215,500";"-57,6";"-4,80";"-71,0";"-13,4";"3,84";"4,41";""
+"215,600";"-58,5";"-4,87";"-70,0";"-11,5";"3,93";"4,52";""
+"215,700";"-66,6";"-5,55";"-70,3";"-3,6";"3,86";"4,53";""
+"215,800";"-64,5";"-5,38";"-71,5";"-7,0";"3,74";"4,38";""
+"215,900";"-60,5";"-5,05";"-71,8";"-11,2";"3,80";"4,41";""
+"216,000";"-62,4";"-5,20";"-71,0";"-8,6";"3,85";"4,48";""
+"216,100";"-73,4";"-6,11";"-70,2";"3,2";"3,74";"4,48";""
+"216,200";"-71,7";"-5,98";"-70,3";"1,4";"3,84";"4,56";""
+"216,300";"-63,5";"-5,29";"-70,5";"-7,0";"3,81";"4,44";""
+"216,400";"-63,2";"-5,26";"-69,7";"-6,5";"3,72";"4,35";"Hafen: Wittenberg -Schutz- und Sicherheitshafen"
+"216,500";"-75,4";"-6,29";"-69,8";"5,6";"3,52";"4,28";""
+"216,600";"-72,9";"-6,07";"-69,0";"3,9";"3,70";"4,43";""
+"216,700";"-64,2";"-5,35";"-68,5";"-4,3";"3,84";"4,48";""
+"216,800";"-72,1";"-6,01";"-71,0";"1,1";"3,66";"4,39";""
+"216,900";"-68,5";"-5,71";"-70,5";"-2,0";"3,63";"4,32";""
+"217,000";"-66,5";"-5,54";"-70,0";"-3,5";"3,64";"4,30";""
+"217,100";"-72,3";"-6,03";"-70,3";"2,0";"3,52";"4,25";""
+"217,200";"-80,4";"-6,70";"-69,7";"10,7";"3,43";"4,23";""
+"217,300";"-68,8";"-5,73";"-70,0";"-1,2";"3,30";"3,98";""
+"217,400";"-81,1";"-6,76";"-71,3";"9,8";"3,17";"3,98";""
+"217,500";"-78,0";"-6,50";"-73,7";"4,3";"3,47";"4,25";""
+"217,600";"-87,6";"-7,30";"-74,0";"13,6";"3,56";"4,43";""
+"217,700";"-75,1";"-6,26";"-73,5";"1,6";"3,51";"4,27";""
+"217,800";"-86,7";"-7,23";"-73,0";"13,7";"3,33";"4,20";""
+"217,900";"-56,0";"-4,67";"-73,5";"-17,5";"3,71";"4,27";""
+"218,000";"-59,7";"-4,97";"-74,0";"-14,3";"4,14";"4,74";""
+"218,100";"-53,9";"-4,49";"-73,7";"-19,8";"4,16";"4,69";""
+"218,200";"-60,4";"-5,04";"-74,3";"-13,9";"4,23";"4,83";""
+"218,300";"-76,8";"-6,40";"-74,0";"2,8";"4,10";"4,87";""
+"218,400";"-72,0";"-6,00";"-73,7";"-1,7";"4,23";"4,95";""
+"218,500";"-76,5";"-6,38";"-73,3";"3,2";"4,28";"5,04";""
+"218,600";"-74,4";"-6,20";"-74,0";"0,4";"4,10";"4,84";""
+"218,700";"-69,9";"-5,82";"-72,8";"-2,9";"4,20";"4,90";""
+"218,800";"-77,5";"-6,46";"-72,5";"5,0";"4,16";"4,93";""
+"218,900";"-84,2";"-7,02";"-74,2";"10,0";"4,10";"4,94";""
+"219,000";"-82,7";"-6,89";"-76,0";"6,7";"4,04";"4,87";""
+"219,100";"-81,7";"-6,81";"-75,8";"5,9";"3,80";"4,62";""
+"219,200";"-84,0";"-7,00";"-74,7";"9,3";"3,63";"4,47";""
+"219,300";"-81,3";"-6,77";"-74,5";"6,8";"3,61";"4,43";""
+"219,400";"-73,9";"-6,16";"-74,3";"-0,4";"3,55";"4,29";""
+"219,500";"-85,9";"-7,16";"-73,2";"12,7";"3,53";"4,39";""
+"219,600";"-98,8";"-8,23";"-73,0";"25,8";"3,79";"4,78";""
+"219,700";"-99,7";"-8,31";"-72,5";"27,2";"4,02";"5,02";""
+"219,800";"-80,7";"-6,73";"-71,0";"9,7";"3,94";"4,75";""
+"219,900";"-92,9";"-7,74";"-70,5";"22,4";"3,92";"4,85";""
+"220,000";"-94,2";"-7,85";"-71,0";"23,2";"4,00";"4,94";""
+"220,100";"-113,9";"-9,49";"-70,2";"43,7";"3,90";"5,04";""
+"220,200";"-102,2";"-8,52";"-70,3";"31,9";"4,04";"5,07";""
+"220,300";"-84,5";"-7,04";"-70,5";"14,0";"4,01";"4,85";""
+"220,400";"-98,8";"-8,23";"-70,7";"28,1";"3,78";"4,77";""
+"220,500";"-107,0";"-8,92";"-70,8";"36,2";"3,59";"4,66";""
+"220,600";"-101,6";"-8,47";"-71,0";"30,6";"3,38";"4,40";""
+"220,700";"-92,5";"-7,70";"-69,8";"22,7";"3,52";"4,45";""
+"220,800";"-88,9";"-7,41";"-69,5";"19,4";"3,32";"4,21";""
+"220,900";"-85,3";"-7,10";"-69,3";"16,0";"3,23";"4,09";""
+"221,000";"-78,7";"-6,56";"-70,0";"8,7";"3,17";"3,96";""
+"221,100";"-78,6";"-6,55";"-70,0";"8,6";"3,12";"3,91";""
+"221,200";"-71,3";"-5,94";"-70,0";"1,3";"3,14";"3,86";""
+"221,300";"-59,7";"-4,97";"-71,0";"-11,3";"3,36";"3,96";""
+"221,400";"-66,3";"-5,52";"-71,0";"-4,7";"3,32";"3,99";""
+"221,500";"-65,1";"-5,42";"-72,0";"-6,9";"3,24";"3,89";""
+"221,600";"-59,4";"-4,95";"-73,0";"-13,6";"3,28";"3,87";""
+"221,700";"-45,1";"-3,76";"-73,0";"-27,9";"3,35";"3,80";""
+"221,800";"-48,4";"-4,03";"-74,0";"-25,6";"3,25";"3,73";""
+"221,900";"-53,8";"-4,48";"-74,0";"-20,2";"3,28";"3,81";""
+"222,000";"-61,4";"-5,12";"-73,0";"-11,6";"3,44";"4,05";""
+"222,100";"-82,7";"-6,89";"-73,0";"9,7";"3,78";"4,61";""
+"222,200";"-71,0";"-5,92";"-73,0";"-2,0";"3,94";"4,65";""
+"222,300";"-57,3";"-4,77";"-73,0";"-15,7";"4,13";"4,70";""
+"222,400";"-65,1";"-5,42";"-73,0";"-7,9";"4,13";"4,78";""
+"222,500";"-75,8";"-6,32";"-73,0";"2,8";"3,97";"4,72";""
+"222,600";"-111,8";"-9,32";"-72,0";"39,8";"3,84";"4,96";""
+"222,700";"-125,7";"-10,47";"-72,0";"53,7";"3,77";"5,03";""
+"222,800";"-112,3";"-9,36";"-72,0";"40,3";"3,73";"4,85";""
+"222,900";"-106,9";"-8,91";"-71,0";"35,9";"3,67";"4,74";""
+"223,000";"-98,4";"-8,20";"-71,0";"27,4";"3,59";"4,57";""
+"223,100";"-63,8";"-5,31";"-72,7";"-8,9";"3,54";"4,18";""
+"223,200";"-55,9";"-4,66";"-74,3";"-18,4";"3,76";"4,32";""
+"223,300";"-51,4";"-4,28";"-74,0";"-22,6";"3,78";"4,30";""
+"223,400";"-58,8";"-4,90";"-72,7";"-13,9";"3,74";"4,32";""
+"223,500";"-85,3";"-7,11";"-71,3";"14,0";"3,77";"4,62";""
+"223,600";"-106,9";"-8,91";"-70,0";"36,9";"3,83";"4,90";""
+"223,700";"-124,8";"-10,40";"-71,5";"53,3";"4,00";"5,25";""
+"223,800";"-127,3";"-10,61";"-73,0";"54,3";"4,05";"5,32";""
+"223,900";"-79,1";"-6,59";"-71,5";"7,6";"3,95";"4,74";""
+"224,000";"-76,6";"-6,38";"-71,0";"5,6";"3,75";"4,52";""
+"224,100";"-69,7";"-5,81";"-70,2";"-0,5";"3,66";"4,36";""
+"224,200";"-72,7";"-6,06";"-70,3";"2,4";"3,84";"4,57";""
+"224,300";"-54,8";"-4,57";"-70,5";"-15,7";"4,10";"4,65";""
+"224,400";"-26,6";"-2,21";"-69,7";"-43,1";"3,90";"4,16";""
+"224,500";"-52,3";"-4,36";"-68,8";"-16,5";"3,51";"4,03";""
+"224,600";"-83,4";"-6,95";"-68,0";"15,4";"3,27";"4,11";""
+"224,700";"-77,1";"-6,42";"-67,2";"9,8";"3,27";"4,04";""
+"224,800";"-63,0";"-5,25";"-67,5";"-4,5";"3,25";"3,87";""
+"224,900";"-75,3";"-6,28";"-67,7";"7,6";"3,45";"4,20";""
+"225,000";"-54,3";"-4,52";"-68,0";"-13,7";"3,53";"4,07";""
+"225,100";"-68,8";"-5,73";"-70,7";"-1,9";"3,35";"4,04";""
+"225,200";"-66,2";"-5,52";"-71,3";"-5,1";"3,19";"3,86";""
+"225,300";"-65,5";"-5,46";"-72,0";"-6,5";"3,25";"3,91";""
+"225,400";"-85,6";"-7,13";"-72,7";"12,9";"3,37";"4,23";""
+"225,500";"-105,4";"-8,79";"-72,3";"33,1";"3,33";"4,38";""
+"225,600";"-87,7";"-7,31";"-72,0";"15,7";"3,38";"4,25";""
+"225,700";"-102,6";"-8,55";"-71,8";"30,8";"3,20";"4,22";""
+"225,800";"-114,3";"-9,53";"-71,5";"42,8";"3,38";"4,53";""
+"225,900";"-128,6";"-10,71";"-72,3";"56,3";"3,77";"5,05";""
+"226,000";"-132,8";"-11,07";"-72,0";"60,8";"4,10";"5,43";""
+"226,100";"-135,9";"-11,33";"-70,5";"65,4";"4,14";"5,50";""
+"226,200";"-109,9";"-9,16";"-71,0";"38,9";"4,34";"5,44";""
+"226,300";"-92,7";"-7,72";"-72,5";"20,2";"4,16";"5,08";""
+"226,400";"-82,1";"-6,84";"-72,0";"10,1";"4,14";"4,96";""
+"226,500";"-109,9";"-9,16";"-72,5";"37,4";"4,16";"5,26";""
+"226,600";"-112,4";"-9,37";"-73,0";"39,4";"4,17";"5,30";""
+"226,700";"-91,6";"-7,63";"-73,5";"18,1";"3,99";"4,91";""
+"226,800";"-73,0";"-6,08";"-73,0";"0,0";"3,94";"4,67";""
+"226,900";"-78,9";"-6,57";"-74,5";"4,4";"3,83";"4,62";""
+"227,000";"-88,5";"-7,38";"-74,0";"14,5";"3,79";"4,68";""
+"227,100";"-77,3";"-6,44";"-74,7";"2,6";"3,80";"4,57";""
+"227,200";"-69,3";"-5,78";"-73,3";"-4,0";"3,74";"4,43";""
+"227,300";"-37,3";"-3,11";"-73,0";"-35,7";"3,75";"4,13";""
+"227,400";"-50,4";"-4,20";"-73,7";"-23,3";"3,75";"4,25";""
+"227,500";"-71,2";"-5,94";"-74,3";"-3,1";"3,65";"4,36";""
+"227,600";"-75,6";"-6,30";"-73,0";"2,6";"3,62";"4,38";""
+"227,700";"-73,2";"-6,10";"-74,2";"-1,0";"3,63";"4,37";""
+"227,800";"-61,5";"-5,12";"-75,5";"-14,0";"3,53";"4,14";""
+"227,900";"-88,5";"-7,38";"-74,7";"13,8";"3,42";"4,31";""
+"228,000";"-75,8";"-6,32";"-76,0";"-0,2";"3,59";"4,35";""
+"228,100";"-63,4";"-5,28";"-76,2";"-12,8";"3,55";"4,19";""
+"228,200";"-54,2";"-4,52";"-74,3";"-20,1";"3,78";"4,32";""
+"228,300";"-52,7";"-4,39";"-75,5";"-22,8";"3,95";"4,47";""
+"228,400";"-56,5";"-4,71";"-75,7";"-19,2";"4,20";"4,77";""
+"228,500";"-67,3";"-5,61";"-75,8";"-8,5";"4,03";"4,70";""
+"228,600";"-61,0";"-5,08";"-74,0";"-13,0";"4,09";"4,70";""
+"228,700";"-88,0";"-7,33";"-74,0";"14,0";"3,75";"4,63";""
+"228,800";"-84,1";"-7,01";"-72,0";"12,1";"3,92";"4,76";""
+"228,900";"-91,9";"-7,66";"-69,0";"22,9";"3,60";"4,52";""
+"229,000";"-89,7";"-7,47";"-68,0";"21,7";"3,52";"4,42";""
+"229,100";"-98,9";"-8,24";"-67,8";"31,1";"3,47";"4,46";""
+"229,200";"-73,0";"-6,08";"-66,7";"6,3";"3,86";"4,59";""
+"229,300";"-63,1";"-5,26";"-67,5";"-4,4";"4,00";"4,63";""
+"229,400";"-75,5";"-6,29";"-68,3";"7,2";"3,89";"4,64";""
+"229,500";"-86,3";"-7,19";"-69,2";"17,1";"3,55";"4,41";""
+"229,600";"-77,7";"-6,47";"-70,0";"7,7";"3,52";"4,30";""
+"229,700";"-75,1";"-6,25";"-70,8";"4,3";"3,52";"4,27";""
+"229,800";"-79,8";"-6,65";"-72,5";"7,3";"3,47";"4,26";""
+"229,900";"-79,1";"-6,59";"-73,3";"5,8";"3,54";"4,33";""
+"230,000";"-52,2";"-4,35";"-72,0";"-19,8";"3,95";"4,47";""
+""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/resources/sinfo/flowdepthdevelopment/sinfo_fte_02.csv	Tue Jun 12 15:04:40 2018 +0200
@@ -0,0 +1,138 @@
+"##Ergebnisausgabe - Rhein - Fließtiefenentwicklung"
+"# FLYS-Version: 3.3.0"
+"# Bearbeiter: gbelger@localdb"
+"# Datum der Erstellung: 06.06.18"
+"# Gewässer: Rhein"
+"# Höhensystem des Flusses: NHN + m "
+"# Bereich (km): 655,000 - 665,000"
+""
+"Fluss-km";"Fließtiefenentwicklung																			 [m]";"Fließtiefenent-wicklung pro Jahr [cm/a]";"?WSPL [m] (23.09.2009-1 - 23.09.1991)";"?MSH [m] (NIEDERRHEIN_QP-2008_Epoche_NHN - NIEDERRHEIN_QP-1991_Epoche_NHN)";"Fließtiefe h-aktuell [m] (23.09.2009-1 - NIEDERRHEIN_QP-2008_Epoche_NHN)";"Fließtiefe h-historisch [m] (23.09.1991 - NIEDERRHEIN_QP-1991_Epoche_NHN)";"Lage"
+""
+"##METADATEN PEILUNG aktuell"
+"# Jahr der Peilung: 2008"
+"# Aufnahmeart: Querprofile"
+"# Auswerter: WSA Duisburg (Abel)"
+"# Lagesystem: LS unbekannt"
+"# Höhensystem: müNHN "
+"# ursprüngliches Höhensystem: müNHN"
+""
+"##METADATEN WASSERSPIEGELLAGE aktuell"
+"# Bezeichnung der Wasserspiegellage: 23.09.2009-1 "
+"# Bezugspegel: Bonn"
+"# Jahr/Zeitraum der Wasserspiegellage: 2009"
+""
+"##METADATEN PEILUNG historisch"
+"# Jahr der Peilung: 1991"
+"# Aufnahmeart: Querprofile"
+"# Auswerter: WSA Duisburg (Abel)"
+"# Lagesystem: LS unbekannt"
+"# Höhensystem: müNHN "
+"# ursprüngliches Höhensystem: müNHN"
+""
+"##METADATEN WASSERSPIEGELLAGE historisch"
+"# Bezeichnung der Wasserspiegellage: 23.09.1991 "
+"# Bezugspegel: Bonn"
+"# Jahr/Zeitraum der Wasserspiegellage: 1991"
+""
+"655,000";"36,0";"2,12";"27,0";"-9,0";"2,47";"2,11";""
+"655,100";"31,0";"1,82";"27,0";"-4,0";"2,40";"2,09";""
+"655,200";"18,0";"1,06";"26,0";"8,0";"2,20";"2,02";""
+"655,300";"8,0";"0,47";"26,0";"18,0";"2,20";"2,12";""
+"655,400";"14,0";"0,82";"25,0";"11,0";"2,25";"2,11";""
+"655,500";"12,0";"0,71";"25,0";"13,0";"2,17";"2,05";""
+"655,600";"25,0";"1,47";"25,0";"0,0";"2,19";"1,94";""
+"655,700";"40,0";"2,35";"23,0";"-17,0";"2,11";"1,71";""
+"655,800";"43,0";"2,53";"23,0";"-20,0";"2,15";"1,72";""
+"655,900";"48,0";"2,82";"22,0";"-26,0";"2,27";"1,79";""
+"656,000";"46,0";"2,71";"23,0";"-23,0";"2,38";"1,92";""
+"656,100";"45,0";"2,65";"23,0";"-22,0";"2,59";"2,14";""
+"656,200";"39,0";"2,29";"23,0";"-16,0";"2,72";"2,33";""
+"656,300";"38,0";"2,24";"23,0";"-15,0";"2,92";"2,54";""
+"656,400";"31,0";"1,82";"22,0";"-9,0";"2,91";"2,60";""
+"656,500";"23,0";"1,35";"20,0";"-3,0";"2,99";"2,76";""
+"656,600";"27,0";"1,59";"20,0";"-7,0";"2,80";"2,53";""
+"656,700";"30,0";"1,76";"20,0";"-10,0";"3,17";"2,87";""
+"656,800";"33,0";"1,94";"20,0";"-13,0";"3,29";"2,96";""
+"656,900";"36,0";"2,12";"21,0";"-15,0";"3,30";"2,94";""
+"657,000";"40,0";"2,35";"21,0";"-19,0";"3,30";"2,90";""
+"657,100";"52,0";"3,06";"23,0";"-29,0";"3,36";"2,84";""
+"657,200";"51,0";"3,00";"25,0";"-26,0";"3,52";"3,01";""
+"657,300";"61,0";"3,59";"24,0";"-37,0";"3,41";"2,80";""
+"657,400";"51,0";"3,00";"23,0";"-28,0";"3,59";"3,08";""
+"657,500";"38,0";"2,24";"24,0";"-14,0";"3,58";"3,20";""
+"657,600";"45,0";"2,65";"25,0";"-20,0";"3,32";"2,87";""
+"657,700";"58,0";"3,41";"26,0";"-32,0";"3,26";"2,68";""
+"657,800";"54,0";"3,18";"26,0";"-28,0";"3,08";"2,54";""
+"657,900";"68,0";"4,00";"26,0";"-42,0";"3,17";"2,49";""
+"658,000";"62,0";"3,65";"26,0";"-36,0";"3,12";"2,50";""
+"658,100";"62,0";"3,65";"26,0";"-36,0";"3,16";"2,54";""
+"658,200";"41,0";"2,41";"26,0";"-15,0";"3,18";"2,77";""
+"658,300";"45,0";"2,65";"27,0";"-18,0";"3,35";"2,90";""
+"658,400";"27,0";"1,59";"26,0";"-1,0";"3,35";"3,08";""
+"658,500";"24,0";"1,41";"25,0";"1,0";"3,23";"2,99";""
+"658,600";"25,0";"1,47";"25,0";"0,0";"3,55";"3,30";""
+"658,700";"17,0";"1,00";"27,0";"10,0";"3,57";"3,40";""
+"658,800";"18,0";"1,06";"27,0";"9,0";"3,78";"3,60";""
+"658,900";"5,0";"0,29";"26,0";"21,0";"4,07";"4,02";""
+"659,000";"34,0";"2,00";"24,0";"-10,0";"3,75";"3,41";""
+"659,100";"37,0";"2,18";"21,0";"-16,0";"4,01";"3,64";""
+"659,200";"35,0";"2,06";"20,0";"-15,0";"3,98";"3,63";""
+"659,300";"49,0";"2,88";"20,0";"-29,0";"3,83";"3,34";""
+"659,400";"41,0";"2,41";"19,0";"-22,0";"3,55";"3,14";""
+"659,500";"35,0";"2,06";"18,0";"-17,0";"3,40";"3,05";""
+"659,600";"6,0";"0,35";"18,0";"12,0";"3,38";"3,32";""
+"659,700";"-1,0";"-0,06";"18,0";"19,0";"3,21";"3,22";""
+"659,800";"-5,0";"-0,29";"18,0";"23,0";"2,97";"3,02";""
+"659,900";"-21,0";"-1,24";"17,0";"38,0";"2,88";"3,09";""
+"660,000";"-23,0";"-1,35";"16,0";"39,0";"3,03";"3,26";""
+"660,100";"-28,0";"-1,65";"17,0";"45,0";"3,16";"3,44";"Geschiebemessstelle: Mondorf"
+"660,200";"-6,0";"-0,35";"18,0";"24,0";"3,19";"3,25";""
+"660,300";"-13,0";"-0,76";"19,0";"32,0";"3,16";"3,29";""
+"660,400";"11,0";"0,65";"20,0";"9,0";"2,92";"2,81";""
+"660,500";"13,0";"0,76";"19,0";"6,0";"2,76";"2,63";""
+"660,600";"29,0";"1,71";"18,0";"-11,0";"2,57";"2,28";""
+"660,700";"9,0";"0,53";"17,0";"8,0";"2,55";"2,46";""
+"660,800";"17,0";"1,00";"16,0";"-1,0";"2,51";"2,34";""
+"660,900";"11,0";"0,65";"12,0";"1,0";"2,50";"2,39";""
+"661,000";"15,0";"0,88";"13,0";"-2,0";"2,56";"2,41";""
+"661,100";"19,0";"1,12";"15,0";"-4,0";"2,51";"2,32";""
+"661,200";"34,0";"2,00";"16,0";"-18,0";"2,68";"2,34";""
+"661,300";"38,0";"2,24";"17,0";"-21,0";"2,85";"2,47";""
+"661,400";"42,0";"2,47";"17,0";"-25,0";"3,02";"2,60";""
+"661,500";"46,0";"2,71";"19,0";"-27,0";"2,97";"2,51";""
+"661,600";"51,0";"3,00";"20,0";"-31,0";"2,69";"2,18";""
+"661,700";"51,0";"3,00";"21,0";"-30,0";"2,53";"2,02";""
+"661,800";"50,0";"2,94";"22,0";"-28,0";"2,62";"2,12";""
+"661,900";"51,0";"3,00";"22,0";"-29,0";"2,59";"2,08";""
+"662,000";"40,0";"2,35";"22,0";"-18,0";"2,46";"2,06";""
+"662,100";"51,0";"3,00";"24,0";"-27,0";"2,39";"1,88";""
+"662,200";"54,0";"3,18";"25,0";"-29,0";"2,49";"1,95";""
+"662,300";"58,0";"3,41";"24,0";"-34,0";"2,46";"1,88";""
+"662,400";"56,0";"3,29";"22,0";"-34,0";"2,69";"2,13";""
+"662,500";"51,0";"3,00";"24,0";"-27,0";"2,19";"1,68";""
+"662,600";"51,0";"3,00";"25,0";"-26,0";"2,13";"1,62";""
+"662,700";"62,0";"3,65";"25,0";"-37,0";"2,34";"1,72";""
+"662,800";"64,0";"3,76";"26,0";"-38,0";"2,49";"1,85";""
+"662,900";"64,0";"3,76";"28,0";"-36,0";"2,31";"1,67";""
+"663,000";"58,0";"3,41";"30,0";"-28,0";"2,25";"1,67";""
+"663,100";"49,0";"2,88";"31,0";"-18,0";"2,37";"1,88";""
+"663,200";"44,0";"2,59";"30,0";"-14,0";"2,40";"1,96";""
+"663,300";"41,0";"2,41";"29,0";"-12,0";"2,32";"1,91";""
+"663,400";"36,0";"2,12";"28,0";"-8,0";"2,49";"2,13";""
+"663,500";"29,0";"1,71";"26,0";"-3,0";"2,59";"2,30";""
+"663,600";"34,0";"2,00";"24,0";"-10,0";"2,78";"2,44";""
+"663,700";"34,0";"2,00";"23,0";"-11,0";"2,70";"2,36";""
+"663,800";"37,0";"2,18";"24,0";"-13,0";"2,32";"1,95";""
+"663,900";"34,0";"2,00";"24,0";"-10,0";"2,40";"2,06";""
+"664,000";"34,0";"2,00";"22,0";"-12,0";"2,62";"2,28";""
+"664,100";"27,0";"1,59";"22,0";"-5,0";"2,86";"2,59";""
+"664,200";"33,0";"1,94";"22,0";"-11,0";"3,14";"2,81";""
+"664,300";"34,0";"2,00";"21,0";"-13,0";"2,77";"2,43";""
+"664,400";"19,0";"1,12";"22,0";"3,0";"3,17";"2,98";""
+"664,500";"13,0";"0,76";"22,0";"9,0";"2,93";"2,80";""
+"664,600";"17,0";"1,00";"22,0";"5,0";"2,89";"2,72";""
+"664,700";"20,0";"1,18";"22,0";"2,0";"3,14";"2,94";""
+"664,800";"23,0";"1,35";"22,0";"-1,0";"3,21";"2,98";""
+"664,900";"20,0";"1,18";"22,0";"2,0";"3,03";"2,83";""
+"665,000";"28,0";"1,65";"22,0";"-6,0";"3,00";"2,72";""
+""

http://dive4elements.wald.intevation.org