[RELEASE] [skip-ci]merging 'release-0.62.0' into 'master'
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 00e9cd7..784f2b8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -60,6 +60,7 @@
      - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $REGISTRY_HOST
      - docker login -u riemer -p $HARBOR_PASSWORD laus.fzi.de:8201
      - docker build --no-cache --pull -t $IMAGE_NAME/$CONTAINER_NAME:latest -t $IMAGE_NAME/$CONTAINER_NAME:$MVN_VERSION -t $HARBOR_IMAGE_NAME/$CONTAINER_NAME:latest -t $HARBOR_IMAGE_NAME/$CONTAINER_NAME:$MVN_VERSION ./streampipes-$CONTAINER_NAME
+     - docker build --no-cache --pull -t $IMAGE_NAME/$CONTAINER_NAME:latest -t $IMAGE_NAME/$CONTAINER_NAME:$MVN_VERSION  ./streampipes-$CONTAINER_NAME
      - docker push $IMAGE_NAME/$CONTAINER_NAME:$MVN_VERSION
      - docker push $IMAGE_NAME/$CONTAINER_NAME:latest
      - docker push $HARBOR_IMAGE_NAME/$CONTAINER_NAME:$MVN_VERSION
@@ -202,6 +203,11 @@
     variables:
       CONTAINER_NAME: "processors-transformation-jvm"
 
+docker-processors-text-mining-flink:
+  <<: *docker_hub_script
+  variables:
+    CONTAINER_NAME: "processors-text-mining-flink"
+
 docker-sinks-brokers-jvm:
     <<: *docker_script
     variables:
@@ -298,6 +304,11 @@
     variables:
       CONTAINER_NAME: "processors-transformation-jvm"
 
+docker-hub-processors-text-mining-flink:
+  <<: *docker_hub_script
+  variables:
+    CONTAINER_NAME: "processors-text-mining-flink"
+
 docker-hub-sinks-brokers-jvm:
     <<: *docker_hub_script
     variables:
diff --git a/.spignore b/.spignore
new file mode 100644
index 0000000..2dc8caa
--- /dev/null
+++ b/.spignore
@@ -0,0 +1,7 @@
+org.streampipes.processors.aggregation.flink.count
+org.streampipes.processor.imageclassification.jvm.image-cropper
+org.streampipes.processors.pattern-detection.flink.sequence
+org.streampipes.processors.pattern-detection.flink.absence
+org.streampipes.processors.pattern-detection.flink.and
+org.streampipes.processors.pattern-detection.flink.increase
+org.streampipes.processors.statistics.flink.statistics-summary
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1771ef0..26f2de2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
     <groupId>org.streampipes</groupId>
     <artifactId>streampipes-pipeline-elements</artifactId>
     <packaging>pom</packaging>
-    <version>0.61.0</version>
+    <version>0.62.0</version>
     <modules>
         <module>streampipes-sinks-databases-jvm</module>
         <module>streampipes-sinks-internal-jvm</module>
@@ -31,7 +31,7 @@
     </modules>
 
     <properties>
-        <streampipes.version>0.61.0</streampipes.version>
+        <streampipes.version>0.62.0</streampipes.version>
         <lightcouch.version>0.1.8</lightcouch.version>
     </properties>
 
@@ -218,6 +218,13 @@
                 </plugin>
             </plugins>
         </pluginManagement>
+<!--        <plugins>-->
+<!--            <plugin>-->
+<!--                <groupId>org.streampipes</groupId>-->
+<!--                <artifactId>streampipes-maven-plugin</artifactId>-->
+<!--                <version>1.0-SNAPSHOT</version>-->
+<!--            </plugin>-->
+<!--        </plugins>-->
     </build>
 
     <scm>
diff --git a/streampipes-pipeline-elements-shared/pom.xml b/streampipes-pipeline-elements-shared/pom.xml
index e78263a..c943dd4 100644
--- a/streampipes-pipeline-elements-shared/pom.xml
+++ b/streampipes-pipeline-elements-shared/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-aggregation-flink/pom.xml b/streampipes-processors-aggregation-flink/pom.xml
index 0fe6b06..f9d590e 100644
--- a/streampipes-processors-aggregation-flink/pom.xml
+++ b/streampipes-processors-aggregation-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/AggregationFlinkInit.java b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/AggregationFlinkInit.java
index 5438408..64ea313 100644
--- a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/AggregationFlinkInit.java
+++ b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/AggregationFlinkInit.java
@@ -20,13 +20,16 @@
 import org.streampipes.container.standalone.init.StandaloneModelSubmitter;
 import org.streampipes.processors.aggregation.flink.config.AggregationFlinkConfig;
 import org.streampipes.processors.aggregation.flink.processor.aggregation.AggregationController;
+import org.streampipes.processors.aggregation.flink.processor.count.CountController;
+import org.streampipes.processors.aggregation.flink.processor.rate.EventRateController;
 
 public class AggregationFlinkInit extends StandaloneModelSubmitter {
 
   public static void main(String[] args) {
     DeclarersSingleton.getInstance()
-            .add(new AggregationController());
-            //.add(new CountController());
+            .add(new AggregationController())
+            .add(new CountController())
+            .add(new EventRateController());
 
     new AggregationFlinkInit().init(AggregationFlinkConfig.INSTANCE);
   }
diff --git a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/aggregation/AggregationController.java b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/aggregation/AggregationController.java
index c509a5e..fa2ee6f 100644
--- a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/aggregation/AggregationController.java
+++ b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/aggregation/AggregationController.java
@@ -27,6 +27,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -35,9 +36,6 @@
 
 public class AggregationController extends FlinkDataProcessorDeclarer<AggregationParameters> {
 
-  private static final String RESOURCE_ID = "strings";
-  private static final String PE_ID = "org.streampipes.processors.aggregation.flink.aggregation";
-
   private static final String AGGREGATE_KEY = "aggregate";
   private static final String AGGREGATED_VALUE_KEY = "aggregatedValue";
   private static final String GROUP_BY_KEY = "groupBy";
@@ -47,26 +45,27 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create(getLabel(PE_ID))
+    return ProcessingElementBuilder.create("org.streampipes.processors.aggregation.flink.aggregation")
             .category(DataProcessorType.AGGREGATE)
-            .iconUrl(AggregationFlinkConfig.iconBaseUrl + "/Aggregation_Icon_HQ.png")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(
                             EpRequirements.numberReq(),
-                            getLabel(AGGREGATE_KEY),
+                            Labels.withId(AGGREGATE_KEY),
                             PropertyScope.MEASUREMENT_PROPERTY)
                     .build())
             .naryMappingPropertyWithoutRequirement(
-                    getLabel(GROUP_BY_KEY),
+                    Labels.withId(GROUP_BY_KEY),
                     PropertyScope.DIMENSION_PROPERTY)
             .outputStrategy(OutputStrategies.append(EpProperties.doubleEp(
-                    getLabel(AGGREGATED_VALUE_KEY),
+                    Labels.withId(AGGREGATED_VALUE_KEY),
                     "aggregatedValue",
                     "http://schema.org/Number")))
-            .requiredIntegerParameter(getLabel(OUTPUT_EVERY_KEY))
-            .requiredIntegerParameter(getLabel(TIME_WINDOW_KEY))
-            .requiredSingleValueSelection(getLabel(OPERATION_KEY),
+            .requiredIntegerParameter(Labels.withId(OUTPUT_EVERY_KEY))
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW_KEY))
+            .requiredSingleValueSelection(Labels.withId(OPERATION_KEY),
                     Options.from(new Tuple2<>("Average", "AVG"),
                             new Tuple2<>("Sum", "SUM"),
                             new Tuple2<>("Min", "MIN"),
@@ -76,10 +75,6 @@
             .build();
   }
 
-  private Label getLabel(String id) {
-    return Labels.fromResources(RESOURCE_ID, id);
-  }
-
   @Override
   public FlinkDataProcessorRuntime<AggregationParameters> getRuntime(DataProcessorInvocation graph,
                                                                      ProcessingElementParameterExtractor extractor) {
diff --git a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/count/CountController.java b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/count/CountController.java
index 4f3eea1..be8a4a8 100644
--- a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/count/CountController.java
+++ b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/count/CountController.java
@@ -11,31 +11,32 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
 public class CountController extends FlinkDataProcessorDeclarer<CountParameters> {
 
-  private static final String TIME_WINDOW_KEY = "timeWindow";
+  private static final String TIME_WINDOW_KEY = "time-window";
   private static final String SCALE_KEY = "scale";
   private static final String COUNT_MAPPING = "count-mapping";
 
   @Override
   public DataProcessorDescription declareModel() {
 
-    return ProcessingElementBuilder.create("org.streampipes.processors.aggregation.flink.count", "Count Aggregation",
-            "Performs an aggregation based on a given event property and outputs the number of occurrences.")
+    return ProcessingElementBuilder.create("org.streampipes.processors.aggregation.flink.count")
             .category(DataProcessorType.AGGREGATE)
-            .iconUrl(AggregationFlinkConfig.iconBaseUrl + "/Counter_Icon_HQ.png")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(), Labels.from(COUNT_MAPPING, "Field to count", "The field that contains the values which should be counted"), PropertyScope.DIMENSION_PROPERTY)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(),
+                            Labels.withId(COUNT_MAPPING), PropertyScope.DIMENSION_PROPERTY)
                     .build())
             .outputStrategy(OutputStrategies.fixed(EpProperties.stringEp(Labels.empty(), "value", "http://schema.org/Text"), EpProperties.integerEp(Labels.empty(), "countValue",
                     "http://schema.org/Number")))
-            .requiredIntegerParameter(Labels.from(TIME_WINDOW_KEY, "Time Window Size", "Size of the time window " +
-                    "in seconds"))
-            .requiredSingleValueSelection(Labels.from(SCALE_KEY, "Time Window Scale", ""),
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW_KEY))
+            .requiredSingleValueSelection(Labels.withId(SCALE_KEY),
                     Options.from(new Tuple2<>("Hours", "HOURS"),
                             new Tuple2<>("Minutes", "MINUTES"),
                             new Tuple2<>("Seconds", "SECONDS")))
diff --git a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/rate/EventRateController.java b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/rate/EventRateController.java
index 78f9e30..acfcaa4 100644
--- a/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/rate/EventRateController.java
+++ b/streampipes-processors-aggregation-flink/src/main/java/org/streampipes/processors/aggregation/flink/processor/rate/EventRateController.java
@@ -11,7 +11,9 @@
 import org.streampipes.sdk.helpers.EpProperties;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -22,17 +24,17 @@
   @Override
   public DataProcessorDescription declareModel() {
 
-    return ProcessingElementBuilder.create("org.streampipes.processor.aggregation.flink.rate", "Event rate", "Computes current event rate")
+    return ProcessingElementBuilder.create("org.streampipes.processors.aggregation.flink.rate")
             .category(DataProcessorType.AGGREGATE)
-            .iconUrl(AggregationFlinkConfig.getIconUrl("event_rate"))
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
             .outputStrategy(OutputStrategies.fixed(EpProperties.doubleEp(Labels.empty(), "rate",
                     "http://schema.org/Number")))
-            .requiredIntegerParameter(Labels.from(RATE_KEY, "Time Baseline", "Time window size used for calculating the rate" +
-                    "in seconds, also defines the output rate"))
+            .requiredIntegerParameter(Labels.withId(RATE_KEY))
             .supportedFormats(StandardTransportFormat.standardFormat())
             .supportedProtocols(StandardTransportFormat.standardProtocols())
             .build();
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/documentation.md b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/documentation.md
new file mode 100644
index 0000000..20bc25b
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/documentation.md
@@ -0,0 +1,37 @@
+## Aggregation
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Performs different aggregation functions based on a sliding time window (e.g., average, sum, min, max)
+
+***
+
+## Required input
+
+The aggregation processor requires a data stream that has at least one field containing a numerical value.
+
+***
+
+## Configuration
+
+### Group by
+The aaggregation function can be calculated separately (partitioned) by the selected field value. 
+
+### Output every
+The frequency in which aggregated values are sent in seconds.
+
+### Time window
+The size of the time window in seconds
+
+### Aggregated Value
+The field used for calculating the aggregation value.
+
+## Output
+
+This processor appends the latest aggregated value to every input event that arrives.
\ No newline at end of file
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/icon.png b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/icon.png
new file mode 100644
index 0000000..4b06333
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/icon.png
Binary files differ
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/strings.en b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/strings.en
new file mode 100644
index 0000000..38306fe
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.aggregation/strings.en
@@ -0,0 +1,21 @@
+org.streampipes.processors.aggregation.flink.aggregation.title=Aggregation
+org.streampipes.processors.aggregation.flink.aggregation.description=Performs different aggregation functions
+
+aggregate.title=Property Selection
+aggregate.description=Specifies the event property from your stream that should be aggregated.
+
+groupBy.title=Group by
+groupBy.description=Partitions the incoming stream by the selected event properties.
+
+outputEvery.title=Output Frequency
+outputEvery.description=Output values every (seconds)
+
+timeWindow.title=Time Window Size
+timeWindow.description=Size of the time window in seconds
+
+operation.title=Operation
+operation.description=Aggregation operation type
+
+aggregatedValue.title=Aggregated value
+aggregatedValue.description=The calculated aggregation value
+
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/documentation.md b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/documentation.md
new file mode 100644
index 0000000..9edef35
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/documentation.md
@@ -0,0 +1,30 @@
+## Count
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Performs an aggregation based on a given event property and outputs the number of occurrences.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/icon.png b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/icon.png
new file mode 100644
index 0000000..82f2384
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/icon.png
Binary files differ
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/strings.en b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/strings.en
new file mode 100644
index 0000000..a99a1ec
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.count/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.aggregation.flink.count.title=Count Aggregation
+org.streampipes.processors.aggregation.flink.count.description=Performs an aggregation based on a given event property and outputs the number of occurrences.
+
+count-mapping.title=Field to count
+count-mapping.description=The field that contains the values which should be counted
+
+time-window.title=Time Window Size
+time-window.description=Size of the time window
+
+scale.title=Time Window Scale
+scale.description=
\ No newline at end of file
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/documentation.md b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/documentation.md
new file mode 100644
index 0000000..e9c6395
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/documentation.md
@@ -0,0 +1,26 @@
+## Event Rate
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Computes the current event rate. Output is a number representing events per second.
+
+***
+
+## Required input
+
+The event rate processor works with any stream and does not have any specific requirements.
+
+***
+
+## Configuration
+
+### Time Baseline
+Time window size used for calculating the rate in seconds, also defines the output rate
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/icon.png b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/icon.png
new file mode 100644
index 0000000..293d345
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/icon.png
Binary files differ
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/strings.en b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/strings.en
new file mode 100644
index 0000000..5a85231
--- /dev/null
+++ b/streampipes-processors-aggregation-flink/src/main/resources/org.streampipes.processors.aggregation.flink.rate/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.processors.aggregation.flink.rate.title=Event Rate
+org.streampipes.processors.aggregation.flink.rate.description=Computes current event rate. Output is a number representing events per second.
+
+rate.title=Time Baseline
+rate.description=Time window size used for calculating the rate in seconds, also defines the output rate
\ No newline at end of file
diff --git a/streampipes-processors-aggregation-flink/src/main/resources/strings b/streampipes-processors-aggregation-flink/src/main/resources/strings
index 38306fe..e69de29 100644
--- a/streampipes-processors-aggregation-flink/src/main/resources/strings
+++ b/streampipes-processors-aggregation-flink/src/main/resources/strings
@@ -1,21 +0,0 @@
-org.streampipes.processors.aggregation.flink.aggregation.title=Aggregation
-org.streampipes.processors.aggregation.flink.aggregation.description=Performs different aggregation functions
-
-aggregate.title=Property Selection
-aggregate.description=Specifies the event property from your stream that should be aggregated.
-
-groupBy.title=Group by
-groupBy.description=Partitions the incoming stream by the selected event properties.
-
-outputEvery.title=Output Frequency
-outputEvery.description=Output values every (seconds)
-
-timeWindow.title=Time Window Size
-timeWindow.description=Size of the time window in seconds
-
-operation.title=Operation
-operation.description=Aggregation operation type
-
-aggregatedValue.title=Aggregated value
-aggregatedValue.description=The calculated aggregation value
-
diff --git a/streampipes-processors-enricher-flink/pom.xml b/streampipes-processors-enricher-flink/pom.xml
index f4d5586..0d184b7 100644
--- a/streampipes-processors-enricher-flink/pom.xml
+++ b/streampipes-processors-enricher-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/mathop/MathOpController.java b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/mathop/MathOpController.java
index fd04406..6d88e30 100644
--- a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/mathop/MathOpController.java
+++ b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/mathop/MathOpController.java
@@ -21,67 +21,86 @@
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
 import org.streampipes.processors.enricher.flink.config.EnricherFlinkConfig;
-import org.streampipes.processors.enricher.flink.processor.math.operation.*;
+import org.streampipes.processors.enricher.flink.processor.math.operation.Operation;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationAddition;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationDivide;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationModulo;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationMultiply;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationSubtracting;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.helpers.EpProperties;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.SO;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
 public class MathOpController extends FlinkDataProcessorDeclarer<MathOpParameters> {
 
-    private final String RESULT_FIELD = "calculationResult";
-    private final String LEFT_OPERAND = "leftOperand";
-    private final String RIGHT_OPERAND = "rightOperand";
-    private final String OPERATION = "operation";
+  private final String RESULT_FIELD = "calculationResult";
+  private final String LEFT_OPERAND = "leftOperand";
+  private final String RIGHT_OPERAND = "rightOperand";
+  private final String OPERATION = "operation";
 
-    @Override
-    public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.math.mathop",
-                "Math","Performs calculations on event properties (+, -, *, /, %)")
-                .iconUrl(EnricherFlinkConfig.getIconUrl("math-icon"))
-                .category(DataProcessorType.ALGORITHM)
-                .requiredStream(StreamRequirementsBuilder
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.math.mathop")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
+            .category(DataProcessorType.ALGORITHM)
+            .requiredStream(StreamRequirementsBuilder
                     .create()
-                        .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
-                                Labels.from(LEFT_OPERAND, "Left operand", "Select left operand"),
-                                PropertyScope.NONE)
-                        .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
-                                Labels.from(RIGHT_OPERAND, "Right operand", "Select right operand"),
-                                PropertyScope.NONE)
-                        .build())
-                .outputStrategy(
-                        OutputStrategies.append(
-                                EpProperties.numberEp(Labels.empty(), RESULT_FIELD, SO.Number)))
-                .requiredSingleValueSelection(OPERATION, "Select Operation", "", Options.from("+", "-", "/", "*", "%"))
-                .supportedFormats(SupportedFormats.jsonFormat())
-                .supportedProtocols(SupportedProtocols.kafka())
-                .build();
+                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
+                            Labels.withId(LEFT_OPERAND),
+                            PropertyScope.NONE)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
+                            Labels.withId(RIGHT_OPERAND),
+                            PropertyScope.NONE)
+                    .build())
+            .outputStrategy(
+                    OutputStrategies.append(
+                            EpProperties.numberEp(Labels.empty(), RESULT_FIELD, SO.Number)))
+            .requiredSingleValueSelection(Labels.withId(OPERATION), Options.from("+", "-", "/",
+                    "*", "%"))
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka())
+            .build();
+  }
+
+  @Override
+  public FlinkDataProcessorRuntime<MathOpParameters> getRuntime(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+    String leftOperand = extractor.mappingPropertyValue(LEFT_OPERAND);
+    String rightOperand = extractor.mappingPropertyValue(RIGHT_OPERAND);
+    String operation = extractor.selectedSingleValue(OPERATION, String.class);
+
+    Operation arithmeticOperation = null;
+    switch (operation) {
+      case "+":
+        arithmeticOperation = new OperationAddition();
+        break;
+      case "-":
+        arithmeticOperation = new OperationSubtracting();
+        break;
+      case "*":
+        arithmeticOperation = new OperationMultiply();
+        break;
+      case "/":
+        arithmeticOperation = new OperationDivide();
+        break;
+      case "%":
+        arithmeticOperation = new OperationModulo();
     }
 
-    @Override
-    public FlinkDataProcessorRuntime<MathOpParameters> getRuntime(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
-        String leftOperand = extractor.mappingPropertyValue(LEFT_OPERAND);
-        String rightOperand = extractor.mappingPropertyValue(RIGHT_OPERAND);
-        String operation = extractor.selectedSingleValue(OPERATION, String.class);
+    MathOpParameters parameters = new MathOpParameters(graph, arithmeticOperation, leftOperand, rightOperand, RESULT_FIELD);
 
-        Operation arithmeticOperation = null;
-        switch (operation) {
-            case "+": arithmeticOperation = new OperationAddition();
-                break;
-            case "-": arithmeticOperation = new OperationSubtracting();
-                break;
-            case "*": arithmeticOperation = new OperationMultiply();
-                break;
-            case "/": arithmeticOperation = new OperationDivide();
-                break;
-            case "%": arithmeticOperation = new OperationModulo();
-        }
-
-        MathOpParameters parameters = new MathOpParameters(graph, arithmeticOperation, leftOperand, rightOperand, RESULT_FIELD);
-
-        return new MathOpProgram(parameters, EnricherFlinkConfig.INSTANCE.getDebug());
-    }
+    return new MathOpProgram(parameters, EnricherFlinkConfig.INSTANCE.getDebug());
+  }
 }
diff --git a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/staticmathop/StaticMathOpController.java b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/staticmathop/StaticMathOpController.java
index 903dd98..fa24c62 100644
--- a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/staticmathop/StaticMathOpController.java
+++ b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/math/staticmathop/StaticMathOpController.java
@@ -21,66 +21,82 @@
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
 import org.streampipes.processors.enricher.flink.config.EnricherFlinkConfig;
-import org.streampipes.processors.enricher.flink.processor.math.operation.*;
+import org.streampipes.processors.enricher.flink.processor.math.operation.Operation;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationAddition;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationDivide;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationModulo;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationMultiply;
+import org.streampipes.processors.enricher.flink.processor.math.operation.OperationSubtracting;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
 public class StaticMathOpController extends FlinkDataProcessorDeclarer<StaticMathOpParameters> {
 
-    private final String RESULT_FIELD = "calculationResultStatic";
-    private final String LEFT_OPERAND = "leftOperand";
-    private final String RIGHT_OPERAND_VALUE = "rightOperandValue";
-    private final String OPERATION = "operation";
+  private final String RESULT_FIELD = "calculationResultStatic";
+  private final String LEFT_OPERAND = "leftOperand";
+  private final String RIGHT_OPERAND_VALUE = "rightOperandValue";
+  private final String OPERATION = "operation";
 
-    @Override
-    public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.math.staticmathop",
-                "Static Math", "Performs calculation on an event property with a static value (+, -, *, /, %)")
-                 .iconUrl(EnricherFlinkConfig.getIconUrl("math-icon-static"))
-                .category(DataProcessorType.ALGORITHM)
-                .requiredStream(StreamRequirementsBuilder
-                        .create()
-                        .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
-                                Labels.from(LEFT_OPERAND, "Left operand", "Select left operand"),
-                                PropertyScope.NONE)
-                        .build())
-                .requiredFloatParameter(Labels.from(RIGHT_OPERAND_VALUE, "Right operand value",
-                        "Specify the value of the right operand."))
-                .outputStrategy(
-                        OutputStrategies.keep())
-//                                EpProperties.numberEp(Labels.empty(), RESULT_FIELD, SO.Number)))
-                .requiredSingleValueSelection(OPERATION, "Select Operation", "", Options.from("+", "-", "/", "*", "%"))
-                .supportedFormats(SupportedFormats.jsonFormat())
-                .supportedProtocols(SupportedProtocols.kafka())
-                .build();
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.math.staticmathop")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
+            .category(DataProcessorType.ALGORITHM)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
+                            Labels.withId(LEFT_OPERAND),
+                            PropertyScope.NONE)
+                    .build())
+            .requiredFloatParameter(Labels.withId(RIGHT_OPERAND_VALUE))
+            .outputStrategy(
+                    OutputStrategies.keep())
+            .requiredSingleValueSelection(Labels.withId(OPERATION),
+                    Options.from("+", "-", "/", "*", "%"))
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka())
+            .build();
+  }
+
+  @Override
+  public FlinkDataProcessorRuntime<StaticMathOpParameters> getRuntime(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+    String leftOperand = extractor.mappingPropertyValue(LEFT_OPERAND);
+    double rightOperand = extractor.singleValueParameter(RIGHT_OPERAND_VALUE, Double.class);
+    String operation = extractor.selectedSingleValue(OPERATION, String.class);
+
+    Operation arithmeticOperation = null;
+    switch (operation) {
+      case "+":
+        arithmeticOperation = new OperationAddition();
+        break;
+      case "-":
+        arithmeticOperation = new OperationSubtracting();
+        break;
+      case "*":
+        arithmeticOperation = new OperationMultiply();
+        break;
+      case "/":
+        arithmeticOperation = new OperationDivide();
+        break;
+      case "%":
+        arithmeticOperation = new OperationModulo();
     }
 
-    @Override
-    public FlinkDataProcessorRuntime<StaticMathOpParameters> getRuntime(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
-        String leftOperand = extractor.mappingPropertyValue(LEFT_OPERAND);
-        double rightOperand = extractor.singleValueParameter(RIGHT_OPERAND_VALUE, Double.class);
-        String operation = extractor.selectedSingleValue(OPERATION, String.class);
+    StaticMathOpParameters parameters = new StaticMathOpParameters(graph, arithmeticOperation, leftOperand, rightOperand, RESULT_FIELD);
 
-        Operation arithmeticOperation = null;
-        switch (operation) {
-            case "+": arithmeticOperation = new OperationAddition();
-                break;
-            case "-": arithmeticOperation = new OperationSubtracting();
-                break;
-            case "*": arithmeticOperation = new OperationMultiply();
-                break;
-            case "/": arithmeticOperation = new OperationDivide();
-                break;
-            case "%": arithmeticOperation = new OperationModulo();
-        }
+    return new StaticMathOpProgram(parameters, EnricherFlinkConfig.INSTANCE.getDebug());
 
-        StaticMathOpParameters parameters = new StaticMathOpParameters(graph, arithmeticOperation, leftOperand, rightOperand, RESULT_FIELD);
-
-        return new StaticMathOpProgram(parameters, EnricherFlinkConfig.INSTANCE.getDebug());
-
-    }
+  }
 }
diff --git a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/timestamp/TimestampController.java b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/timestamp/TimestampController.java
index 1a53828..5934f9a 100644
--- a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/timestamp/TimestampController.java
+++ b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/timestamp/TimestampController.java
@@ -24,6 +24,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.SO;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -34,10 +35,9 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink" +
-                    ".enrich-timestamp", "Timestamp Enricher",
-            "Appends the current time in ms to the event payload")
-            .iconUrl(EnricherFlinkConfig.getIconUrl("enrich-timestamp-icon"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.timestamp")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
diff --git a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/trigonometry/TrigonometryController.java b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/trigonometry/TrigonometryController.java
index e0434ed..0b320e8 100644
--- a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/trigonometry/TrigonometryController.java
+++ b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/trigonometry/TrigonometryController.java
@@ -25,6 +25,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.SO;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -38,20 +39,21 @@
 
     @Override
     public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.trigonometry",
-                "Trigonometry","Performs Trigonometric function on event properties")
-                .iconUrl(EnricherFlinkConfig.getIconUrl("trigonometry_icon"))
+        return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.trigonometry")
+                .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+                .withLocales(Locales.EN)
                 .category(DataProcessorType.ALGORITHM)
                 .requiredStream(StreamRequirementsBuilder
                         .create()
                         .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
-                                Labels.from(OPERAND, "Alpha", "Select the alpha parameter"),
+                                Labels.withId(OPERAND),
                                 PropertyScope.NONE)
                         .build())
                 .outputStrategy(
                         OutputStrategies.append(
                                 EpProperties.numberEp(Labels.empty(), RESULT_FIELD, SO.Number)))
-                .requiredSingleValueSelection(Labels.from(OPERATION, "Select function", ""), Options.from("sin(a)", "cos(a)", "tan(a)" ))
+                .requiredSingleValueSelection(Labels.withId(OPERATION),
+                        Options.from("sin(a)", "cos(a)", "tan(a)" ))
                 .supportedFormats(SupportedFormats.jsonFormat())
                 .supportedProtocols(SupportedProtocols.kafka())
                 .build();
diff --git a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/urldereferencing/UrlDereferencingController.java b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/urldereferencing/UrlDereferencingController.java
index f274b16..253275f 100644
--- a/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/urldereferencing/UrlDereferencingController.java
+++ b/streampipes-processors-enricher-flink/src/main/java/org/streampipes/processors/enricher/flink/processor/urldereferencing/UrlDereferencingController.java
@@ -25,6 +25,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.SO;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -36,14 +37,14 @@
 
     @Override
     public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.urldereferencing",
-                "URL Dereferencing","Append the html page as a string to event")
-                .iconUrl(EnricherFlinkConfig.getIconUrl("html_icon"))
+        return ProcessingElementBuilder.create("org.streampipes.processors.enricher.flink.processor.urldereferencing")
+                .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+                .withLocales(Locales.EN)
                 .category(DataProcessorType.ENRICH)
                 .requiredStream(StreamRequirementsBuilder
                         .create()
                         .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(),
-                                Labels.from(URL, "URL", "The server URL"),
+                                Labels.withId(URL),
                                 PropertyScope.NONE)
                         .build())
                 .outputStrategy(
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/documentation.md b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/documentation.md
new file mode 100644
index 0000000..2544868
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/documentation.md
@@ -0,0 +1,32 @@
+## Math
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Performs calculations on event properties (+, -, *, /, %).
+
+***
+
+## Required input
+The math processor works with any event that has at least one field containing a numerical value.
+
+***
+
+## Configuration
+
+### Left operand
+The field from the input event that should be used as the left operand.
+
+### Right operand
+The field from the input event that should be used as the right operand.
+
+### Operation
+The math operation that should be performed.
+
+## Output
+The processor appends the calculation result to each input event.
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/icon.png b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/icon.png
new file mode 100644
index 0000000..4da2789
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/icon.png
Binary files differ
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/strings.en b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/strings.en
new file mode 100644
index 0000000..5197140
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.mathop/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.enricher.flink.processor.math.mathop.title=Math
+org.streampipes.processors.enricher.flink.processor.math.mathop.description=Performs calculations on event properties (+, -, *, /, %)
+
+leftOperand.title=Left operand
+leftOperand.description=Select left operand
+
+rightOperand.title=Right operand
+rightOperand.description=Select right operand
+
+operation.title=Select Operation
+operation.description=
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/documentation.md b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/documentation.md
new file mode 100644
index 0000000..e5b62b0
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/documentation.md
@@ -0,0 +1,32 @@
+## Static Math
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Performs calculation on an event property with a static value (+, -, *, /, %).
+
+***
+
+## Required input
+The math processor works with any event that has at least one field containing a numerical value.
+
+***
+
+## Configuration
+
+### Left operand
+The field from the input event that should be used as the left operand.
+
+### Right operand value
+Specify the value of the right operand.
+
+### Operation
+The math operation that should be performed.
+
+## Output
+The processor appends the calculation result to each input event.
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/icon.png b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/icon.png
new file mode 100644
index 0000000..6146d8d
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/icon.png
Binary files differ
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/strings.en b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/strings.en
new file mode 100644
index 0000000..25ea72e
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.math.staticmathop/strings.en
@@ -0,0 +1,10 @@
+org.streampipes.processors.enricher.flink.processor.math.staticmathop.title=Static Math
+org.streampipes.processors.enricher.flink.processor.math.staticmathop.description=Performs calculation on an event property with a static value (+, -, *, /, %)
+
+leftOperand.title=Left operand
+leftOperand.description=Select left operand
+
+rightOperandValue.title=Right operand value
+rightOperandValue.description=Specify the value of the right operand.
+
+operation.title=Select operation
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/documentation.md b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/documentation.md
new file mode 100644
index 0000000..3313a95
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/documentation.md
@@ -0,0 +1,32 @@
+## Trigonometry
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Performs Trigonometric functions (sin, cos, tan) on event properties.
+
+***
+
+## Required input
+The trigonometry processor works with any event that has at least one field containing a numerical value.
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### Alpha
+The field that should be used for calculating the trigonometric function.
+
+
+### Operation
+The trigonometric function that should be calculated.
+
+## Output
+The processor appends the calculation result to each input event.
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/icon.png b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/icon.png
new file mode 100644
index 0000000..77fc667
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/icon.png
Binary files differ
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/strings.en b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/strings.en
new file mode 100644
index 0000000..bd88f7a
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.trigonometry/strings.en
@@ -0,0 +1,9 @@
+org.streampipes.processors.enricher.flink.processor.trigonometry.title=Trigonometry Functions
+org.streampipes.processors.enricher.flink.processor.trigonometry.description=Performs Trigonometric functions on event properties
+
+operand.title=Alpha
+operand.description=Select the alpha parameter
+
+operation.title=Operation
+operation.description=
+
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/documentation.md b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/documentation.md
new file mode 100644
index 0000000..9bf7d96
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/documentation.md
@@ -0,0 +1,27 @@
+## URL Dereferencing
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Parses and appends the html page as a string to event.
+
+***
+
+## Required input
+The URL Dereferencing processor requires an input stream that provides an input field of type 'string', representing 
+the URL to dereference.
+
+***
+
+## Configuration
+
+### URL
+The field containing the URL to dereference.
+
+## Output
+The processor appends the extracted HTML page to each input event.
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/icon.png b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/icon.png
new file mode 100644
index 0000000..ba5d35b
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/icon.png
Binary files differ
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/strings.en b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/strings.en
new file mode 100644
index 0000000..323e492
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.processor.urldereferencing/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.processors.enricher.flink.processor.urldereferencing.title=URL Dereferencing
+org.streampipes.processors.enricher.flink.processor.urldereferencing.description=Append the html page as a string to event
+
+url.title=URL
+url.description=The server URL
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/documentation.md b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/documentation.md
new file mode 100644
index 0000000..0e1f29b
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/documentation.md
@@ -0,0 +1,24 @@
+## Timestamp Enricher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+Appends the current time in ms to the event payload.
+
+***
+
+## Required input
+The timestamp enricher works with any input event.
+
+***
+
+## Configuration
+
+(no further configuration required)
+
+## Output
+This processor appends the current system time to every input event.
\ No newline at end of file
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/icon.png b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/icon.png
new file mode 100644
index 0000000..a4fa6e6
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/icon.png
Binary files differ
diff --git a/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/strings.en b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/strings.en
new file mode 100644
index 0000000..18f0384
--- /dev/null
+++ b/streampipes-processors-enricher-flink/src/main/resources/org.streampipes.processors.enricher.flink.timestamp/strings.en
@@ -0,0 +1,2 @@
+org.streampipes.processors.enricher.flink.timestamp.title=Timestamp Enricher
+org.streampipes.processors.enricher.flink.timestamp.description=Appends the current time in ms to the event payload
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/pom.xml b/streampipes-processors-filters-jvm/pom.xml
index 34385e6..b549536 100644
--- a/streampipes-processors-filters-jvm/pom.xml
+++ b/streampipes-processors-filters-jvm/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/compose/ComposeController.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/compose/ComposeController.java
index 9b0a273..2868068 100644
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/compose/ComposeController.java
+++ b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/compose/ComposeController.java
@@ -23,9 +23,11 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
@@ -35,9 +37,10 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.merger",
-            "Compose", "Merges two event streams ")
+    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.compose")
             .category(DataProcessorType.TRANSFORM)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .iconUrl(FiltersJvmConfig.getIconUrl("projection"))
             .requiredStream(StreamRequirementsBuilder
                     .create()
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilter.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilter.java
deleted file mode 100644
index e95c2ec..0000000
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilter.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 FZI Forschungszentrum Informatik
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package org.streampipes.processors.filters.jvm.processor.listfilter;
-
-public class ListFilter {
-}
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilterController.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilterController.java
deleted file mode 100644
index 5974d04..0000000
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilterController.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 FZI Forschungszentrum Informatik
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package org.streampipes.processors.filters.jvm.processor.listfilter;
-
-public class ListFilterController {
-}
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilterParameters.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilterParameters.java
deleted file mode 100644
index c807023..0000000
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/listfilter/ListFilterParameters.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 FZI Forschungszentrum Informatik
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package org.streampipes.processors.filters.jvm.processor.listfilter;
-
-public class ListFilterParameters {
-}
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilter.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilter.java
index 5b4370c..e6b49ed 100644
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilter.java
+++ b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilter.java
@@ -42,7 +42,7 @@
     Double threshold = params.getThreshold();
 
     if (params.getNumericalOperator() == NumericalOperator.EQ) {
-      satisfiesFilter = (value == threshold);
+      satisfiesFilter = (Math.abs(value - threshold) < 0.000001);
     } else if (params.getNumericalOperator() == NumericalOperator.GE) {
       satisfiesFilter = (value >= threshold);
     } else if (params.getNumericalOperator() == NumericalOperator.GT) {
@@ -51,6 +51,8 @@
       satisfiesFilter = (value <= threshold);
     } else if (params.getNumericalOperator() == NumericalOperator.LT) {
       satisfiesFilter = (value < threshold);
+    } else if (params.getNumericalOperator() == NumericalOperator.IE) {
+      satisfiesFilter = (Math.abs(value - threshold) > 0.000001);
     }
 
     if (satisfiesFilter) {
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilterController.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilterController.java
index f43ba9f..0c2d856 100644
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilterController.java
+++ b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalFilterController.java
@@ -25,10 +25,12 @@
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.Options;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
@@ -40,17 +42,19 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.numericalfilter", "Numerical Filter", "Numerical Filter Description")
+    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.numericalfilter")
             .category(DataProcessorType.FILTER)
-            .providesAssets()
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(), Labels.from(NUMBER_MAPPING, "Specifies the field name where the filter operation should" +
-                    " be applied on.", ""), PropertyScope.NONE).build())
+                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
+                            Labels.withId(NUMBER_MAPPING),
+                            PropertyScope.NONE).build())
             .outputStrategy(OutputStrategies.keep())
-            .requiredSingleValueSelection(Labels.from(OPERATION, "Filter Operation", "Specifies the filter " +
-                    "operation that should be applied on the field"), Options.from("<", "<=", ">", ">=", "=="))
-            .requiredFloatParameter(Labels.from(VALUE, "Threshold value", "Specifies a threshold value."), "number")
+            .requiredSingleValueSelection(Labels.withId(OPERATION), Options.from("<", "<=", ">",
+                    ">=", "==", "!="))
+            .requiredFloatParameter(Labels.withId(VALUE), NUMBER_MAPPING)
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
             .build();
@@ -66,13 +70,15 @@
     String operation = "GT";
 
     if (stringOperation.equals("<=")) {
-      operation = "LT";
-    } else if (stringOperation.equals("<")) {
       operation = "LE";
+    } else if (stringOperation.equals("<")) {
+      operation = "LT";
     } else if (stringOperation.equals(">=")) {
       operation = "GE";
     } else if (stringOperation.equals("==")) {
       operation = "EQ";
+    } else if (stringOperation.equals("!=")) {
+      operation = "IE";
     }
 
     String filterProperty = extractor.mappingPropertyValue(NUMBER_MAPPING);
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalOperator.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalOperator.java
index 05cbbd9..24480ac 100644
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalOperator.java
+++ b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/numericalfilter/NumericalOperator.java
@@ -17,5 +17,6 @@
 package org.streampipes.processors.filters.jvm.processor.numericalfilter;
 
 public enum NumericalOperator {
-GE, GT, LE, LT, EQ
+  // Greater/Equal, Greater than, Less/Equal, Less than, Equal, Inequal
+  GE, GT, LE, LT, EQ, IE
 }
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/projection/ProjectionController.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/projection/ProjectionController.java
index e073785..90a2259 100644
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/projection/ProjectionController.java
+++ b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/projection/ProjectionController.java
@@ -20,14 +20,15 @@
 import org.streampipes.model.DataProcessorType;
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.processors.filters.jvm.config.FiltersJvmConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
@@ -37,9 +38,10 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.project", "Projection", "Outputs a selectable subset of an input event type")
+    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.project")
             .category(DataProcessorType.TRANSFORM)
-            .iconUrl(FiltersJvmConfig.getIconUrl("projection"))
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
diff --git a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/textfilter/TextFilterController.java b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/textfilter/TextFilterController.java
index 21a210f..2b85a22 100644
--- a/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/textfilter/TextFilterController.java
+++ b/streampipes-processors-filters-jvm/src/main/java/org/streampipes/processors/filters/jvm/processor/textfilter/TextFilterController.java
@@ -20,16 +20,17 @@
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.filters.jvm.config.FiltersJvmConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.Options;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
@@ -41,16 +42,18 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.textfilter", "Text Filter", "Text Filter Description")
-            .iconUrl(FiltersJvmConfig.getIconUrl("Textual_Filter_Icon_HQ"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.filters.jvm.textfilter")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .category(DataProcessorType.FILTER)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(EpRequirements
-                    .stringReq(), Labels.from(MAPPING_PROPERTY_ID, "Select Text Property", ""), PropertyScope.NONE)
+                    .stringReq(), Labels.withId(MAPPING_PROPERTY_ID), PropertyScope.NONE)
                     .build())
-            .requiredSingleValueSelection(Labels.from(OPERATION_ID, "Select Operation", ""), Options.from("MATCHES", "CONTAINS"))
-            .requiredTextParameter(Labels.from(KEYWORD_ID, "Select Keyword", ""), "text")
+            .requiredSingleValueSelection(Labels.withId(OPERATION_ID), Options.from("MATCHES",
+                    "CONTAINS"))
+            .requiredTextParameter(Labels.withId(KEYWORD_ID), "text")
             .outputStrategy(OutputStrategies.keep())
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/documentation.md b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/documentation.md
new file mode 100644
index 0000000..7d1b348
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/documentation.md
@@ -0,0 +1,26 @@
+## Compose
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Merges two event streams. Any time, a new input event arrives, it is merged with the last input event from the other 
+event stream and forwarded.
+
+***
+
+## Required input
+The Compose processor does not have any specific input requirements.
+
+***
+
+## Configuration
+
+(no further configuration required)
+
+## Output
+The compose processor has a configurable output that can be selected by the user at pipeline modeling time.
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/icon.png b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/icon.png
new file mode 100644
index 0000000..4b06333
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/icon.png
Binary files differ
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/strings.en b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/strings.en
new file mode 100644
index 0000000..69a6237
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.compose/strings.en
@@ -0,0 +1,2 @@
+org.streampipes.processors.filters.jvm.compose.title=Compose
+org.streampipes.processors.filters.jvm.compose.description=Merges two event streams
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/documentation.md b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/documentation.md
index 2f3a185..337ec45 100644
--- a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/documentation.md
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/documentation.md
@@ -1,22 +1,32 @@
 ## Numerical Filter
 
 <p align="center"> 
-    <img src="icon.png" width="30%"/>
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
 </p>
 
+***
+
 ## Description
+The Numerical Filter processor filters numerical values based on a given threshold.
 
-Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.   
+***
 
-Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.   
+## Required input
+The processor works with any input event that has one field containing a numerical value.
 
-Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.   
+***
 
-Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.   
+## Configuration
 
-Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.   
-
-At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur
+### Field
+Specifies the field name where the filter operation should be applied on.
 
 
-## Configuration
\ No newline at end of file
+### Operation
+Specifies the filter operation that should be applied on the field.
+
+### Threshold value
+Specifies the threshold value.
+
+## Output
+The processor outputs the input event if it satisfies the filter expression.
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/strings.en b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/strings.en
new file mode 100644
index 0000000..a96e975
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.numericalfilter/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.filters.jvm.numericalfilter.title=Numerical Filter
+org.streampipes.processors.filters.jvm.numericalfilter.description=Numerical Filter Description
+
+number-mapping.title=Field
+number-mapping.description=Specifies the field name where the filter operation should be applied on.
+
+operation.title=Filter Operation
+operation.description=Specifies the filter operation that should be applied on the field
+
+value.title=Threshold value
+value.description=Specifies a threshold value
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/documentation.md b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/documentation.md
new file mode 100644
index 0000000..91916df
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/documentation.md
@@ -0,0 +1,24 @@
+## Projection
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+Outputs a selectable subset of an input event type.
+
+***
+
+## Required input
+The project processor works with any input event stream.
+
+***
+
+## Configuration
+
+(no further configuration required)
+
+## Output
+The output depends on the fields selected at pipeline development time.
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/icon.png b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/icon.png
new file mode 100644
index 0000000..fa6e81a
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/icon.png
Binary files differ
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/strings.en b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/strings.en
new file mode 100644
index 0000000..30807a0
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.project/strings.en
@@ -0,0 +1,2 @@
+org.streampipes.processors.filters.jvm.project.title=Projection
+org.streampipes.processors.filters.jvm.project.description=Outputs a selectable subset of an input event type
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/documentation.md b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/documentation.md
new file mode 100644
index 0000000..7b5eb42
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/documentation.md
@@ -0,0 +1,29 @@
+## Text Filter
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+The Text Filter processor filters text values based on a given string.
+
+***
+
+## Required input
+The processor works with any input event that has one field containing a text.
+
+***
+
+## Configuration
+
+### Text Field
+The field containing the text that should be filtered.
+
+
+### Operation
+The operation used by the filter processor (equals or matches)
+
+## Output
+The processor outputs the input event if it satisfies the filter expression.
\ No newline at end of file
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/icon.png b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/icon.png
new file mode 100644
index 0000000..a8228f7
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/icon.png
Binary files differ
diff --git a/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/strings.en b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/strings.en
new file mode 100644
index 0000000..f09f40f
--- /dev/null
+++ b/streampipes-processors-filters-jvm/src/main/resources/org.streampipes.processors.filters.jvm.textfilter/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.filters.jvm.textfilter.title=Text Filter
+org.streampipes.processors.filters.jvm.textfilter.description=Text Filter Description
+
+text.title=Select Text Field
+text.description=
+
+operation.title=Select Operation
+operation.description=
+
+keyword.title=Select Keyword
+keyword.description=
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/pom.xml b/streampipes-processors-filters-siddhi/pom.xml
index acad5db..28e4002 100644
--- a/streampipes-processors-filters-siddhi/pom.xml
+++ b/streampipes-processors-filters-siddhi/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/FiltersSiddhiInit.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/FiltersSiddhiInit.java
index 82f6477..c0189c7 100644
--- a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/FiltersSiddhiInit.java
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/FiltersSiddhiInit.java
@@ -22,14 +22,16 @@
 import org.streampipes.messaging.jms.SpJmsProtocolFactory;
 import org.streampipes.messaging.kafka.SpKafkaProtocolFactory;
 import org.streampipes.processors.siddhi.config.FilterSiddhiConfig;
-import org.streampipes.processors.siddhi.filter.NumericalFilterController;
+import org.streampipes.processors.siddhi.stop.StreamStopController;
+import org.streampipes.processors.siddhi.trend.TrendController;
 
 public class FiltersSiddhiInit extends StandaloneModelSubmitter {
 
   public static void main(String[] args) {
     DeclarersSingleton
             .getInstance()
-            .add(new NumericalFilterController());
+            .add(new TrendController())
+            .add(new StreamStopController());
 
     DeclarersSingleton.getInstance().registerDataFormat(new JsonDataFormatFactory());
     DeclarersSingleton.getInstance().registerProtocol(new SpKafkaProtocolFactory());
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilter.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilter.java
index 5f6ffbb..9057445 100644
--- a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilter.java
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilter.java
@@ -23,7 +23,8 @@
 
   @Override
   protected String fromStatement(List<String> inputStreamNames, NumericalFilterParameters params) {
-    return "from " +inputStreamNames.get(0) +"[" +params.getFilterProperty() +"<" +params.getThreshold() +"]";
+    String filterProperty = prepareName(params.getFilterProperty());
+    return "from " + inputStreamNames.get(0) +"[" + filterProperty +"<" + params.getThreshold() +"]";
   }
 
   @Override
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilterController.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilterController.java
index 0938615..c29a116 100644
--- a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilterController.java
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/filter/NumericalFilterController.java
@@ -23,6 +23,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
@@ -33,6 +34,25 @@
   private static final String OPERATION = "operation";
 
   @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.numericalfilter")
+            .category(DataProcessorType.FILTER)
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
+                            Labels.withId(NUMBER_MAPPING), PropertyScope.NONE).build())
+            .outputStrategy(OutputStrategies.keep())
+            .requiredSingleValueSelection(Labels.withId(OPERATION), Options.from("<", "<=", ">",
+                    ">=", "=="))
+            .requiredFloatParameter(Labels.withId(VALUE), NUMBER_MAPPING)
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .build();
+  }
+
+  @Override
   public ConfiguredEventProcessor<NumericalFilterParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
 
     Double threshold = extractor.singleValueParameter(VALUE, Double.class);
@@ -59,22 +79,4 @@
     return new ConfiguredEventProcessor<>(staticParam, NumericalFilter::new);
   }
 
-  @Override
-  public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.numericalfilter", "Numerical Filter", "Numerical Filter Description")
-            .category(DataProcessorType.FILTER)
-            .iconUrl("Numerical_Filter_Icon_HQ")
-            .requiredStream(StreamRequirementsBuilder
-                    .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(), Labels.from(NUMBER_MAPPING, "Specifies the field name where the filter operation should" +
-                            " be applied " +
-                            "on.", ""), PropertyScope.NONE).build())
-            .outputStrategy(OutputStrategies.keep())
-            .requiredSingleValueSelection(Labels.from(OPERATION, "Filter Operation", "Specifies the filter " +
-                    "operation that should be applied on the field"), Options.from("<", "<=", ">", ">=", "=="))
-            .requiredFloatParameter(Labels.from(VALUE, "Threshold value", "Specifies a threshold value."), NUMBER_MAPPING)
-            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-            .supportedFormats(SupportedFormats.jsonFormat())
-            .build();
-  }
 }
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/Frequency.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/Frequency.java
new file mode 100644
index 0000000..5237635
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/Frequency.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.frequency;
+
+import org.streampipes.wrapper.siddhi.engine.SiddhiEventEngine;
+
+import java.util.List;
+
+public class Frequency extends SiddhiEventEngine<FrequencyParameters> {
+
+  @Override
+  protected String fromStatement(List<String> inputStreamNames, FrequencyParameters params) {
+            return "from every not " + inputStreamNames.get(0) + " for " + params.getDuration() + " sec";
+  }
+
+  @Override
+  protected String selectStatement(FrequencyParameters params) {
+    return "select *";
+  }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/FrequencyController.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/FrequencyController.java
new file mode 100644
index 0000000..f4035b1
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/FrequencyController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.frequency;
+
+import org.streampipes.model.DataProcessorType;
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+public class FrequencyController extends StandaloneEventProcessingDeclarer<FrequencyParameters> {
+
+  private static final String DURATION = "duration";
+  private static final String TIME_UNIT = "timeUnit";
+
+
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.frequency")
+            .category(DataProcessorType.FILTER)
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .requiredSingleValueSelection(Labels.withId(TIME_UNIT), Options.from("sec", "min", "hrs"))
+            .outputStrategy(OutputStrategies.custom(true))
+            .requiredIntegerParameter(Labels.withId(DURATION))
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<FrequencyParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+
+    int duration = extractor.singleValueParameter(DURATION, Integer.class);
+    String timeUnit = extractor.selectedSingleValue(TIME_UNIT, String.class);
+
+    FrequencyParameters staticParam = new FrequencyParameters(graph, duration, timeUnit);
+
+    return new ConfiguredEventProcessor<>(staticParam, Frequency::new);
+  }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/FrequencyParameters.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/FrequencyParameters.java
new file mode 100644
index 0000000..6980019
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequency/FrequencyParameters.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.siddhi.frequency;
+
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
+
+public class FrequencyParameters extends EventProcessorBindingParams {
+
+  private int duration;
+  private String timeUnit;
+
+  public FrequencyParameters(DataProcessorInvocation graph, int duration, String timeUnit) {
+    super(graph);
+    this.duration = duration;
+    this.timeUnit = timeUnit;
+  }
+
+  public int getDuration() {
+    return duration;
+  }
+
+  public void setDuration(int duration) {
+    this.duration = duration;
+  }
+
+  public String getTimeUnit() {
+    return timeUnit;
+  }
+
+  public void setTimeUnit(String timeUnit) {
+    this.timeUnit = timeUnit;
+  }
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChange.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChange.java
new file mode 100644
index 0000000..1fe1f8a
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChange.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.frequencychange;
+
+import org.streampipes.wrapper.siddhi.engine.SiddhiEventEngine;
+
+import java.util.List;
+
+public class FrequencyChange extends SiddhiEventEngine<FrequencyChangeParameters> {
+
+  @Override
+  protected String fromStatement(List<String> inputStreamNames, FrequencyChangeParameters params) {
+            return "from every not " + inputStreamNames.get(0) + " for " + params.getDuration() + " sec";
+  }
+
+  @Override
+  protected String selectStatement(FrequencyChangeParameters params) {
+    return "select *";
+  }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChangeController.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChangeController.java
new file mode 100644
index 0000000..ae9cf33
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChangeController.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.frequencychange;
+
+import org.streampipes.model.DataProcessorType;
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+public class FrequencyChangeController extends StandaloneEventProcessingDeclarer<FrequencyChangeParameters> {
+
+  private static final String DURATION = "duration";
+  private static final String TIME_UNIT = "timeUnit";
+  private static final String INCREASE = "increase";
+
+
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.frequencychange")
+            .category(DataProcessorType.FILTER)
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .requiredSingleValueSelection(Labels.withId(TIME_UNIT), Options.from("sec", "min",
+                    "hrs"))
+            .requiredIntegerParameter(Labels.withId(INCREASE), 0, 500, 1)
+            .outputStrategy(OutputStrategies.custom(true))
+            .requiredIntegerParameter(Labels.withId(DURATION))
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<FrequencyChangeParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+
+    int duration = extractor.singleValueParameter(DURATION, Integer.class);
+    String timeUnit = extractor.selectedSingleValue(TIME_UNIT, String.class);
+    int increase = extractor.selectedSingleValue(INCREASE, Integer.class);
+
+    FrequencyChangeParameters staticParam = new FrequencyChangeParameters(graph, duration, timeUnit, increase);
+
+    return new ConfiguredEventProcessor<>(staticParam, FrequencyChange::new);
+  }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChangeParameters.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChangeParameters.java
new file mode 100644
index 0000000..6560280
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/frequencychange/FrequencyChangeParameters.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.siddhi.frequencychange;
+
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
+
+public class FrequencyChangeParameters extends EventProcessorBindingParams {
+
+  private int duration;
+  private String timeUnit;
+  private int increase;
+
+
+  public FrequencyChangeParameters(DataProcessorInvocation graph, int duration, String timeUnit, int increase) {
+    super(graph);
+    this.duration = duration;
+    this.timeUnit = timeUnit;
+    this.increase = increase;
+  }
+
+  public int getDuration() {
+    return duration;
+  }
+
+  public void setDuration(int duration) {
+    this.duration = duration;
+  }
+
+  public String getTimeUnit() {
+    return timeUnit;
+  }
+
+  public void setTimeUnit(String timeUnit) {
+    this.timeUnit = timeUnit;
+  }
+
+  public int getIncrease() {
+    return increase;
+  }
+
+  public void setIncrease(int increase) {
+    this.increase = increase;
+  }
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/Sequence.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/Sequence.java
new file mode 100644
index 0000000..078fcf2
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/Sequence.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.sequence;
+
+import org.streampipes.wrapper.siddhi.engine.SiddhiEventEngine;
+
+import java.util.List;
+
+public class Sequence extends SiddhiEventEngine<SequenceParameters> {
+
+  @Override
+  protected String fromStatement(List<String> inputStreamNames, SequenceParameters params) {
+
+//    from every (e1=MaterialSupplyStream) -> e2=MaterialConsumptionStream within 10 min
+
+//      return "from every(e1=" + inputStreamNames.get(0) + ") -> not e2=" + inputStreamNames.get(0) + " for " + params.getDuration() + " sec";
+//    return "define stream Test(timestamp LONG,message STRING);\n" +
+            return "from every not " + inputStreamNames.get(0) + " for " + params.getDuration() + " sec";
+  }
+
+  @Override
+  protected String selectStatement(SequenceParameters params) {
+//    return getCustomOutputSelectStatement(params.getGraph());
+    return "select *";
+//    return "select currentTimeMillis() as s0timestamp, 'Customer has not arrived' as message";
+  }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/SequenceController.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/SequenceController.java
new file mode 100644
index 0000000..276a13a
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/SequenceController.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.sequence;
+
+import org.streampipes.model.DataProcessorType;
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+public class SequenceController extends StandaloneEventProcessingDeclarer<SequenceParameters> {
+
+  private static final String Duration = "duration";
+
+
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.sequence")
+            .category(DataProcessorType.FILTER)
+            .withAssets(Assets.DOCUMENTATION)
+            .withLocales(Locales.EN)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .outputStrategy(OutputStrategies.custom(true))
+            .requiredIntegerParameter(Labels.withId(Duration))
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<SequenceParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+
+    int duration = extractor.singleValueParameter(Duration, Integer.class);
+
+    SequenceParameters staticParam = new SequenceParameters(graph, duration);
+
+    return new ConfiguredEventProcessor<>(staticParam, Sequence::new);
+  }
+
+}
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationParameters.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/SequenceParameters.java
similarity index 62%
copy from streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationParameters.java
copy to streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/SequenceParameters.java
index 28ef98a..0c0d3af 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationParameters.java
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/sequence/SequenceParameters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,21 +14,26 @@
  * limitations under the License.
  *
  */
-package org.streampipes.processors.imageprocessing.jvm.processor.imagerectification;
+
+package org.streampipes.processors.siddhi.sequence;
 
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
 
-public class ImageRectificationParameters extends EventProcessorBindingParams {
+public class SequenceParameters extends EventProcessorBindingParams {
 
-  private String imageProperty;
+  private int duration;
 
-  public ImageRectificationParameters(DataProcessorInvocation graph, String imageProperty) {
+  public SequenceParameters(DataProcessorInvocation graph, int duration) {
     super(graph);
-    this.imageProperty = imageProperty;
+    this.duration = duration;
   }
 
-  public String getImageProperty() {
-    return imageProperty;
+  public int getDuration() {
+    return duration;
+  }
+
+  public void setDuration(int duration) {
+    this.duration = duration;
   }
 }
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStop.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStop.java
new file mode 100644
index 0000000..06bd553
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStop.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.stop;
+
+import org.streampipes.wrapper.siddhi.engine.SiddhiEventEngine;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class StreamStop extends SiddhiEventEngine<StreamStopParameters> {
+
+  public StreamStop() {
+    super();
+  }
+
+  @Override
+  protected String fromStatement(List<String> inputStreamNames, StreamStopParameters params) {
+    return "define stream Test(timestamp LONG,message STRING);\n" +
+            "from every not " + inputStreamNames.get(0) + " for " + params.getDuration() + " sec";
+  }
+
+  @Override
+  protected String selectStatement(StreamStopParameters params) {
+      setSortedEventKeys(Arrays.asList("timestamp", "message"));
+    return "select currentTimeMillis() as timestamp, 'Event stream has stopped' as message";
+  }
+
+
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStopController.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStopController.java
new file mode 100644
index 0000000..a82a5ff
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStopController.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.stop;
+
+import org.streampipes.model.DataProcessorType;
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.EpProperties;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+import java.util.Arrays;
+
+public class StreamStopController extends StandaloneEventProcessingDeclarer<StreamStopParameters> {
+
+  private static final String Duration = "duration";
+  private static final String Message = "message";
+
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.stop")
+            .withLocales(Locales.EN)
+            .category(DataProcessorType.FILTER)
+            .withAssets(Assets.DOCUMENTATION)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .outputStrategy(OutputStrategies.fixed(
+                    Arrays.asList(
+                            EpProperties.timestampProperty("timestamp"),
+                            EpProperties.stringEp(Labels.withId(Message),
+                                    "message", "http://schema.org/text")
+                    )
+            ))
+            .requiredIntegerParameter(Labels.withId(Duration))
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<StreamStopParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+
+    int duration = extractor.singleValueParameter(Duration, Integer.class);
+
+    StreamStopParameters staticParam = new StreamStopParameters(graph, duration);
+
+    return new ConfiguredEventProcessor<>(staticParam, StreamStop::new);
+  }
+
+}
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationParameters.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStopParameters.java
similarity index 62%
rename from streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationParameters.java
rename to streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStopParameters.java
index 28ef98a..0071dbd 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationParameters.java
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/stop/StreamStopParameters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,21 +14,26 @@
  * limitations under the License.
  *
  */
-package org.streampipes.processors.imageprocessing.jvm.processor.imagerectification;
+
+package org.streampipes.processors.siddhi.stop;
 
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
 
-public class ImageRectificationParameters extends EventProcessorBindingParams {
+public class StreamStopParameters extends EventProcessorBindingParams {
 
-  private String imageProperty;
+  private int duration;
 
-  public ImageRectificationParameters(DataProcessorInvocation graph, String imageProperty) {
+  public StreamStopParameters(DataProcessorInvocation graph, int duration) {
     super(graph);
-    this.imageProperty = imageProperty;
+    this.duration = duration;
   }
 
-  public String getImageProperty() {
-    return imageProperty;
+  public int getDuration() {
+    return duration;
+  }
+
+  public void setDuration(int duration) {
+    this.duration = duration;
   }
 }
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/Trend.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/Trend.java
new file mode 100644
index 0000000..a9db394
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/Trend.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.trend;
+
+import org.streampipes.wrapper.siddhi.engine.SiddhiEventEngine;
+
+import java.util.List;
+
+public class Trend extends SiddhiEventEngine<TrendParameters> {
+
+  @Override
+  protected String fromStatement(List<String> inputStreamNames, TrendParameters params) {
+      String mappingProperty = prepareName(params.getMapping());
+      int duration = params.getDuration();
+      String inequaloperator;
+      String operator;
+
+      double increase = Double.valueOf(params.getIncrease());
+      increase = (increase / 100) + 1;
+
+      if (params.getOperation() == TrendOperator.INCREASE) {
+          inequaloperator = "<=";
+          operator = "/";
+
+      } else {
+          inequaloperator = ">=";
+          operator = "*";
+      }
+
+      String s = "from every(e1=" + inputStreamNames.get(0) +") -> e2=" +inputStreamNames.get(0) + "[e1." + mappingProperty + inequaloperator + mappingProperty + operator + increase + "]<1>" +
+            " within " + duration + " sec";
+
+    return s;
+  }
+
+  @Override
+  protected String selectStatement(TrendParameters params) {
+      return getCustomOutputSelectStatement(params.getGraph());
+  }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendController.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendController.java
new file mode 100644
index 0000000..1d699d8
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.streampipes.processors.siddhi.trend;
+
+import org.streampipes.model.DataProcessorType;
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.model.schema.PropertyScope;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+public class TrendController extends StandaloneEventProcessingDeclarer<TrendParameters> {
+
+    private static final String Mapping = "mapping";
+    private static final String Increase = "increase";
+    private static final String Operation = "operation";
+    private static final String Duration = "duration";
+
+    @Override
+    public DataProcessorDescription declareModel() {
+        return ProcessingElementBuilder.create("org.streampipes.processors.siddhi.increase")
+                .withLocales(Locales.EN)
+                .category(DataProcessorType.PATTERN_DETECT)
+                .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+                .requiredStream(StreamRequirementsBuilder.create()
+                        .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(), Labels.withId
+                                (Mapping), PropertyScope.MEASUREMENT_PROPERTY)
+                        .build())
+                .requiredSingleValueSelection(Labels.withId(Operation), Options
+                        .from("Increase", "Decrease"))
+                .requiredIntegerParameter(Labels.withId(Increase), 0, 500, 1)
+                .requiredIntegerParameter(Labels.withId(Duration))
+                .outputStrategy(OutputStrategies.custom())
+                .supportedFormats(SupportedFormats.jsonFormat())
+                .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+                .build();
+    }
+
+    @Override
+    public ConfiguredEventProcessor<TrendParameters> onInvocation(DataProcessorInvocation
+                                                                             invocationGraph, ProcessingElementParameterExtractor extractor) {
+        String operation = extractor.selectedSingleValue( Operation, String.class);
+        int increase = extractor.singleValueParameter(Increase, Integer.class);
+        int duration = extractor.singleValueParameter(Duration, Integer.class);
+        String mapping = extractor.mappingPropertyValue(Mapping);
+        TrendParameters params = new TrendParameters(invocationGraph, getOperation(operation), increase, duration, mapping);
+
+        return new ConfiguredEventProcessor<>(params, Trend::new);
+    }
+
+    private TrendOperator getOperation(String operation) {
+        if (operation.equals("Increase")) {
+            return TrendOperator.INCREASE;
+        } else {
+            return TrendOperator.DECREASE;
+        }
+    }
+
+
+}
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/Operation.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendOperator.java
similarity index 76%
rename from streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/Operation.java
rename to streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendOperator.java
index c667f79..4f74e42 100644
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/Operation.java
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -12,10 +12,11 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
  */
 
-package org.streampipes.processors.pattern.detection.flink.processor.increase;
+package org.streampipes.processors.siddhi.trend;
 
-public enum Operation {
-INCREASE, DECREASE
+public enum TrendOperator {
+    INCREASE, DECREASE
 }
diff --git a/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendParameters.java b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendParameters.java
new file mode 100644
index 0000000..c1acf5c
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/java/org/streampipes/processors/siddhi/trend/TrendParameters.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.siddhi.trend;
+
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
+
+public class TrendParameters extends EventProcessorBindingParams {
+
+    private TrendOperator operation;
+    private int increase;
+    private int duration;
+
+    private String mapping;
+
+
+    public TrendParameters(DataProcessorInvocation invocationGraph,
+                              TrendOperator operation, int increase, int duration,
+                              String mapping) {
+        super(invocationGraph);
+        this.operation = operation;
+        this.increase = increase;
+        this.duration = duration;
+        this.mapping = mapping;
+    }
+
+
+    public TrendOperator getOperation() {
+        return operation;
+    }
+
+
+    public int getIncrease() {
+        return increase;
+    }
+
+
+    public int getDuration() {
+        return duration;
+    }
+
+
+    public String getMapping() {
+        return mapping;
+    }
+
+}
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequency/documentation.md b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequency/documentation.md
new file mode 100644
index 0000000..679112a
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequency/documentation.md
@@ -0,0 +1,27 @@
+## Frequency Calculation
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Calculates the frequency of the event stream.
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequency/strings.en b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequency/strings.en
new file mode 100644
index 0000000..e7d9858
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequency/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.siddhi.frequency.title=Frequency Calculation
+org.streampipes.processors.siddhi.frequency.description=Calculates the frequency of the event stream
+
+duration.title=Time Window Length (Seconds)
+duration.description=Specifies the size of the time window in seconds.
+
+timeUnit.title=Time Unit
+timeUnit.description=Specifies a unit for the time window.
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequencychange/documentation.md b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequencychange/documentation.md
new file mode 100644
index 0000000..a5da9a1
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequencychange/documentation.md
@@ -0,0 +1,30 @@
+## Frequency Change
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detects when the frequency of the event stream changes
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequencychange/strings.en b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequencychange/strings.en
new file mode 100644
index 0000000..5cc842b
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.frequencychange/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.siddhi.frequencychange.title=Frequency Change
+org.streampipes.processors.siddhi.frequencychange.description=Detects when the frequency of the event stream changes
+
+duration.title=Time Window Length (Seconds)
+duration.description=Specifies the size of the time window in seconds.
+
+timeUnit.title=Time Unit
+timeUnit.description=Specifies a unit for the time window of the sequence.
+
+increase.title=Percentage of Increase/Decrease
+increase.description=Specifies the increase in percent (e.g., 100 indicates an increase by 100 percent within the specified time window.
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/documentation.md b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/documentation.md
new file mode 100644
index 0000000..a627206
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/documentation.md
@@ -0,0 +1,30 @@
+## Trend
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detects the increase of a numerical field over a customizable time window. Example: A temperature value increases by 10 percent within 5 minutes.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/icon.png b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/icon.png
new file mode 100644
index 0000000..820806f
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/icon.png
Binary files differ
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/strings.en b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/strings.en
new file mode 100644
index 0000000..0e04b31
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.increase/strings.en
@@ -0,0 +1,14 @@
+org.streampipes.processors.siddhi.increase.title=Trend
+org.streampipes.processors.siddhi.increase.description=Detects the increase of a numerical field over a customizable time window. Example: A temperature value increases by 10 percent within 5 minutes.
+
+mapping.title=Value to Observe
+mapping.description=Specifies the value that should be monitored.
+
+increase.title=Percentage of Increase/Decrease
+increase.description=Specifies the increase in percent (e.g., 100 indicates an increase by 100 percent within the specified time window.
+
+duration.title=Time Window Length (Seconds)
+duration.description=Specifies the size of the time window in seconds.
+
+operation.title=Increase/Decrease
+operation.description=Specifies the type of operation the processor should perform.
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/documentation.md b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/documentation.md
new file mode 100644
index 0000000..923f28d
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/documentation.md
@@ -0,0 +1,30 @@
+## Numerical Filter (Siddhi)
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/icon.png b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/icon.png
new file mode 100644
index 0000000..643d474
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/icon.png
Binary files differ
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/strings.en b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/strings.en
new file mode 100644
index 0000000..8b97841
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.numericalfilter/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.siddhi.numericalfilter.title=Numerical Filter (Siddhi)
+org.streampipes.processors.siddhi.numericalfilter.description=
+
+number-mapping.title=Field to Filter
+number-mapping.description=Specifies the field name where the filter operation should be applied on.
+
+value.title=Threshold value
+value.description=Specifies a threshold value.
+
+operation.title=Filter Operation
+operation.description=Specifies the filter operation that should be applied on the field
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.sequence/documentation.md b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.sequence/documentation.md
new file mode 100644
index 0000000..28219c4
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.sequence/documentation.md
@@ -0,0 +1,30 @@
+## Sequence Detection
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Merges events from two event streams, when the top event arrives first and then the bottom event
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.sequence/strings.en b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.sequence/strings.en
new file mode 100644
index 0000000..d36add0
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.sequence/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.processors.siddhi.sequence.title=Sequence Detection
+org.streampipes.processors.siddhi.sequence.description=Merges events from two event streams, when the top event arrives first and then the bottom event
+
+duration.title=Time Window Length (Seconds)
+duration.description=Specifies the size of the time window in seconds.
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.stop/documentation.md b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.stop/documentation.md
new file mode 100644
index 0000000..fc932b5
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.stop/documentation.md
@@ -0,0 +1,30 @@
+## Stream Stop Detection
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Triggers an event when the input data stream stops sending events
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.stop/strings.en b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.stop/strings.en
new file mode 100644
index 0000000..205960d
--- /dev/null
+++ b/streampipes-processors-filters-siddhi/src/main/resources/org.streampipes.processors.siddhi.stop/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.siddhi.stop.title=Stream Stop Detection
+org.streampipes.processors.siddhi.stop.description=Triggers an event when the input data stream stops sending events
+
+message.title=Message
+message.description=Message that stream stopped
+
+duration.title=Time Window Length (Seconds)
+duration.description=Specifies the size of the time window in seconds.
\ No newline at end of file
diff --git a/streampipes-processors-geo-flink/pom.xml b/streampipes-processors-geo-flink/pom.xml
index 3a5f899..76e2f5a 100644
--- a/streampipes-processors-geo-flink/pom.xml
+++ b/streampipes-processors-geo-flink/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-geo-flink/src/main/java/org/streampipes/processor/geo/flink/processor/gridenricher/SpatialGridEnrichmentController.java b/streampipes-processors-geo-flink/src/main/java/org/streampipes/processor/geo/flink/processor/gridenricher/SpatialGridEnrichmentController.java
index 93d6887..55e4dda 100644
--- a/streampipes-processors-geo-flink/src/main/java/org/streampipes/processor/geo/flink/processor/gridenricher/SpatialGridEnrichmentController.java
+++ b/streampipes-processors-geo-flink/src/main/java/org/streampipes/processor/geo/flink/processor/gridenricher/SpatialGridEnrichmentController.java
@@ -26,6 +26,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.Geo;
 import org.streampipes.vocabulary.SO;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
@@ -36,19 +37,20 @@
   private static final String MAPPING_LATITUDE = "mapping-latitude";
   private static final String MAPPING_LONGITUDE = "mapping-longitude";
 
-  private static final String CELLSIZE = "cellsize";
-  private static final String STARTING_CELL = "starting-cell";
+  private static final String CELLSIZE = "cellSize";
+  private static final String STARTING_CELL = "startingCell";
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processor.geo.flink", "Spatial Grid Enrichment", "Groups spatial " +
-            "events into cells of a given size")
+    return ProcessingElementBuilder.create("org.streampipes.processor.geo.flink")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq(Geo.lat)
-                            , Labels.from(MAPPING_LATITUDE, "Latitude Property", ""), PropertyScope.MEASUREMENT_PROPERTY)
+                            , Labels.withId(MAPPING_LATITUDE), PropertyScope.MEASUREMENT_PROPERTY)
                     .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq(Geo.lng)
-                            , Labels.from(MAPPING_LONGITUDE, "Longitude Property", ""), PropertyScope.MEASUREMENT_PROPERTY)
+                            , Labels.withId(MAPPING_LONGITUDE), PropertyScope.MEASUREMENT_PROPERTY)
                     .build())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
@@ -60,10 +62,9 @@
                     EpProperties.doubleEp(Labels.empty(), SpatialGridConstants.GRID_LAT_SE_KEY, Geo.lat),
                     EpProperties.doubleEp(Labels.empty(), SpatialGridConstants.GRID_LON_SE_KEY, Geo.lng),
                     EpProperties.integerEp(Labels.empty(), SpatialGridConstants.GRID_CELLSIZE_KEY, SO.Number)))
-            .requiredIntegerParameter(CELLSIZE, "Cell Size", "The size of a cell in meters",
+            .requiredIntegerParameter(Labels.withId(CELLSIZE),
                     100, 10000, 100)
-            .requiredOntologyConcept(Labels.from(STARTING_CELL, "Starting Location", "The " +
-                    "upper-left corner of the starting cell"), StaticProperties
+            .requiredOntologyConcept(Labels.withId(STARTING_CELL), StaticProperties
                     .supportedDomainProperty(Geo.lat, true), StaticProperties
                     .supportedDomainProperty(Geo.lng, true))
             .build();
diff --git a/streampipes-processors-geo-flink/src/main/resources/org.streampipes.processor.geo.flink/documentation.md b/streampipes-processors-geo-flink/src/main/resources/org.streampipes.processor.geo.flink/documentation.md
new file mode 100644
index 0000000..cbc9ba3
--- /dev/null
+++ b/streampipes-processors-geo-flink/src/main/resources/org.streampipes.processor.geo.flink/documentation.md
@@ -0,0 +1,30 @@
+## Spatial Grid Enrichment
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Groups spatial events into cells of a given size
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-geo-flink/src/main/resources/org.streampipes.processor.geo.flink/strings.en b/streampipes-processors-geo-flink/src/main/resources/org.streampipes.processor.geo.flink/strings.en
new file mode 100644
index 0000000..67a3126
--- /dev/null
+++ b/streampipes-processors-geo-flink/src/main/resources/org.streampipes.processor.geo.flink/strings.en
@@ -0,0 +1,14 @@
+org.streampipes.processor.geo.flink.title=Spatial Grid Enrichment
+org.streampipes.processor.geo.flink.description=Groups spatial events into cells of a given size
+
+mapping-latitude.title=Latitude Field
+mapping-latitude.description=
+
+mapping-longitude.title=Longitude Field
+mapping-longitude.description=
+
+cellSize.title=Cell Size
+cellSize.description=The size of a cell in meters
+
+startingCell.title=Starting Location
+startingCell.description=The upper-left corner of the starting cell
\ No newline at end of file
diff --git a/streampipes-processors-geo-jvm/pom.xml b/streampipes-processors-geo-jvm/pom.xml
index e9391e1..95c74ad 100644
--- a/streampipes-processors-geo-jvm/pom.xml
+++ b/streampipes-processors-geo-jvm/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -41,11 +41,6 @@
             <version>3.9.0</version>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.maps</groupId>
-            <artifactId>google-maps-services</artifactId>
-            <version>0.2.6</version>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/GeoJvmInit.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/GeoJvmInit.java
index e7c8d3d..c010b82 100644
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/GeoJvmInit.java
+++ b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/GeoJvmInit.java
@@ -23,16 +23,13 @@
 import org.streampipes.messaging.jms.SpJmsProtocolFactory;
 import org.streampipes.messaging.kafka.SpKafkaProtocolFactory;
 import org.streampipes.processors.geo.jvm.config.GeoJvmConfig;
-import org.streampipes.processors.geo.jvm.processor.geocode.GeocodingController;
-import org.streampipes.processors.geo.jvm.processor.route.GoogleRoutingController;
 
 public class GeoJvmInit extends StandaloneModelSubmitter {
 
   public static void main(String[] args) {
     DeclarersSingleton
-            .getInstance()
-            .add(new GeocodingController())
-            .add(new GoogleRoutingController());
+            .getInstance();
+//            .add(new GeocodingController())
 
     DeclarersSingleton.getInstance().registerDataFormat(new JsonDataFormatFactory());
     DeclarersSingleton.getInstance().registerProtocol(new SpKafkaProtocolFactory());
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/Geocoder.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/Geocoder.java
deleted file mode 100644
index 247a7cd..0000000
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/Geocoder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.geo.jvm.processor.geocode;
-
-import com.google.maps.GeoApiContext;
-import com.google.maps.GeocodingApi;
-import com.google.maps.errors.ApiException;
-import com.google.maps.model.GeocodingResult;
-import org.streampipes.model.runtime.Event;
-import org.streampipes.processors.geo.jvm.config.GeoJvmConfig;
-import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
-import org.streampipes.wrapper.routing.SpOutputCollector;
-import org.streampipes.wrapper.runtime.EventProcessor;
-
-import java.io.IOException;
-
-public class Geocoder implements EventProcessor<GeocodingParameters> {
-
-  private GeocodingParameters geocodingParameters;
-  private GeoApiContext context;
-
-  @Override
-  public void onInvocation(GeocodingParameters geocodingParameters, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext runtimeContext) {
-    this.geocodingParameters = geocodingParameters;
-    context = new GeoApiContext.Builder()
-            .apiKey(GeoJvmConfig.INSTANCE.getGoogleApiKey())
-            .build();
-  }
-
-  @Override
-  public void onEvent(Event in, SpOutputCollector spOutputCollector) {
-    String city = in.getFieldBySelector(geocodingParameters.getCity()).getAsPrimitive().getAsString();
-    String street = in.getFieldBySelector(geocodingParameters.getStreet()).getAsPrimitive()
-            .getAsString();
-    String number = in.getFieldBySelector(geocodingParameters.getNumber()).getAsPrimitive().getAsString();
-
-    String searchQuery = street + " " +number + ", " +city;
-
-    try {
-      GeocodingResult[] result = GeocodingApi.geocode(context, searchQuery).await();
-      if(result.length > 0) {
-        in.addField("latitude", result[0].geometry.location.lat);
-        in.addField("longitude", result[0].geometry.location.lng);
-      }
-    } catch (ApiException e) {
-      e.printStackTrace();
-    } catch (InterruptedException e) {
-      e.printStackTrace();
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-
-    spOutputCollector.collect(in);
-
-
-  }
-
-  @Override
-  public void onDetach() {
-
-  }
-}
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/GeocodingController.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/GeocodingController.java
deleted file mode 100644
index b553561..0000000
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/GeocodingController.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.geo.jvm.processor.geocode;
-
-import org.streampipes.model.graph.DataProcessorDescription;
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.geo.jvm.config.GeoJvmConfig;
-import org.streampipes.sdk.builder.ProcessingElementBuilder;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
-import org.streampipes.vocabulary.Geo;
-import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
-import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
-
-public class GeocodingController extends StandaloneEventProcessingDeclarer<GeocodingParameters> {
-
-  private static final String CITY_MAPPING = "city";
-  private static final String STREET_MAPPING = "street";
-  private static final String STREET_NUMBER_MAPPING = "street-number";
-
-  @Override
-  public ConfiguredEventProcessor<GeocodingParameters> onInvocation(DataProcessorInvocation
-                                                                            graph, ProcessingElementParameterExtractor extractor) {
-    String city = extractor.mappingPropertyValue(CITY_MAPPING);
-    String street = extractor.mappingPropertyValue(STREET_MAPPING);
-    String number = extractor.mappingPropertyValue(STREET_NUMBER_MAPPING);
-
-    GeocodingParameters params = new GeocodingParameters(graph, city, street, number);
-    return new ConfiguredEventProcessor<>(params, Geocoder::new);
-  }
-
-  @Override
-  public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.geo.jvm.geocoder", "Geocoder", "Geocodes a location based " +
-            "on given street, address and street number")
-            .iconUrl(GeoJvmConfig.iconBaseUrl + "Location_Icon_HQ.png")
-
-            .requiredStream(
-                    StreamRequirementsBuilder.create()
-                            .requiredPropertyWithUnaryMapping(
-                                    EpRequirements
-                                            .domainPropertyReq("http://schema.org/city"),
-                                    Labels.from(CITY_MAPPING, "City", ""),
-                                    PropertyScope.NONE)
-                            .requiredPropertyWithUnaryMapping(
-                                    EpRequirements
-                                            .domainPropertyReq("http://schema" +
-                                                    ".org/streetAddress"),
-                                    Labels.from(STREET_MAPPING, "Street", ""),
-                                    PropertyScope.NONE)
-                            .requiredPropertyWithUnaryMapping(
-                                    EpRequirements
-                                            .domainPropertyReq("http://schema" +
-                                                    ".org/streetNumber"),
-                                    Labels.from(STREET_NUMBER_MAPPING, "Street number", ""),
-                                    PropertyScope.NONE)
-                            .build())
-            .outputStrategy(OutputStrategies.append(EpProperties.doubleEp(Labels.from("latitude",
-                    "Latitude", ""),
-                    "latitude", Geo.lat), EpProperties.doubleEp(Labels.from("longitude",
-                    "Longitude", ""), "longitude", Geo.lng)))
-
-            .supportedFormats(SupportedFormats.jsonFormat())
-            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-            .build();
-  }
-}
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/GeocodingParameters.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/GeocodingParameters.java
deleted file mode 100644
index 3e2e615..0000000
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/geocode/GeocodingParameters.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.geo.jvm.processor.geocode;
-
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
-
-public class GeocodingParameters extends EventProcessorBindingParams {
-
-  private String city;
-  private String street;
-  private String number;
-
-  public GeocodingParameters(DataProcessorInvocation graph, String city, String street, String number) {
-    super(graph);
-    this.city = city;
-    this.street = street;
-    this.number = number;
-  }
-
-  public String getCity() {
-    return city;
-  }
-
-  public String getStreet() {
-    return street;
-  }
-
-  public String getNumber() {
-    return number;
-  }
-}
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRouting.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRouting.java
deleted file mode 100644
index db2d23e..0000000
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRouting.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.streampipes.processors.geo.jvm.processor.route;
-
-import com.google.maps.DistanceMatrixApi;
-import com.google.maps.GeoApiContext;
-import com.google.maps.errors.ApiException;
-import com.google.maps.model.DistanceMatrix;
-import com.google.maps.model.LatLng;
-import org.streampipes.logging.api.Logger;
-import org.streampipes.model.runtime.Event;
-import org.streampipes.processors.geo.jvm.config.GeoJvmConfig;
-import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
-import org.streampipes.wrapper.routing.SpOutputCollector;
-import org.streampipes.wrapper.runtime.EventProcessor;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-public class GoogleRouting implements EventProcessor<GoogleRoutingParameters> {
-
-    private static Logger LOG;
-
-    private GoogleRoutingParameters googleRoutingParameters;
-    private GeoApiContext context;
-
-    @Override
-    public void onInvocation(GoogleRoutingParameters googleRoutingParameters, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext
-            runtimeContext) {
-        LOG = googleRoutingParameters.getGraph().getLogger(GoogleRouting.class);
-
-        this.googleRoutingParameters = googleRoutingParameters;
-        context = new GeoApiContext.Builder()
-                .apiKey(GeoJvmConfig.INSTANCE.getGoogleApiKey())
-                .build();
-    }
-
-    @Override
-    public void onEvent(Event in, SpOutputCollector out) {
-        String city = in.getFieldBySelector(googleRoutingParameters.getCity()).getAsPrimitive().getAsString();
-        String street = in.getFieldBySelector(googleRoutingParameters.getStreet()).getAsPrimitive
-                ().getAsString();
-        String number = in.getFieldBySelector(googleRoutingParameters.getNumber()).getAsPrimitive
-                ().getAsString();
-        String home = googleRoutingParameters.getHome();
-
-        String destinationLocation = city + ", " + street + ", " + number;
-
-        try {
-
-            String[] origin = {home};
-            String[] destination = {destinationLocation};
-            DistanceMatrix rest = DistanceMatrixApi.getDistanceMatrix(context, origin, destination).await();
-
-            if (rest.rows.length > 0 && rest.rows[0].elements[0].status.name().equals("NOT_FOUND")) {
-                LOG.info("Could not find location: " + destinationLocation);
-            } else {
-
-                long l = rest.rows[0].elements[0].distance.inMeters;
-
-                in.addField("kvi", l);
-
-                out.collect(in);
-            }
-
-        } catch (ApiException e) {
-            e.printStackTrace();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private static Map<String, Object> getGeoObject(LatLng latLng) {
-        Map<String, Object> result = new HashMap<>();
-
-        result.put("latitude", latLng.lat);
-        result.put("longitude", latLng.lng);
-
-        return result;
-
-    }
-
-    @Override
-    public void onDetach() {
-    }
-}
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRoutingController.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRoutingController.java
deleted file mode 100644
index 0ce2e7b..0000000
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRoutingController.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.streampipes.processors.geo.jvm.processor.route;
-
-import org.streampipes.model.graph.DataProcessorDescription;
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.geo.jvm.config.GeoJvmConfig;
-import org.streampipes.sdk.builder.ProcessingElementBuilder;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
-import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
-import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
-
-public class GoogleRoutingController extends StandaloneEventProcessingDeclarer<GoogleRoutingParameters> {
-
-    private static final String CITY_MAPPING = "city";
-    private static final String STREET_MAPPING = "street";
-    private static final String STREET_NUMBER_MAPPING = "street-number";
-    private static final String START_ADDRESS = "start-address";
-
-    @Override
-    public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors.geo.jvm.google-routing", "Google Routing", "Uses the Google" +
-                "routing service to calculate a route from start to destination")
-                .iconUrl(GeoJvmConfig.iconBaseUrl + "Map_Icon_HQ.png")
-                .requiredStream(
-                        StreamRequirementsBuilder.create()
-                                .requiredPropertyWithUnaryMapping(
-                                        EpRequirements
-                                                .domainPropertyReq("http://schema.org/city"),
-                                        Labels.from(CITY_MAPPING, "City", ""),
-                                        PropertyScope.NONE)
-                                .requiredPropertyWithUnaryMapping(
-                                        EpRequirements
-                                                .domainPropertyReq("http://schema" +
-                                                        ".org/streetAddress"),
-                                        Labels.from(STREET_MAPPING, "Street", ""),
-                                        PropertyScope.NONE)
-                                .requiredPropertyWithUnaryMapping(
-                                        EpRequirements
-                                                .domainPropertyReq("http://schema" +
-                                                        ".org/streetNumber"),
-                                        Labels.from(STREET_NUMBER_MAPPING, "Street Number", ""),
-                                        PropertyScope.NONE)
-                                .build())
-
-                .requiredTextParameter(Labels.from(START_ADDRESS, "Start Address", ""))
-                .outputStrategy(OutputStrategies.append(EpProperties.stringEp(Labels.from("kvi", "Distance", ""),
-                        "kvi", "http://kvi.de")))
-
-                .supportedFormats(SupportedFormats.jsonFormat())
-                .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-                .build();
-    }
-
-    /*
-        TUTORIAL:
-        Here you get the Configuration Parameters which the User has entered
-    */
-    @Override
-    public ConfiguredEventProcessor<GoogleRoutingParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
-        String city = extractor.mappingPropertyValue(CITY_MAPPING);
-        String street = extractor.mappingPropertyValue(STREET_MAPPING);
-        String number = extractor.mappingPropertyValue(STREET_NUMBER_MAPPING);
-
-        String home = extractor.singleValueParameter(START_ADDRESS, String.class);
-
-        GoogleRoutingParameters params = new GoogleRoutingParameters(graph, city, street, number, home);
-        return new ConfiguredEventProcessor<>(params, GoogleRouting::new);
-    }
-}
diff --git a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRoutingParameters.java b/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRoutingParameters.java
deleted file mode 100644
index e965b3c..0000000
--- a/streampipes-processors-geo-jvm/src/main/java/org/streampipes/processors/geo/jvm/processor/route/GoogleRoutingParameters.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.streampipes.processors.geo.jvm.processor.route;
-
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
-
-public class GoogleRoutingParameters extends EventProcessorBindingParams {
-    private String city;
-    private String street;
-    private String number;
-    private String home;
-
-
-    public GoogleRoutingParameters(DataProcessorInvocation graph, String city, String street, String number, String home) {
-        super(graph);
-        this.city = city;
-        this.street = street;
-        this.number = number;
-        this.home = home;
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public String getStreet() {
-        return street;
-    }
-
-    public void setStreet(String street) {
-        this.street = street;
-    }
-
-    public String getNumber() {
-        return number;
-    }
-
-    public void setNumber(String number) {
-        this.number = number;
-    }
-
-    public String getHome() {
-        return home;
-    }
-
-    public void setHome(String home) {
-        this.home = home;
-    }
-}
\ No newline at end of file
diff --git a/streampipes-processors-image-processing-jvm/pom.xml b/streampipes-processors-image-processing-jvm/pom.xml
index 13aaed4..ff03fdd 100644
--- a/streampipes-processors-image-processing-jvm/pom.xml
+++ b/streampipes-processors-image-processing-jvm/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -54,7 +54,7 @@
         <dependency>
             <groupId>org.boofcv</groupId>
             <artifactId>boofcv-core</artifactId>
-            <version>0.29</version>
+            <version>0.33</version>
         </dependency>
     </dependencies>
 
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/ImageProcessingJvmInit.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/ImageProcessingJvmInit.java
index 2c5288d..bb02bb7 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/ImageProcessingJvmInit.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/ImageProcessingJvmInit.java
@@ -24,7 +24,6 @@
 import org.streampipes.messaging.kafka.SpKafkaProtocolFactory;
 import org.streampipes.processors.imageprocessing.jvm.config.ImageProcessingJvmConfig;
 import org.streampipes.processors.imageprocessing.jvm.processor.genericclassification.GenericImageClassificationController;
-import org.streampipes.processors.imageprocessing.jvm.processor.imagecropper.ImageCropperController;
 import org.streampipes.processors.imageprocessing.jvm.processor.imageenrichment.ImageEnrichmentController;
 import org.streampipes.processors.imageprocessing.jvm.processor.qrreader.QrCodeReaderController;
 
@@ -34,8 +33,7 @@
     DeclarersSingleton
             .getInstance()
             .add(new ImageEnrichmentController())
-            .add(new ImageCropperController())
-            //.add(new ImageRectificationController())
+//            .add(new ImageCropperController())
             .add(new QrCodeReaderController())
             .add(new GenericImageClassificationController());
 
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/ImageTransformer.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/ImageTransformer.java
index e8a5c97..8e327f3 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/ImageTransformer.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/ImageTransformer.java
@@ -16,19 +16,20 @@
  */
 package org.streampipes.processors.imageprocessing.jvm.processor.commons;
 
+import org.streampipes.model.runtime.Event;
 import org.streampipes.processors.imageprocessing.jvm.processor.imageenrichment.BoxCoordinates;
 import org.streampipes.processors.imageprocessing.jvm.processor.imageenrichment.ImageEnrichmentParameters;
 
-import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.Map;
 import java.util.Optional;
 
+import javax.imageio.ImageIO;
+
 public class ImageTransformer extends PlainImageTransformer<ImageEnrichmentParameters> {
 
-  public ImageTransformer(Map<String, Object> in, ImageEnrichmentParameters params) {
+  public ImageTransformer(Event in, ImageEnrichmentParameters params) {
    super(in, params);
   }
 
@@ -38,10 +39,10 @@
   }
 
   public BoxCoordinates getBoxCoordinates(BufferedImage image) {
-    Float x = toFloat(in.get(params.getBoxX()));
-    Float y = toFloat(in.get(params.getBoxY()));
-    Float width = toFloat(in.get(params.getBoxWidth()));
-    Float height = toFloat(in.get(params.getBoxHeight()));
+    Float x = in.getFieldBySelector(params.getBoxX()).getAsPrimitive().getAsFloat();
+    Float y = in.getFieldBySelector(params.getBoxY()).getAsPrimitive().getAsFloat();
+    Float width = in.getFieldBySelector(params.getBoxWidth()).getAsPrimitive().getAsFloat();
+    Float height = in.getFieldBySelector(params.getBoxHeight()).getAsPrimitive().getAsFloat();
 
     return BoxCoordinates.make(image.getWidth(), image.getHeight(), width, height, x, y);
   }
@@ -61,9 +62,4 @@
     }
 
   }
-
-  private Float toFloat(Object obj) {
-    return Float.parseFloat(String.valueOf(obj));
-  }
-
 }
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/PlainImageTransformer.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/PlainImageTransformer.java
index 19be260..1258926 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/PlainImageTransformer.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/PlainImageTransformer.java
@@ -16,31 +16,31 @@
  */
 package org.streampipes.processors.imageprocessing.jvm.processor.commons;
 
+import org.streampipes.model.runtime.Event;
 import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
 
-import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Base64;
-import java.util.Map;
 import java.util.Optional;
 
+import javax.imageio.ImageIO;
+
 public class PlainImageTransformer<T extends EventProcessorBindingParams> {
 
-  protected Map<String, Object> in;
+  protected Event in;
   protected T params;
 
-  public PlainImageTransformer(Map<String, Object> in, T params) {
+  public PlainImageTransformer(Event in, T params) {
     this.in = in;
     this.params = params;
   }
 
   public Optional<BufferedImage> getImage(String imagePropertyName) {
     System.out.println(imagePropertyName);
-    System.out.println(in.get(imagePropertyName));
-    String imageBase64 = String.valueOf(in.get(imagePropertyName));
+    String imageBase64 = in.getFieldBySelector(imagePropertyName).getAsPrimitive().getAsString();
 
     InputStream img = new ByteArrayInputStream(Base64.getDecoder().decode(imageBase64));
     try {
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/RequiredBoxStream.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/RequiredBoxStream.java
index 5ab8040..920d4c2 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/RequiredBoxStream.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/commons/RequiredBoxStream.java
@@ -25,29 +25,16 @@
 public class RequiredBoxStream {
 
   public static final String IMAGE_PROPERTY = "image-property";
-  public static final String BOX_WIDTH_PROPERTY = "box-width-property";
-  public static final String BOX_HEIGHT_PROPERTY = "box-height-property";
-  public static final String BOX_X_PROPERTY = "box-x-property";
-  public static final String BOX_Y_PROPERTY = "box-y-property";
+  public static final String BOX_ARRAY_PROPERTY = "box-array-property";
 
   public static CollectedStreamRequirements getBoxStream() {
-
-    return StreamRequirementsBuilder
+        return StreamRequirementsBuilder
             .create()
             .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq("https://image.com"), Labels
                             .from(IMAGE_PROPERTY, "Image Classification", ""),
                     PropertyScope.NONE)
-            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq("https://schema.org/width"),
-                    Labels.from(BOX_WIDTH_PROPERTY, "Box Width", ""),
-                    PropertyScope.NONE)
-            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq("https://schema.org/height"),
-                    Labels.from(BOX_HEIGHT_PROPERTY, "Box Height", ""),
-                    PropertyScope.NONE)
-            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq("https://schema.org/x"),
-                    Labels.from(BOX_X_PROPERTY, "Box X Coordinate", ""),
-                    PropertyScope.NONE)
-            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq("https://schema.org/y"),
-                    Labels.from(BOX_Y_PROPERTY, "Box Y Coordinate", ""),
+            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReqList("https://streampipes.org/boundingboxes"),
+                    Labels.from(BOX_ARRAY_PROPERTY, "Array Width Bounding Boxes", "Contains an array with bounding boxes"),
                     PropertyScope.NONE)
             .build();
   }
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassification.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassification.java
index 67af96d..4216a13 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassification.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassification.java
@@ -64,7 +64,7 @@
   @Override
   public void onEvent(Event in, SpOutputCollector out) {
     PlainImageTransformer<GenericImageClassificationParameters> imageTransformer = new
-            PlainImageTransformer<>(in.getRaw(),
+            PlainImageTransformer<>(in,
             params);
 
 
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassificationController.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassificationController.java
index 202c56a..89cd2fe 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassificationController.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/genericclassification/GenericImageClassificationController.java
@@ -24,22 +24,24 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
 public class GenericImageClassificationController extends StandaloneEventProcessingDeclarer<GenericImageClassificationParameters> {
 
-  private static final String IMAGE = "IMAGE";
+  private static final String IMAGE = "image-mapping";
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.jvm.generic-image-classification", "Generic Image Classification", "Image " +
-            "Classification Description (Generic Model)")
+    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.jvm.generic-image-classification")
             .category(DataProcessorType.FILTER)
+            .withAssets(Assets.DOCUMENTATION)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(EpRequirements
-                                    .domainPropertyReq("https://image.com"), Labels.from(IMAGE, "Image Classification", ""),
+                                    .domainPropertyReq("https://image.com"), Labels.withId(IMAGE),
                             PropertyScope.NONE)
                     .build())
             .outputStrategy(OutputStrategies.fixed(
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropper.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropper.java
index bf5704b..ed2a98f 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropper.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropper.java
@@ -38,7 +38,7 @@
 
   @Override
   public void onEvent(Event in, SpOutputCollector out) {
-    ImageTransformer imageTransformer = new ImageTransformer(in.getRaw(), params);
+    ImageTransformer imageTransformer = new ImageTransformer(in, params);
     Optional<BufferedImage> imageOpt = imageTransformer.getImage();
 
     if (imageOpt.isPresent()) {
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperController.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperController.java
index f023d01..69e1867 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperController.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperController.java
@@ -17,32 +17,27 @@
 package org.streampipes.processors.imageprocessing.jvm.processor.imagecropper;
 
 
-import static org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream.*;
-
 import org.streampipes.model.DataProcessorType;
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.processors.imageprocessing.jvm.config.ImageProcessingJvmConfig;
 import org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.EpProperties;
-import org.streampipes.sdk.helpers.Labels;
-import org.streampipes.sdk.helpers.OutputStrategies;
-import org.streampipes.sdk.helpers.SupportedFormats;
-import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
+import static org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream.IMAGE_PROPERTY;
+
 
 public class ImageCropperController extends StandaloneEventProcessingDeclarer<ImageCropperParameters> {
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.jvm.image-cropper", "Image Cropper", "Image Enrichment: Crops an " +
-            "image based on " +
-            "given bounding box coordinates")
-            .iconUrl(ImageProcessingJvmConfig.getIconUrl( "crop"))
+    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.jvm.image-cropper")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .category(DataProcessorType.FILTER)
             .requiredStream(RequiredBoxStream.getBoxStream())
             .outputStrategy(OutputStrategies.fixed(
@@ -58,13 +53,10 @@
   public ConfiguredEventProcessor<ImageCropperParameters> onInvocation(DataProcessorInvocation dataProcessorInvocation, ProcessingElementParameterExtractor extractor) {
 
     String imageProperty = extractor.mappingPropertyValue(IMAGE_PROPERTY);
-    String boxWidthProperty = extractor.mappingPropertyValue(BOX_WIDTH_PROPERTY);
-    String boxHeightProperty = extractor.mappingPropertyValue(BOX_HEIGHT_PROPERTY);
-    String boxXProperty = extractor.mappingPropertyValue(BOX_X_PROPERTY);
-    String boxYProperty = extractor.mappingPropertyValue(BOX_Y_PROPERTY);
+    String boxArray = extractor.mappingPropertyValue(RequiredBoxStream.BOX_ARRAY_PROPERTY);
 
     ImageCropperParameters params = new ImageCropperParameters(dataProcessorInvocation, imageProperty,
-            boxWidthProperty, boxHeightProperty, boxXProperty, boxYProperty);
+            boxArray, "box_width", "box_height", "box_x", "box_y");
 
     return new ConfiguredEventProcessor<>(params, ImageCropper::new);
   }
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperParameters.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperParameters.java
index 53cbc41..f5c39de 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperParameters.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagecropper/ImageCropperParameters.java
@@ -21,7 +21,7 @@
 
 public class ImageCropperParameters extends ImageEnrichmentParameters {
 
-  public ImageCropperParameters(DataProcessorInvocation graph, String imageProperty, String boxWidth, String boxHeight, String boxX, String boxY) {
-    super(graph, imageProperty, boxWidth, boxHeight, boxX, boxY);
+  public ImageCropperParameters(DataProcessorInvocation graph, String imageProperty, String boxArray, String boxWidth, String boxHeight, String boxX, String boxY) {
+    super(graph, imageProperty, boxArray, boxWidth, boxHeight, boxX, boxY);
   }
 }
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnricher.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnricher.java
index e9ea04e..f036945 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnricher.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnricher.java
@@ -16,6 +16,7 @@
  */
 package org.streampipes.processors.imageprocessing.jvm.processor.imageenrichment;
 
+import org.streampipes.model.runtime.field.AbstractField;
 import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
 import org.streampipes.wrapper.routing.SpOutputCollector;
 import org.streampipes.wrapper.runtime.EventProcessor;
@@ -26,7 +27,9 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Base64;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -46,8 +49,16 @@
     @Override
     public void onEvent(org.streampipes.model.runtime.Event in, SpOutputCollector out) {
 // TODO
-        List<Map<String, Object>> allBoxes = in.getFieldBySelector(params.getBoxArray()).getAsList()
-                .parseAsCustomType(value -> (Map<String, Object>) value);
+        List<Map<String, AbstractField>> allBoxes = in.getFieldBySelector(params.getBoxArray())
+                .getAsList()
+                .parseAsCustomType(value -> value.getAsComposite().getRawValue());
+
+        List<Map<String, Object>> allBoxesMap = new ArrayList<>();
+        allBoxes.forEach(box -> {
+            Map<String, Object> boxMap = new HashMap<>();
+            box.forEach((key, value) -> boxMap.put(value.getFieldNameIn(), value.getRawValue()));
+            allBoxesMap.add(boxMap);
+        });
 
         Optional<BufferedImage> imageOpt = getImage(in.getFieldBySelector(params.getImageProperty
                 ()).getAsPrimitive().getRawValue());
@@ -55,7 +66,7 @@
         if (imageOpt.isPresent()) {
             BufferedImage image = imageOpt.get();
 
-            for (Map<String, Object> box : allBoxes) {
+            for (Map<String, Object> box : allBoxesMap) {
 //
                 BoxCoordinates boxCoordinates = getBoxCoordinates(image, box);
 
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnrichmentController.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnrichmentController.java
index 14c6bed..746c053 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnrichmentController.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imageenrichment/ImageEnrichmentController.java
@@ -16,39 +16,28 @@
  */
 package org.streampipes.processors.imageprocessing.jvm.processor.imageenrichment;
 
-import static org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream.IMAGE_PROPERTY;
-
 import org.streampipes.model.DataProcessorType;
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.imageprocessing.jvm.config.ImageProcessingJvmConfig;
+import org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.CollectedStreamRequirements;
-import org.streampipes.sdk.helpers.EpProperties;
-import org.streampipes.sdk.helpers.EpRequirements;
-import org.streampipes.sdk.helpers.Labels;
-import org.streampipes.sdk.helpers.OutputStrategies;
-import org.streampipes.sdk.helpers.SupportedFormats;
-import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
-public class ImageEnrichmentController extends StandaloneEventProcessingDeclarer<ImageEnrichmentParameters> {
+import static org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream.IMAGE_PROPERTY;
 
-  public static final String BOX_ARRAY_PROPERTY = "box-array-property";
+public class ImageEnrichmentController extends StandaloneEventProcessingDeclarer<ImageEnrichmentParameters> {
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.jvm.image-enricher", "Image Enricher", "Image Enrichment: Enriches an " +
-            "image with " +
-            "given bounding box coordinates")
-            .iconUrl(ImageProcessingJvmConfig.getIconUrl( "image_enrich"))
+    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.jvm.image-enricher")
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .category(DataProcessorType.FILTER)
-            .requiredStream(getStreamRequirements())
-
+            .requiredStream(RequiredBoxStream.getBoxStream())
             .outputStrategy(OutputStrategies.fixed(
                     EpProperties.stringEp(Labels.empty(), "image", "https://image.com")
 
@@ -58,24 +47,10 @@
             .build();
   }
 
-  private CollectedStreamRequirements getStreamRequirements() {
-        return StreamRequirementsBuilder
-            .create()
-            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReq("https://image.com"), Labels
-                            .from(IMAGE_PROPERTY, "Image Classification", ""),
-                    PropertyScope.NONE)
-                // TODO add again
-            .requiredPropertyWithUnaryMapping(EpRequirements.domainPropertyReqList("https://streampipes.org/boundingboxes"),
-                    Labels.from(BOX_ARRAY_PROPERTY, "Array Width Bounding Boxes", "Contains an array with bounding boxes"),
-                    PropertyScope.NONE)
-            .build();
-  }
-
   @Override
   public ConfiguredEventProcessor<ImageEnrichmentParameters> onInvocation(DataProcessorInvocation dataProcessorInvocation, ProcessingElementParameterExtractor extractor) {
     String imageProperty = extractor.mappingPropertyValue(IMAGE_PROPERTY);
-    String boxArray = extractor.mappingPropertyValue(BOX_ARRAY_PROPERTY);
-//    String boxArray = "boxes";
+    String boxArray = extractor.mappingPropertyValue(RequiredBoxStream.BOX_ARRAY_PROPERTY);
 
     ImageEnrichmentParameters params = new ImageEnrichmentParameters(dataProcessorInvocation, imageProperty,
             boxArray, "box_width", "box_height", "box_x", "box_y");
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationController.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationController.java
deleted file mode 100644
index d1de6ed..0000000
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectificationController.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.imageprocessing.jvm.processor.imagerectification;
-
-import static org.streampipes.processors.imageprocessing.jvm.processor.commons.RequiredBoxStream.IMAGE_PROPERTY;
-
-import org.streampipes.model.DataProcessorType;
-import org.streampipes.model.graph.DataProcessorDescription;
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.sdk.builder.ProcessingElementBuilder;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.EpRequirements;
-import org.streampipes.sdk.helpers.Labels;
-import org.streampipes.sdk.helpers.OutputStrategies;
-import org.streampipes.sdk.helpers.SupportedFormats;
-import org.streampipes.sdk.helpers.SupportedProtocols;
-import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
-import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
-
-public class ImageRectificationController extends StandaloneEventProcessingDeclarer<ImageRectificationParameters> {
-
-  @Override
-  public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.image-rectifier", "Image Rectifier", "Image Rectification: Rectifies " +
-            "an image")
-            .category(DataProcessorType.FILTER)
-            .requiredStream(StreamRequirementsBuilder.create().requiredPropertyWithUnaryMapping(EpRequirements
-                            .domainPropertyReq("https://image.com"), Labels
-                            .from(IMAGE_PROPERTY, "Image Classification", ""),
-                    PropertyScope.NONE).build())
-            .outputStrategy(OutputStrategies.keep())
-            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-            .supportedFormats(SupportedFormats.jsonFormat())
-            .build();
-  }
-
-  @Override
-  public ConfiguredEventProcessor<ImageRectificationParameters> onInvocation(DataProcessorInvocation dataProcessorInvocation, ProcessingElementParameterExtractor extractor) {
-    String imagePropertyName = extractor.mappingPropertyValue(IMAGE_PROPERTY);
-
-    ImageRectificationParameters params = new ImageRectificationParameters(dataProcessorInvocation, imagePropertyName);
-
-    return new ConfiguredEventProcessor<>(params, ImageRectifier::new);
-  }
-
-}
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectifier.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectifier.java
deleted file mode 100644
index d3a0e9f..0000000
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/imagerectification/ImageRectifier.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.imageprocessing.jvm.processor.imagerectification;
-
-import org.streampipes.model.runtime.Event;
-import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
-import org.streampipes.wrapper.routing.SpOutputCollector;
-import org.streampipes.wrapper.runtime.EventProcessor;
-
-public class ImageRectifier implements EventProcessor<ImageRectificationParameters> {
-
-  private ImageRectificationParameters params;
-
-
-  @Override
-  public void onInvocation(ImageRectificationParameters imageRectificationParameters, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext runtimeContext) {
-    this.params = imageRectificationParameters;
-  }
-
-  @Override
-  public void onEvent(Event event, SpOutputCollector spOutputCollector) {
-    // TODO add logic here
-  }
-
-  @Override
-  public void onDetach() {
-
-  }
-}
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReader.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReader.java
index 2484f8c..d77b98d 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReader.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReader.java
@@ -36,17 +36,21 @@
 public class QrCodeReader implements EventProcessor<QrCodeReaderParameters> {
 
   private QrCodeReaderParameters params;
+  private Boolean sendIfNoResult;
+  private String placeholderValue;
   private static final Logger LOG = LoggerFactory.getLogger(QrCodeReader.class);
 
   @Override
   public void onInvocation(QrCodeReaderParameters qrCodeReaderParameters, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext runtimeContext) {
     this.params = qrCodeReaderParameters;
+    this.sendIfNoResult = qrCodeReaderParameters.getSendIfNoResult();
+    this.placeholderValue = qrCodeReaderParameters.getPlaceholderValue();
   }
 
   @Override
   public void onEvent(Event in, SpOutputCollector out) {
     PlainImageTransformer<QrCodeReaderParameters> imageTransformer = new PlainImageTransformer<>
-            (in.getRaw(), params);
+            (in, params);
     Optional<BufferedImage> imageOpt = imageTransformer.getImage(params.getImagePropertyName());
 
     if (imageOpt.isPresent()) {
@@ -58,21 +62,32 @@
 
       detector.process(gray);
       List<QrCode> detections = detector.getDetections();
+      List<QrCode> failures = detector.getFailures();
 
       if (detections.size() > 0) {
         LOG.info(detections.get(0).message);
-        Event event = new Event();
-        event.addField("qrvalue", detections.get(0).message);
-        event.addField("timestamp", System.currentTimeMillis());
+        Event event = makeEvent(detections.get(0).message);
         out.collect(event);
       } else {
         LOG.info("Could not find any QR code");
+        if (sendIfNoResult) {
+          Event event = makeEvent(placeholderValue);
+          out.collect(event);
+        }
       }
 
 
     }
   }
 
+  private Event makeEvent(String qrCodeValue) {
+    Event event = new Event();
+    event.addField("qrvalue", qrCodeValue);
+    event.addField("timestamp", System.currentTimeMillis());
+    return event;
+  }
+
+
   @Override
   public void onDetach() {
 
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderController.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderController.java
index f1bd0b6..ea4063a 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderController.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderController.java
@@ -22,34 +22,41 @@
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.imageprocessing.jvm.config.ImageProcessingJvmConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpProperties;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
 public class QrCodeReaderController extends StandaloneEventProcessingDeclarer<QrCodeReaderParameters> {
 
+  private static final String PLACEHOLDER_VALUE = "placeholder-value";
+  private static final String SEND_IF_NO_RESULT = "send-if-no-result";
+  private static final String QR_VALUE = "qr-value";
+
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("qr-code-reader", "QR Code Reader", ("QR Code Reader: Detects a QR Code " +
-            "in an image"))
+    return ProcessingElementBuilder.create("org.streampipes.processor.imageclassification.qrcode")
             .category(DataProcessorType.FILTER)
-            .iconUrl(ImageProcessingJvmConfig.getIconUrl("qrcode"))
-
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .withLocales(Locales.EN)
             .requiredStream(StreamRequirementsBuilder.create().requiredPropertyWithUnaryMapping(EpRequirements
                             .domainPropertyReq("https://image.com"), Labels
-                            .from(IMAGE_PROPERTY, "Image", ""),
+                            .withId(IMAGE_PROPERTY),
                     PropertyScope.NONE).build())
+            .requiredSingleValueSelection(Labels.withId(SEND_IF_NO_RESULT), Options.from("Yes", "No"))
+            .requiredTextParameter(Labels.withId(PLACEHOLDER_VALUE))
             .outputStrategy(OutputStrategies.fixed(EpProperties.timestampProperty("timestamp"),
-                    EpProperties.stringEp(Labels.from("qr-value", "QR code value", ""),
+                    EpProperties.stringEp(Labels.withId(QR_VALUE),
                             "qrvalue", "http://schema.org/text")))
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
@@ -59,8 +66,12 @@
   @Override
   public ConfiguredEventProcessor<QrCodeReaderParameters> onInvocation(DataProcessorInvocation dataProcessorInvocation, ProcessingElementParameterExtractor extractor) {
     String imagePropertyName = extractor.mappingPropertyValue(IMAGE_PROPERTY);
+    String placeholderValue = extractor.singleValueParameter(PLACEHOLDER_VALUE, String.class);
+    Boolean sendIfNoResult = extractor.selectedSingleValue(SEND_IF_NO_RESULT, String.class)
+            .equals("Yes");
 
-    QrCodeReaderParameters params = new QrCodeReaderParameters(dataProcessorInvocation, imagePropertyName);
+    QrCodeReaderParameters params = new QrCodeReaderParameters(dataProcessorInvocation,
+            imagePropertyName, placeholderValue, sendIfNoResult);
 
     return new ConfiguredEventProcessor<>(params, QrCodeReader::new);
   }
diff --git a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderParameters.java b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderParameters.java
index 30c056f..3c18970 100644
--- a/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderParameters.java
+++ b/streampipes-processors-image-processing-jvm/src/main/java/org/streampipes/processors/imageprocessing/jvm/processor/qrreader/QrCodeReaderParameters.java
@@ -22,13 +22,26 @@
 public class QrCodeReaderParameters extends EventProcessorBindingParams {
 
   private String imagePropertyName;
+  private String placeholderValue;
+  private Boolean sendIfNoResult;
 
-  public QrCodeReaderParameters(DataProcessorInvocation graph, String imagePropertyName) {
+  public QrCodeReaderParameters(DataProcessorInvocation graph, String imagePropertyName, String
+          placeholderValue, Boolean sendIfNoResult) {
     super(graph);
     this.imagePropertyName = imagePropertyName;
+    this.placeholderValue = placeholderValue;
+    this.sendIfNoResult = sendIfNoResult;
   }
 
   public String getImagePropertyName() {
     return imagePropertyName;
   }
+
+  public String getPlaceholderValue() {
+    return placeholderValue;
+  }
+
+  public Boolean getSendIfNoResult() {
+    return sendIfNoResult;
+  }
 }
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/documentation.md b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/documentation.md
new file mode 100644
index 0000000..6baa0cf
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/documentation.md
@@ -0,0 +1,30 @@
+## Generic Image Classification
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Image  + Classification Description (Generic Model)
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/icon.png b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/icon.png
new file mode 100644
index 0000000..a0e37f5
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/icon.png
Binary files differ
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/strings.en b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/strings.en
new file mode 100644
index 0000000..f1a6f8c
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.generic-image-classification/strings.en
@@ -0,0 +1,4 @@
+org.streampipes.processor.imageclassification.jvm.generic-image-classification.title=Generic Image Classification
+org.streampipes.processor.imageclassification.jvm.generic-image-classification.description=Classification Description (Generic Model)
+
+image-mapping.title=Image field
\ No newline at end of file
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/documentation.md b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/documentation.md
new file mode 100644
index 0000000..496bbf2
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/documentation.md
@@ -0,0 +1,30 @@
+## Image Cropper
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Image Enrichment: Crops an  + image based on  + given bounding box coordinates
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/icon.png b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/icon.png
new file mode 100644
index 0000000..c35c817
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/icon.png
Binary files differ
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/strings.en b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/strings.en
new file mode 100644
index 0000000..80848f1
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-cropper/strings.en
@@ -0,0 +1,2 @@
+org.streampipes.processor.imageclassification.jvm.image-cropper.title=Image Cropper
+org.streampipes.processor.imageclassification.jvm.image-cropper.description=Crops an image based on given bounding box coordinates
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/documentation.md b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/documentation.md
new file mode 100644
index 0000000..1546e07
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/documentation.md
@@ -0,0 +1,30 @@
+## Image Enricher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Image Enrichment: Enriches an  + image with  + given bounding box coordinates
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/icon.png b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/icon.png
new file mode 100644
index 0000000..50beeff
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/icon.png
Binary files differ
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/strings.en b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/strings.en
new file mode 100644
index 0000000..7b4d666
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.jvm.image-enricher/strings.en
@@ -0,0 +1,2 @@
+org.streampipes.processor.imageclassification.jvm.image-enricher.title=Image Enricher
+org.streampipes.processor.imageclassification.jvm.image-enricher.description=Enriches an image with a bounding box of given coordinates
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/documentation.md b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/documentation.md
new file mode 100644
index 0000000..6e67828
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/documentation.md
@@ -0,0 +1,30 @@
+## QR Code Reader
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+QR Code Reader: Detects a QR Code in an image
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/icon.png b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/icon.png
new file mode 100644
index 0000000..ade3a54
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/icon.png
Binary files differ
diff --git a/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/strings.en b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/strings.en
new file mode 100644
index 0000000..d1b11e8
--- /dev/null
+++ b/streampipes-processors-image-processing-jvm/src/main/resources/org.streampipes.processor.imageclassification.qrcode/strings.en
@@ -0,0 +1,14 @@
+org.streampipes.processor.imageclassification.qrcode.title=QR Code Reader
+org.streampipes.processor.imageclassification.qrcode.description=Detects a QR Code in an image
+
+send-if-no-result.title=Send placeholder value if no qr code is detected
+send-if-no-result.description=
+
+placeholder-value.title=Placeholder value
+placeholder-value.description=
+
+qr-value.title=QR code value
+qr-value.description=
+
+image-property.title=Image
+image-property.description=
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/pom.xml b/streampipes-processors-pattern-detection-flink/pom.xml
index 81fbe40..be71028 100644
--- a/streampipes-processors-pattern-detection-flink/pom.xml
+++ b/streampipes-processors-pattern-detection-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/PatternDetectionFlinkInit.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/PatternDetectionFlinkInit.java
index cd60550..6ef5553 100644
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/PatternDetectionFlinkInit.java
+++ b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/PatternDetectionFlinkInit.java
@@ -19,18 +19,16 @@
 import org.streampipes.container.init.DeclarersSingleton;
 import org.streampipes.container.standalone.init.StandaloneModelSubmitter;
 import org.streampipes.processors.pattern.detection.flink.config.PatternDetectionFlinkConfig;
-import org.streampipes.processors.pattern.detection.flink.processor.increase.IncreaseController;
 import org.streampipes.processors.pattern.detection.flink.processor.peak.PeakDetectionController;
 
 public class PatternDetectionFlinkInit extends StandaloneModelSubmitter {
 
   public static void main(String[] args) {
     DeclarersSingleton.getInstance()
-            .add(new IncreaseController())
             .add(new PeakDetectionController());
-            //.add(new SequenceController());
-            //.add(new AbsenceController())
-            //.add(new AndController());
+//            .add(new SequenceController())
+//            .add(new AbsenceController())
+//            .add(new AndController());
 
     new PatternDetectionFlinkInit().init(PatternDetectionFlinkConfig.INSTANCE);
   }
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/absence/AbsenceController.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/absence/AbsenceController.java
index 7b76c49..a300567 100644
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/absence/AbsenceController.java
+++ b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/absence/AbsenceController.java
@@ -10,6 +10,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -23,7 +24,9 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.absence", "Absence", "Detects whether an event does not arrive within a specified time after the occurrence of another event.")
+    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.absence")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
             .category(DataProcessorType.PATTERN_DETECT)
             .requiredStream(StreamRequirementsBuilder
                     .create()
@@ -33,8 +36,9 @@
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
-            .requiredSingleValueSelection(Labels.from(TIME_UNIT, "Time Unit", "The time unit used for detecting the co-occurrence."), Options.from("Seconds", "Minutes", "Hours"))
-            .requiredIntegerParameter(Labels.from(TIME_WINDOW, "Time Window Size", "Time window size (seconds)"))
+            .requiredSingleValueSelection(Labels.withId(TIME_UNIT), Options.from("Seconds",
+                    "Minutes", "Hours"))
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW))
             .outputStrategy(OutputStrategies.custom(false))
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/and/AndController.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/and/AndController.java
index 53037f2..373502c 100644
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/and/AndController.java
+++ b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/and/AndController.java
@@ -9,6 +9,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -23,19 +24,25 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.and", "And", "Detects whether an event co-occurs with another event within a given time..")
+    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.and")
             .category(DataProcessorType.PATTERN_DETECT)
-            .iconUrl(PatternDetectionFlinkConfig.getIconUrl("And_Icon"))
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(), Labels.from("left-mapping", "Left Mapping", ""), PropertyScope.DIMENSION_PROPERTY)
+                    .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(),
+                            Labels.withId(LEFT_MAPPING)
+                            , PropertyScope.DIMENSION_PROPERTY)
                     .build())
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(), Labels.from("right-mapping", "Right Mapping", ""), PropertyScope.DIMENSION_PROPERTY)
+                    .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(),
+                            Labels.withId(RIGHT_MAPPING)
+                            , PropertyScope.DIMENSION_PROPERTY)
                     .build())
-            .requiredSingleValueSelection(Labels.from(TIME_UNIT, "Time Unit", "The time unit used for detecting the co-occurrence."), Options.from("Seconds", "Minutes", "Hours"))
-            .requiredIntegerParameter(Labels.from(TIME_WINDOW, "Time Window Size", "Time window size (seconds)"))
+            .requiredSingleValueSelection(Labels.withId(TIME_UNIT), Options.from("Seconds",
+                    "Minutes", "Hours"))
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW))
             .outputStrategy(OutputStrategies.custom(true))
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/Increase.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/Increase.java
deleted file mode 100644
index ae7815a..0000000
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/Increase.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2017 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.streampipes.processors.pattern.detection.flink.processor.increase;
-
-import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
-import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
-import org.apache.flink.util.Collector;
-import org.streampipes.model.runtime.Event;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Increase implements WindowFunction<Event, Event, String, TimeWindow> {
-
-  private String propertyFieldName;
-  private Integer increaseValue;
-  private Operation operation;
-  private List<String> outputProperties;
-  private String groupByFieldName;
-
-  public Increase(Integer increaseValue, Operation operation, String mapping, List<String> outputProperties, String
-          groupByFieldName) {
-    this.propertyFieldName = mapping;
-    this.increaseValue = increaseValue;
-    this.operation = operation;
-    this.outputProperties = outputProperties;
-    this.groupByFieldName = groupByFieldName;
-  }
-
-  @Override
-  public void apply(String key, TimeWindow window, Iterable<Event> input, Collector<Event>
-          out) throws Exception {
-
-    List<Double> values = new ArrayList<>();
-    Event lastEvent = new Event();
-
-    for (Event anInput : input) {
-      lastEvent = anInput;
-      if (lastEvent.getFieldBySelector(groupByFieldName).getAsPrimitive().getAsString().equals(key)) {
-        values.add(lastEvent.getFieldBySelector(propertyFieldName).getAsPrimitive().getAsDouble());
-      }
-    }
-    if (values.size() > 0) {
-      if (operation == Operation.INCREASE) {
-        if (values.get(values.size()-1) >= values.get(0) * (1 + increaseValue / 100)) {
-          buildOutput(out, lastEvent);
-        }
-      } else {
-        // 1 <= 2 - (2* (1- 10 / 100) <=> 1 <= 2*0
-        if (values.get(values.size()-1) <= values.get(0) - (values.get(values.size()-1) * (1 - (increaseValue / 100)))) {
-          buildOutput(out, lastEvent);
-        }
-      }
-    }
-  }
-
-  private void buildOutput(Collector<Event> out, Event lastEvent) {
-    Event outEvent = new Event();
-    for(String outputProperty : outputProperties) {
-      outEvent.addField(lastEvent.getFieldBySelector(outputProperty));
-    }
-
-    out.collect(outEvent);
-  }
-
-}
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseController.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseController.java
deleted file mode 100644
index e1f8ffd..0000000
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseController.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2017 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.streampipes.processors.pattern.detection.flink.processor.increase;
-
-import org.streampipes.model.DataProcessorType;
-import org.streampipes.model.graph.DataProcessorDescription;
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.pattern.detection.flink.config.PatternDetectionFlinkConfig;
-import org.streampipes.sdk.builder.ProcessingElementBuilder;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
-import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
-import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
-
-public class IncreaseController extends FlinkDataProcessorDeclarer<IncreaseParameters> {
-
-  private static final String PARTITION_BY = "partition-by";
-  private static final String TIMESTAMP = "timestamp";
-  private static final String VALUE_MAPPING = "value-mapping";
-  private static final String INCREASE = "increase";
-  private static final String DURATION = "duration";
-  private static final String OPERATION = "operation";
-
-  @Override
-  public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.increase", "Increase", "Detects the increase of a numerical field over a customizable time window. Example: A temperature value increases by 10 percent within 5 minutes.")
-            .category(DataProcessorType.PATTERN_DETECT)
-            .iconUrl(PatternDetectionFlinkConfig.getIconUrl("increase-icon"))
-            .requiredStream(StreamRequirementsBuilder
-                    .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements
-                            .numberReq(), Labels.from(VALUE_MAPPING, "Value to observe", "Specifies the value that should be " +
-                            "monitored."), PropertyScope.MEASUREMENT_PROPERTY)
-                    .requiredPropertyWithUnaryMapping(EpRequirements
-                            .timestampReq(), Labels.from(TIMESTAMP, "Timestamp field", "The field that contains " +
-                            "the event's timestamp"), PropertyScope.HEADER_PROPERTY)
-                    .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(),
-                            Labels.from(PARTITION_BY, "Group by", "Partition the stream by a given id"), PropertyScope
-                                    .DIMENSION_PROPERTY)
-                    .build())
-            .requiredIntegerParameter(INCREASE, "Percentage of Increase/Decrease", "Specifies the increase in " +
-                    "percent (e.g., 100 indicates an increase by 100 percent within the specified time window.", 0, 500, 1)
-            .requiredIntegerParameter(Labels.from(DURATION, "Time Window Length (Seconds)", "Specifies the size of the time window in seconds."))
-            .requiredSingleValueSelection(Labels.from(OPERATION, "Increase/Decrease", "Specifies the type of operation the " +
-                    "processor should perform."), Options.from("Increase", "Decrease"))
-            .outputStrategy(OutputStrategies.custom(true))
-            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-            .supportedFormats(SupportedFormats.jsonFormat())
-            .build();
-  }
-
-  @Override
-  public FlinkDataProcessorRuntime<IncreaseParameters> getRuntime(DataProcessorInvocation graph,
-                                                                  ProcessingElementParameterExtractor extractor) {
-
-    String operation = extractor.selectedSingleValue(OPERATION, String.class);
-    Integer increase = extractor.singleValueParameter(INCREASE, Integer.class);
-    Integer duration = extractor.singleValueParameter(DURATION, Integer.class);
-    String mapping = extractor.mappingPropertyValue(VALUE_MAPPING);
-    String groupBy = extractor.mappingPropertyValue(PARTITION_BY);
-    String timestampField = extractor.mappingPropertyValue(TIMESTAMP);
-
-    IncreaseParameters params = new IncreaseParameters(graph, getOperation(operation), increase, duration, mapping,
-            groupBy, timestampField);
-
-    return new IncreaseProgram(params, PatternDetectionFlinkConfig.INSTANCE.getDebug());
-
-  }
-
-  private Operation getOperation(String operation) {
-    if (operation.equals("Increase")) {
-      return Operation.INCREASE;
-    } else {
-      return Operation.DECREASE;
-    }
-  }
-}
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseParameters.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseParameters.java
deleted file mode 100644
index aa9f8c4..0000000
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseParameters.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2017 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.streampipes.processors.pattern.detection.flink.processor.increase;
-
-import org.streampipes.model.graph.DataProcessorInvocation;
-import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
-
-public class IncreaseParameters extends EventProcessorBindingParams {
-
-	private Operation operation;
-	private int increase;
-	private int duration;
-	
-	private String mapping;
-	private String groupBy;
-	private String timestampField;
-
-	public IncreaseParameters(DataProcessorInvocation invocationGraph,
-			Operation operation, int increase, int duration,
-			String mapping, String groupBy, String timestampField) {
-		super(invocationGraph);
-		this.operation = operation;
-		this.increase = increase;
-		this.duration = duration;
-		this.mapping = mapping;
-		this.groupBy = groupBy;
-		this.timestampField = timestampField;
-	}
-
-
-	public Operation getOperation() {
-		return operation;
-	}
-
-	public int getIncrease() {
-		return increase;
-	}
-
-	public int getDuration() {
-		return duration;
-	}
-
-	public String getMapping() {
-		return mapping;
-	}
-
-	public String getGroupBy() {
-		return groupBy;
-	}
-
-	public String getTimestampField() {
-		return timestampField;
-	}
-}
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseProgram.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseProgram.java
deleted file mode 100644
index 3ff16a3..0000000
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/increase/IncreaseProgram.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2017 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.streampipes.processors.pattern.detection.flink.processor.increase;
-
-import org.apache.flink.api.java.functions.KeySelector;
-import org.apache.flink.streaming.api.datastream.DataStream;
-import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
-import org.apache.flink.streaming.api.windowing.time.Time;
-import org.streampipes.model.runtime.Event;
-import org.streampipes.processors.pattern.detection.flink.AbstractPatternDetectionProgram;
-import org.streampipes.processors.pattern.detection.flink.processor.common.TimestampExtractor;
-
-public class IncreaseProgram extends AbstractPatternDetectionProgram<IncreaseParameters> {
-
-  public IncreaseProgram(IncreaseParameters params, boolean debug) {
-    super(params, debug);
-  }
-
-  @Override
-  public DataStream<Event> getApplicationLogic(DataStream<Event>... dataStreams) {
-    String timestampField = params.getTimestampField();
-    return dataStreams[0]
-            .assignTimestampsAndWatermarks(new TimestampExtractor(timestampField))
-            .keyBy(getKeySelector())
-            .window(TumblingEventTimeWindows.of(Time.seconds(params.getDuration())))
-            .apply(new Increase(params.getIncrease(), params.getOperation(), params.getMapping(), params
-                    .getOutputProperties(), params.getGroupBy())).setParallelism(1);
-  }
-
-  private KeySelector<Event, String> getKeySelector() {
-    String groupBy = params.getGroupBy();
-    return new KeySelector<Event, String>() {
-      @Override
-      public String getKey(Event in) throws Exception {
-        return in.getFieldBySelector(groupBy).getAsPrimitive().getAsString();
-      }
-    };
-  }
-}
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/peak/PeakDetectionController.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/peak/PeakDetectionController.java
index f1d2168..9b32759 100644
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/peak/PeakDetectionController.java
+++ b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/peak/PeakDetectionController.java
@@ -25,6 +25,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -43,26 +44,22 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.peak-detection", "Peak Detection",
-            "Detect peaks in time series data")
+    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.peak-detection")
             .category(DataProcessorType.ALGORITHM)
-            .iconUrl(PatternDetectionFlinkConfig.getIconUrl("peak-detection-icon"))
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder.create().requiredPropertyWithUnaryMapping(EpRequirements
                             .numberReq(),
-                    Labels.from(VALUE_TO_OBSERVE, "Value to " +
-                            "observe", "Provide a value where statistics are calculated upon"), PropertyScope.MEASUREMENT_PROPERTY)
+                    Labels.withId(VALUE_TO_OBSERVE), PropertyScope.MEASUREMENT_PROPERTY)
                     .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(),
-                            Labels.from(TIMESTAMP_MAPPING, "Time", "Provide a time parameter"), PropertyScope.NONE)
+                            Labels.withId(TIMESTAMP_MAPPING), PropertyScope.NONE)
                     .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(),
-                            Labels.from(PARTITION_BY, "Group by", "Partition the stream by a given id"), PropertyScope
+                            Labels.withId(PARTITION_BY), PropertyScope
                                     .DIMENSION_PROPERTY).build())
-            .requiredIntegerParameter(Labels.from(COUNT_WINDOW_SIZE, "Count Window Size", "Defines " +
-                    "the size of the count window"), 60)
-            .requiredIntegerParameter(Labels.from(LAG_KEY, "Lag", "Defines the lag of the smoothing " +
-                    "function"), 5)
-            .requiredFloatParameter(Labels.from(THRESHOLD_KEY, "Threshold", "Defines the standard deviation " +
-                    "threshold"), 2.0f)
-            .requiredFloatParameter(Labels.from(INFLUENCE_KEY, "Influence", "Defines the influence"), 0.5f)
+            .requiredIntegerParameter(Labels.withId(COUNT_WINDOW_SIZE), 60)
+            .requiredIntegerParameter(Labels.withId(LAG_KEY), 5)
+            .requiredFloatParameter(Labels.withId(THRESHOLD_KEY), 2.0f)
+            .requiredFloatParameter(Labels.withId(INFLUENCE_KEY), 0.5f)
             .outputStrategy(OutputStrategies.fixed(
                     EpProperties.timestampProperty("timestamp"),
                     EpProperties.stringEp(Labels.empty(), "id", "http://schema.org/id"),
diff --git a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/sequence/SequenceController.java b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/sequence/SequenceController.java
index d1f928c..785e2da 100644
--- a/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/sequence/SequenceController.java
+++ b/streampipes-processors-pattern-detection-flink/src/main/java/org/streampipes/processors/pattern/detection/flink/processor/sequence/SequenceController.java
@@ -24,6 +24,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -34,14 +35,15 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.sequence", "Sequence", "Detects a sequence of events in the following form: Event A followed by Event B within X seconds. In addition, both streams can be matched by a common property value (e.g., a.machineId = b.machineId)")
+    return ProcessingElementBuilder.create("org.streampipes.processors.pattern-detection.flink.sequence")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .category(DataProcessorType.PATTERN_DETECT)
-            .iconUrl(PatternDetectionFlinkConfig.getIconUrl("Sequence_Icon_HQ"))
             .requiredStream(StreamRequirementsBuilder.create().requiredProperty(EpRequirements.anyProperty()).build())
             .requiredStream(StreamRequirementsBuilder.create().requiredProperty(EpRequirements.anyProperty()).build())
-            .requiredIntegerParameter(Labels.from(TIME_WINDOW, "Time Window Size", "Size of the time window "))
-            .requiredSingleValueSelection(Labels.from(TIME_UNIT, "Time Unit", "Specifies a unit for the time window of the " +
-                    "sequence. "), Options.from("sec", "min", "hrs"))
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW))
+            .requiredSingleValueSelection(Labels.withId(TIME_UNIT), Options.from("sec", "min",
+                    "hrs"))
             .outputStrategy(OutputStrategies.keep(false))
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.absence/documentation.md b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.absence/documentation.md
new file mode 100644
index 0000000..2a2c347
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.absence/documentation.md
@@ -0,0 +1,30 @@
+## Absence
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detects whether an event does not arrive within a specified time after the occurrence of another event.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.absence/strings.en b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.absence/strings.en
new file mode 100644
index 0000000..3bf1633
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.absence/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.pattern-detection.flink.absence.title=Absence
+org.streampipes.processors.pattern-detection.flink.absence.description=Detects whether an event does not arrive within a specified time after the occurrence of another event.
+
+time-window.title=Time Window
+time-window.description=Time window size (seconds)
+
+time-unit.title=Time Unit
+time-unit.description=The time unit used for detecting the co-occurrence.
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/documentation.md b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/documentation.md
new file mode 100644
index 0000000..445c8ba
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/documentation.md
@@ -0,0 +1,30 @@
+## And
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detects whether an event co-occurs with another event within a given time.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/icon.png b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/icon.png
new file mode 100644
index 0000000..23bdcbf
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/icon.png
Binary files differ
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/strings.en b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/strings.en
new file mode 100644
index 0000000..6a99505
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.and/strings.en
@@ -0,0 +1,14 @@
+org.streampipes.processors.pattern-detection.flink.and.title=And
+org.streampipes.processors.pattern-detection.flink.and.description=Detects whether an event co-occurs with another event within a given time.
+
+time-window.title=Time Window
+time-window.description=Time window size (seconds)
+
+time-unit.title=Time Unit
+time-unit.description=The time unit used for detecting the co-occurrence.
+
+left-mapping.title=Left Mapping
+left-mapping.description=
+
+right-mapping.title=Right Mapping
+right-mapping.description=
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/documentation.md b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/documentation.md
new file mode 100644
index 0000000..71540c8
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/documentation.md
@@ -0,0 +1,30 @@
+## Peak Detection
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detect peaks in time series data
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/icon.png b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/icon.png
new file mode 100644
index 0000000..82d479f
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/icon.png
Binary files differ
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/strings.en b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/strings.en
new file mode 100644
index 0000000..ef64e28
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.peak-detection/strings.en
@@ -0,0 +1,23 @@
+org.streampipes.processors.pattern-detection.flink.peak-detection.title=Peak Detection
+org.streampipes.processors.pattern-detection.flink.peak-detection.description=Detect peaks in time series data
+
+value-to-observe.title=Value to Observe
+value-to-observe.description=Provide a value where statistics are calculated upon
+
+partition-by.title=Group by
+partition-by.description=Partition the stream by a given id
+
+timestamp-mapping.title=Time
+timestam-mapping.description=Provide a time parameter
+
+sp-lag.title=Lag
+sp-lag.description=Defines the lag of the smoothing function
+
+sp-threshold.title=Threshold
+sp-threshold.description=Defines the standard deviation threshold
+
+sp-count-window.title=Count Window Size
+sp-count-window.description=Defines the size of the count window
+
+sp-influence.title=Influence
+sp-influence.description=Defines the influence
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/documentation.md b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/documentation.md
new file mode 100644
index 0000000..0a4bd6b
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/documentation.md
@@ -0,0 +1,30 @@
+## Sequence
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detects a sequence of events in the following form: Event A followed by Event B within X seconds. In addition, both streams can be matched by a common property value (e.g., a.machineId = b.machineId)
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/icon.png b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/icon.png
new file mode 100644
index 0000000..aaab7bd
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/icon.png
Binary files differ
diff --git a/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/strings.en b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/strings.en
new file mode 100644
index 0000000..6d7c90b
--- /dev/null
+++ b/streampipes-processors-pattern-detection-flink/src/main/resources/org.streampipes.processors.pattern-detection.flink.sequence/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.pattern-detection.flink.sequence.title=Sequence
+org.streampipes.processors.pattern-detection.flink.sequence.description=Detects a sequence of events.
+
+timeWindow.title=Time Window Size
+timeWindow.description=Size of the time window
+
+timeUnit.title=Time Unit
+timeUnit.description=Specifies a unit for the time window of the sequence.
\ No newline at end of file
diff --git a/streampipes-processors-pattern-detection-flink/src/test/java/org/streampipes/processors/pattern/detection/processor/increase/TestIncrease.java b/streampipes-processors-pattern-detection-flink/src/test/java/org/streampipes/processors/pattern/detection/processor/increase/TestIncrease.java
deleted file mode 100644
index 702f2fe..0000000
--- a/streampipes-processors-pattern-detection-flink/src/test/java/org/streampipes/processors/pattern/detection/processor/increase/TestIncrease.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.pattern.detection.processor.increase;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-
-import io.flinkspector.core.input.Input;
-import io.flinkspector.core.input.InputBuilder;
-import io.flinkspector.datastream.DataStreamTestBase;
-import org.apache.flink.streaming.api.datastream.DataStream;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.streampipes.model.runtime.Event;
-import org.streampipes.processors.pattern.detection.flink.processor.increase.IncreaseController;
-import org.streampipes.processors.pattern.detection.flink.processor.increase.IncreaseParameters;
-import org.streampipes.processors.pattern.detection.flink.processor.increase.IncreaseProgram;
-import org.streampipes.processors.pattern.detection.flink.processor.increase.Operation;
-import org.streampipes.test.generator.InvocationGraphGenerator;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-@RunWith(Parameterized.class)
-public class TestIncrease extends DataStreamTestBase {
-
-  @Parameterized.Parameters
-  public static Iterable<Object[]> data() {
-    return Arrays.asList(new Object[][]{
-            {Operation.INCREASE, 100, 10, 1.0f, 2.0f, 5000, true},
-            {Operation.DECREASE, 100, 10, 2.0f, 0.0f, 5000, true},
-            {Operation.DECREASE, 50, 10, 2.0f, 1.0f, 5000, true},
-            {Operation.DECREASE, 50, 10, 2.0f, 1.5f, 5000, false},
-            {Operation.INCREASE, 100, 10, 1.0f, 2.0f, 11000, false},
-    });
-  }
-
-  @Parameterized.Parameter
-  public Operation operation;
-
-  @Parameterized.Parameter(1)
-  public Integer increase;
-
-  @Parameterized.Parameter(2)
-  public Integer duration;
-
-  @Parameterized.Parameter(3)
-  public Float value1;
-
-  @Parameterized.Parameter(4)
-  public Float value2;
-
-  @Parameterized.Parameter(5)
-  public Integer waitForMs;
-
-  @Parameterized.Parameter(6)
-  public Boolean shouldMatch;
-
-
-  @Test
-  public void testIncreaseProgram() {
-    IncreaseParameters params = new IncreaseParameters(InvocationGraphGenerator
-            .makeInvocationWithOutputProperties(new IncreaseController().declareModel(), Arrays.asList("id", "timestamp", "value")),
-            operation,
-            increase,
-            duration,
-            "value",
-            "id",
-            "timestamp");
-
-
-    IncreaseProgram program = new IncreaseProgram(params, true);
-
-    DataStream<Event> stream = program.getApplicationLogic(createTestStream(makeInputData(makeMap())));
-
-    assertStream(stream, equalTo(getOutput(shouldMatch)));
-  }
-
-  private Collection<Event> getOutput(Boolean shouldMatch) {
-    List<Event> allEvents = new ArrayList<>();
-
-    if (shouldMatch) {
-     allEvents.add(makeMap().get(1));
-    }
-
-    return allEvents;
-  }
-
-  private Input<Event> makeInputData(List<Event> inputMap) {
-    List<Event> testData = inputMap;
-    InputBuilder<Event> builder = InputBuilder.startWith(testData.get(0));
-    for(int i = 1; i < inputMap.size(); i++) {
-      builder.emit(inputMap.get(i));
-    }
-    return builder;
-  }
-
-  private List<Event> makeMap() {
-    List<Event> allEvents = new ArrayList<>();
-    Event event1 = new Event();
-    event1.addField("id", "a");
-    event1.addField("timestamp", 0);
-    event1.addField("value", value1);
-
-    allEvents.add(event1);
-
-    Event event2 = new Event();
-    event2.addField("id", "a");
-    event2.addField("timestamp", waitForMs);
-    event2.addField("value", value2);
-
-    allEvents.add(event2);
-
-    return allEvents;
-  }
-
-
-}
diff --git a/streampipes-processors-statistics-flink/pom.xml b/streampipes-processors-statistics-flink/pom.xml
index 5873ef6..b27be4c 100644
--- a/streampipes-processors-statistics-flink/pom.xml
+++ b/streampipes-processors-statistics-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/StatisticsFlinkInit.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/StatisticsFlinkInit.java
index 1f02a5d..9644b67 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/StatisticsFlinkInit.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/StatisticsFlinkInit.java
@@ -20,7 +20,7 @@
 import org.streampipes.container.init.DeclarersSingleton;
 import org.streampipes.container.standalone.init.StandaloneModelSubmitter;
 import org.streampipes.processors.statistics.flink.config.StatisticsFlinkConfig;
-import org.streampipes.processors.statistics.flink.processor.stat.StatisticsSummaryController;
+import org.streampipes.processors.statistics.flink.processor.stat.summary.StatisticsSummaryController;
 import org.streampipes.processors.statistics.flink.processor.stat.window.StatisticsSummaryControllerWindow;
 
 public class StatisticsFlinkInit extends StandaloneModelSubmitter {
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryCalculator.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryCalculator.java
similarity index 96%
rename from streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryCalculator.java
rename to streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryCalculator.java
index 54e1d7e..74aec40 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryCalculator.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryCalculator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
  *
  */
 
-package org.streampipes.processors.statistics.flink.processor.stat;
+package org.streampipes.processors.statistics.flink.processor.stat.summary;
 
 import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
 import org.apache.flink.api.common.functions.FlatMapFunction;
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryController.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryController.java
similarity index 80%
rename from streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryController.java
rename to streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryController.java
index d85cb5f..e943457 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryController.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
  *
  */
 
-package org.streampipes.processors.statistics.flink.processor.stat;
+package org.streampipes.processors.statistics.flink.processor.stat.summary;
 
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
@@ -24,7 +24,14 @@
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.helpers.EpProperties;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.sdk.utils.Datatypes;
 import org.streampipes.vocabulary.Statistics;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
@@ -44,13 +51,13 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.statistics.flink.statistics-summary", "Statistics Summary", "Calculate" +
-            " simple descriptive summary statistics")
-            .iconUrl(StatisticsFlinkConfig.getIconUrl("statistical_summary"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.statistics.flink.statistics-summary")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(EpRequirements.listRequirement(Datatypes
-                    .Number), Labels.from(listPropertyMappingName, "Property", "Select a list property"), PropertyScope.MEASUREMENT_PROPERTY)
+                    .Number), Labels.withId(listPropertyMappingName), PropertyScope.MEASUREMENT_PROPERTY)
                     .build())
             .outputStrategy(OutputStrategies.append(EpProperties.doubleEp(Labels.empty(), MEAN, Statistics
                             .MEAN),
@@ -71,7 +78,7 @@
 
     StatisticsSummaryParameters params = new StatisticsSummaryParameters(graph, listPropertyMapping);
 
-    return new StatisticsSummaryProgram(params);
+    return new StatisticsSummaryProgram(params, StatisticsFlinkConfig.INSTANCE.getDebug());
 
   }
 }
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryParameters.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryParameters.java
similarity index 94%
rename from streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryParameters.java
rename to streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryParameters.java
index b850cdc..5485036 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryParameters.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryParameters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
  *
  */
 
-package org.streampipes.processors.statistics.flink.processor.stat;
+package org.streampipes.processors.statistics.flink.processor.stat.summary;
 
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryProgram.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryProgram.java
similarity index 95%
rename from streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryProgram.java
rename to streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryProgram.java
index 5797602..81d8c04 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/StatisticsSummaryProgram.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/summary/StatisticsSummaryProgram.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 FZI Forschungszentrum Informatik
+ * Copyright 2019 FZI Forschungszentrum Informatik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
  *
  */
 
-package org.streampipes.processors.statistics.flink.processor.stat;
+package org.streampipes.processors.statistics.flink.processor.stat.summary;
 
 import org.apache.flink.streaming.api.datastream.DataStream;
 import org.streampipes.model.runtime.Event;
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryCalculatorWindow.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryCalculatorWindow.java
index 4e0fffa..020581c 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryCalculatorWindow.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryCalculatorWindow.java
@@ -21,7 +21,7 @@
 import org.apache.flink.api.common.functions.FlatMapFunction;
 import org.apache.flink.util.Collector;
 import org.streampipes.model.runtime.Event;
-import org.streampipes.processors.statistics.flink.processor.stat.StatisticsSummaryController;
+import org.streampipes.processors.statistics.flink.processor.stat.summary.StatisticsSummaryController;
 
 import java.io.Serializable;
 import java.util.List;
diff --git a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryControllerWindow.java b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryControllerWindow.java
index 926058c..03dfd70 100644
--- a/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryControllerWindow.java
+++ b/streampipes-processors-statistics-flink/src/main/java/org/streampipes/processors/statistics/flink/processor/stat/window/StatisticsSummaryControllerWindow.java
@@ -21,11 +21,12 @@
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
 import org.streampipes.processors.statistics.flink.config.StatisticsFlinkConfig;
-import org.streampipes.processors.statistics.flink.processor.stat.StatisticsSummaryController;
+import org.streampipes.processors.statistics.flink.processor.stat.summary.StatisticsSummaryController;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.Statistics;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -43,23 +44,21 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.statistics.flink.statistics-summary-window", "Sliding Descriptive " +
-                    "Statistics",
-            "Calculate" +
-                    " simple descriptive summary statistics based on a configurable time window")
-            .iconUrl(StatisticsFlinkConfig.getIconUrl("statistics-icon"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.statistics.flink.statistics-summary-window")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(EpRequirements.numberReq(),
-                            Labels.from(VALUE_TO_OBSERVE, "Value to " +
-                                    "observe", "Provide a value where statistics are calculated upon"), PropertyScope.MEASUREMENT_PROPERTY)
+                            Labels.withId(VALUE_TO_OBSERVE), PropertyScope.MEASUREMENT_PROPERTY)
                     .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(),
-                            Labels.from(TIMESTAMP_MAPPING, "Time", "Provide a time parameter"), PropertyScope.HEADER_PROPERTY)
+                            Labels.withId(TIMESTAMP_MAPPING),
+                            PropertyScope.HEADER_PROPERTY)
                     .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(),
-                            Labels.from(PARTITION_BY, "Group by", "Partition the stream by a given id"), PropertyScope.DIMENSION_PROPERTY)
+                            Labels.withId(PARTITION_BY), PropertyScope.DIMENSION_PROPERTY)
                     .build())
-            .requiredIntegerParameter(Labels.from(TIME_WINDOW, "Time Window Size", "Size of the time window"))
-            .requiredSingleValueSelection(Labels.from(TIME_SCALE, "Time Window Scale", ""),
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW))
+            .requiredSingleValueSelection(Labels.withId(TIME_SCALE),
                     Options.from("Hours", "Minutes", "Seconds"))
             .outputStrategy(OutputStrategies.fixed(
                     EpProperties.timestampProperty("timestamp"),
@@ -105,7 +104,7 @@
     StatisticsSummaryParamsSerializable serializableParams = new StatisticsSummaryParamsSerializable
             (valueToObserve, timestampMapping, groupBy, (long) timeWindowSize, timeUnit);
 
-    return new StatisticsSummaryProgramWindow(params, serializableParams);
+    return new StatisticsSummaryProgramWindow(params, serializableParams, StatisticsFlinkConfig.INSTANCE.getDebug());
 
   }
 }
diff --git a/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary-window/icon.png b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary-window/icon.png
new file mode 100644
index 0000000..8cdf4dc
--- /dev/null
+++ b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary-window/icon.png
Binary files differ
diff --git a/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary-window/strings.en b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary-window/strings.en
new file mode 100644
index 0000000..5ac58b5
--- /dev/null
+++ b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary-window/strings.en
@@ -0,0 +1,18 @@
+org.streampipes.processors.statistics.flink.statistics-summary-window.title=Sliding Descriptive Statistics
+org.streampipes.processors.statistics.flink.statistics-summary-window.description=Calculate simple descriptive summary statistics based on a configurable time window
+
+value-to-observe.title=Value to Observe
+value-to-observe.description=Provide a value where statistics are calculated upon
+
+partition-by.title=Group by
+partition-by.description=Partition the stream by a given id
+
+timestamp-mapping.title=Time Field
+timestamp-mapping.description=Provide a time parameter
+
+time-window.title=Time Window Size
+time-window.description=Size of the time window
+
+time-scale.title=Time Window Scale
+time-scale.description=
+
diff --git a/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/documentation.md b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/documentation.md
new file mode 100644
index 0000000..359b661
--- /dev/null
+++ b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/documentation.md
@@ -0,0 +1,30 @@
+## Statistics Summary
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Calculate simple descriptive summary statistics
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/icon.png b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/icon.png
new file mode 100644
index 0000000..c809464
--- /dev/null
+++ b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/icon.png
Binary files differ
diff --git a/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/strings.en b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/strings.en
new file mode 100644
index 0000000..9e5a369
--- /dev/null
+++ b/streampipes-processors-statistics-flink/src/main/resources/org.streampipes.processors.statistics.flink.statistics-summary/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.processors.statistics.flink.statistics-summary.title=Statistics Summary
+org.streampipes.processors.statistics.flink.statistics-summary.description=Calculate simple descriptive summary statistics
+
+list-property.title=Field Name
+list-property.description=Select a list property
\ No newline at end of file
diff --git a/streampipes-processors-text-mining-flink/pom.xml b/streampipes-processors-text-mining-flink/pom.xml
index db27783..d387039 100644
--- a/streampipes-processors-text-mining-flink/pom.xml
+++ b/streampipes-processors-text-mining-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/TextMiningFlinkInit.java b/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/TextMiningFlinkInit.java
index 6f7d8e6..eb068f4 100644
--- a/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/TextMiningFlinkInit.java
+++ b/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/TextMiningFlinkInit.java
@@ -25,6 +25,7 @@
 
   public static void main(String[] args) {
     DeclarersSingleton.getInstance()
+//            .add(new LanguageDetectionController())
             .add(new WordCountController());
 
     new TextMiningFlinkInit().init(TextMiningFlinkConfig.INSTANCE);
diff --git a/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/language/LanguageDetectionController.java b/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/language/LanguageDetectionController.java
index 8e7f383..a6f812a 100644
--- a/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/language/LanguageDetectionController.java
+++ b/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/language/LanguageDetectionController.java
@@ -24,39 +24,37 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
 public class LanguageDetectionController extends FlinkDataProcessorDeclarer<LanguageDetectionParameters> {
 
-  private static final String RESOURCE_ID = "strings.languagedetection";
-  private static final String PE_ID = "org.streampipes.processors.textmining.flink.languagedetection";
-
   private static final String DETECTION_FIELD_KEY = "detectionField";
   private static final String LANGUAGE_KEY = "language";
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create(getLabel(PE_ID))
+    return ProcessingElementBuilder.create("org.streampipes.processors.textmining.flink.languagedetection")
             .category(DataProcessorType.ENRICH_TEXT)
+            .withAssets(Assets.DOCUMENTATION)
+            .withLocales(Locales.EN)
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(
                             EpRequirements.stringReq(),
-                            getLabel(DETECTION_FIELD_KEY),
+                            Labels.withId(DETECTION_FIELD_KEY),
                             PropertyScope.NONE)
                     .build())
             .outputStrategy(OutputStrategies.append(EpProperties.stringEp(
-                    getLabel(LANGUAGE_KEY),
+                    Labels.withId(LANGUAGE_KEY),
                     "language",
                     "http://schema.org/language")))
             .build();
   }
 
-  private Label getLabel(String id) {
-    return Labels.fromResources(RESOURCE_ID, id);
-  }
-
   @Override
   public FlinkDataProcessorRuntime<LanguageDetectionParameters> getRuntime(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
     String fieldName = extractor.mappingPropertyValue(DETECTION_FIELD_KEY);
diff --git a/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/wordcount/WordCountController.java b/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/wordcount/WordCountController.java
index c7ef342..104968f 100644
--- a/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/wordcount/WordCountController.java
+++ b/streampipes-processors-text-mining-flink/src/main/java/org/streampipes/processors/textmining/flink/processor/wordcount/WordCountController.java
@@ -8,40 +8,40 @@
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.EpProperties;
-import org.streampipes.sdk.helpers.EpRequirements;
-import org.streampipes.sdk.helpers.Label;
-import org.streampipes.sdk.helpers.Labels;
-import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
 public class WordCountController extends FlinkDataProcessorDeclarer<WordCountParameters> {
 
-  private static final String RESOURCE_ID = "strings.wordcount";
-  private static final String PE_ID = "org.streampipes.processors.textmining.flink.wordcount";
-
   private static final String WORD_COUNT_FIELD_KEY = "wordcountField";
-  private static final String TIME_WINDOW_KEY = "timeWindowKey";
+  private static final String TIME_WINDOW_KEY = "timeWindow";
   private static final String WORD_KEY = "word";
   private static final String COUNT_KEY = "count";
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create(getLabel(PE_ID))
+    return ProcessingElementBuilder.create("org.streampipes.processors.textmining.flink.wordcount")
+            .withAssets(Assets.DOCUMENTATION)
+            .withLocales(Locales.EN)
             .category(DataProcessorType.AGGREGATE)
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .supportedFormats(SupportedFormats.jsonFormat())
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(
                             EpRequirements.stringReq(),
-                            getLabel(WORD_COUNT_FIELD_KEY),
+                            Labels.withId(WORD_COUNT_FIELD_KEY),
                             PropertyScope.NONE)
                     .build())
             .outputStrategy(OutputStrategies.fixed(EpProperties.stringEp(
-                    getLabel(WORD_KEY),
+                    Labels.withId(WORD_KEY),
                     "word",
-                    "http://schema.org/text"), EpProperties.integerEp(getLabel(COUNT_KEY), "count", "http://schema.org/number")))
-            .requiredIntegerParameter(getLabel(TIME_WINDOW_KEY))
+                    "http://schema.org/text"),
+                    EpProperties.integerEp(Labels.withId(COUNT_KEY),
+                    "count", "http://schema.org/number")))
+            .requiredIntegerParameter(Labels.withId(TIME_WINDOW_KEY))
             .build();
   }
 
@@ -54,8 +54,4 @@
     return new WordCountProgram(new WordCountParameters(graph, fieldName, timeWindowValue), TextMiningFlinkConfig.INSTANCE.getDebug());
 
   }
-
-  private Label getLabel(String id) {
-    return Labels.fromResources(RESOURCE_ID, id);
-  }
 }
diff --git a/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.languagedetection/documentation.md b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.languagedetection/documentation.md
new file mode 100644
index 0000000..9333ecb
--- /dev/null
+++ b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.languagedetection/documentation.md
@@ -0,0 +1,30 @@
+## Language Detection
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Detects the language of a written text.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.languagedetection/strings.en b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.languagedetection/strings.en
new file mode 100644
index 0000000..8e822a4
--- /dev/null
+++ b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.languagedetection/strings.en
@@ -0,0 +1,7 @@
+org.streampipes.processors.textmining.flink.languagedetection.title=Language Detection
+org.streampipes.processors.textmining.flink.languagedetection.description=Detects the language of a written text.
+
+detectionField.title=Field Selection
+detectionField.description=Specifies the field where the language detection should be applied upon.
+
+
diff --git a/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/documentation.md b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/documentation.md
new file mode 100644
index 0000000..32d5721
--- /dev/null
+++ b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/documentation.md
@@ -0,0 +1,30 @@
+## Word Count
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Counts words on continuous text-based streams
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/icon.png b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/icon.png
new file mode 100644
index 0000000..89861c4
--- /dev/null
+++ b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/icon.png
Binary files differ
diff --git a/streampipes-processors-text-mining-flink/src/main/resources/strings.wordcount b/streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/strings.en
similarity index 100%
rename from streampipes-processors-text-mining-flink/src/main/resources/strings.wordcount
rename to streampipes-processors-text-mining-flink/src/main/resources/org.streampipes.processors.textmining.flink.wordcount/strings.en
diff --git a/streampipes-processors-text-mining-flink/src/main/resources/strings.languagedetection b/streampipes-processors-text-mining-flink/src/main/resources/strings.languagedetection
deleted file mode 100644
index faaf935..0000000
--- a/streampipes-processors-text-mining-flink/src/main/resources/strings.languagedetection
+++ /dev/null
@@ -1,7 +0,0 @@
-languagedetection.title=Language Detection
-languagedetection.description=Detects the language of a written text.
-
-detectionField.title=Field Selection
-detectionField.description=Specifies the field where the language detection should be applied upon.
-
-
diff --git a/streampipes-processors-transformation-flink/pom.xml b/streampipes-processors-transformation-flink/pom.xml
index 3734d7c..d89c256 100644
--- a/streampipes-processors-transformation-flink/pom.xml
+++ b/streampipes-processors-transformation-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/TransformationFlinkInit.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/TransformationFlinkInit.java
index 6d03aa6..236806a 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/TransformationFlinkInit.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/TransformationFlinkInit.java
@@ -24,6 +24,7 @@
 import org.streampipes.processors.transformation.flink.processor.converter.FieldConverterController;
 import org.streampipes.processors.transformation.flink.processor.hasher.FieldHasherController;
 import org.streampipes.processors.transformation.flink.processor.mapper.FieldMapperController;
+import org.streampipes.processors.transformation.flink.processor.measurementUnitConverter.MeasurementUnitConverterController;
 import org.streampipes.processors.transformation.flink.processor.rename.FieldRenamerController;
 
 public class TransformationFlinkInit extends StandaloneModelSubmitter {
@@ -33,7 +34,7 @@
             .add(new FieldConverterController())
             .add(new FieldHasherController())
             .add(new FieldMapperController())
-            //.add(new MeasurementUnitConverterController())
+            .add(new MeasurementUnitConverterController())
             .add(new FieldRenamerController())
             .add(new BoilerplateController());
 
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/boilerplate/BoilerplateController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/boilerplate/BoilerplateController.java
index 5b2e4bc..924344a 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/boilerplate/BoilerplateController.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/boilerplate/BoilerplateController.java
@@ -24,6 +24,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -36,17 +37,18 @@
 
     @Override
     public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.processor.boilerplate",
-                "Boilerplate Removal", "Removes boilerplate and extract fulltext from HTML")
-                .iconUrl(TransformationFlinkConfig.getIconUrl("Boilerplate_icon"))
+        return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.processor.boilerplate")
+                .withLocales(Locales.EN)
+                .withAssets(Assets.DOCUMENTATION, Assets.ICON)
                 .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(),
-                            Labels.from(HTML_PROPERTY,"Html", "The property with the html"), PropertyScope.NONE)
+                            Labels.withId(HTML_PROPERTY),
+                            PropertyScope.NONE)
                     .build())
-                .requiredSingleValueSelection(Labels.from(EXTRACTOR, "Extractor", "Common use: Article Extractor"),
+                .requiredSingleValueSelection(Labels.withId(EXTRACTOR),
                         Options.from("Article Extractor", "Default Extractor", "Largest Content Extractor", "Canola Extractor", "Keep Everything Extractor"))
-                .requiredSingleValueSelection(Labels.from(OUTPUT_MODE, "Output Mode", ""),
+                .requiredSingleValueSelection(Labels.withId(OUTPUT_MODE),
                         Options.from("Plain Text", "Highlighted Html", "Html"))
                 .supportedProtocols(SupportedProtocols.kafka())
                 .supportedFormats(SupportedFormats.jsonFormat())
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverter.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverter.java
index 01a680a..68f4867 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverter.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverter.java
@@ -41,9 +41,9 @@
       String value = in.getFieldBySelector(convertProperty).getAsPrimitive().getAsString();
       try {
           if (targetDatatype.equals(XSD._float.toString())) {
-              in.updateFieldBySelector(convertProperty, Float.parseFloat(value));
+              in.updateFieldBySelector(convertProperty, Float.parseFloat(value.trim()));
           } else {
-              in.updateFieldBySelector(convertProperty, Integer.parseInt(value));
+              in.updateFieldBySelector(convertProperty, Integer.parseInt(value.trim()));
           }
           
           out.collect(in);
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverterController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverterController.java
index cf6d4df..899fa26 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverterController.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/converter/FieldConverterController.java
@@ -19,11 +19,19 @@
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.transformation.flink.config.TransformationFlinkConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
-import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.helpers.TransformOperations;
+import org.streampipes.sdk.helpers.Tuple2;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.XSD;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -36,16 +44,15 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.field-converter", "Field Converter",
-            "Converts a string value to a number data type")
-            .iconUrl(TransformationFlinkConfig.getIconUrl("field_converter"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.field-converter")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(), Labels.from
-                            (CONVERT_PROPERTY,"Property", "The" +
-                                    " property to convert"), PropertyScope.NONE)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.stringReq(), Labels.withId
+                            (CONVERT_PROPERTY), PropertyScope.NONE)
                     .build())
-            .requiredSingleValueSelection(Labels.from(TARGET_TYPE, "Datatype", "The target datatype"), Options.from
+            .requiredSingleValueSelection(Labels.withId(TARGET_TYPE), Options.from
                     (new Tuple2<>("Float", XSD._float.toString()), new Tuple2<>
                             ("Integer", XSD._integer.toString())))
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/hasher/FieldHasherController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/hasher/FieldHasherController.java
index bc27021..3966b97 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/hasher/FieldHasherController.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/hasher/FieldHasherController.java
@@ -20,17 +20,18 @@
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.transformation.flink.config.TransformationFlinkConfig;
 import org.streampipes.processors.transformation.flink.processor.hasher.algorithm.HashAlgorithmType;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.Options;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -41,15 +42,15 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.fieldhasher", "Field Hasher",
-            "The Field Hasher uses an algorithm to encode values in a field. The Field Hasher can use MD5, SHA1 or SHA2 to hash field values.")
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.fieldhasher")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(), Labels.from
-                            (HASH_PROPERTIES, "Field", "The field the hash function should be applied on"), PropertyScope.NONE)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(), Labels.withId
+                            (HASH_PROPERTIES), PropertyScope.NONE)
                     .build())
-            .iconUrl(TransformationFlinkConfig.getIconUrl("field-hasher-icon"))
-            .requiredSingleValueSelection(Labels.from("hash-algorithm", "Hash Algorithm", "The hash algorithm that should be used."),
+            .requiredSingleValueSelection(Labels.withId(HASH_ALGORITHM),
                     Options.from("SHA1", "SHA2", "MD5"))
             .outputStrategy(OutputStrategies.keep())
             .supportedFormats(SupportedFormats.jsonFormat())
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/mapper/FieldMapperController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/mapper/FieldMapperController.java
index d8ff5ad..f6d313e 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/mapper/FieldMapperController.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/mapper/FieldMapperController.java
@@ -29,9 +29,11 @@
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.sdk.utils.Datatypes;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -47,15 +49,15 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.field-mapper", "Field Mapper",
-            "Replaces one or more field with a new field and computes a hash value of these fields")
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.field-mapper")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(), Labels.from
-                            (REPLACE_PROPERTIES,"Fields", "The" +
-                                    " fields to replace"), PropertyScope.NONE)
+                    .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(), Labels.withId
+                            (REPLACE_PROPERTIES), PropertyScope.NONE)
                     .build())
-            .requiredTextParameter(Labels.from(FIELD_NAME, "The name of the new field ", ""))
+            .requiredTextParameter(Labels.withId(FIELD_NAME))
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
             .outputStrategy(OutputStrategies.customTransformation())
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitConverter/MeasurementUnitConverterController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitConverter/MeasurementUnitConverterController.java
index 3e2e947..4ddb9d7 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitConverter/MeasurementUnitConverterController.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitConverter/MeasurementUnitConverterController.java
@@ -32,6 +32,7 @@
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.units.UnitProvider;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
@@ -45,27 +46,23 @@
         FlinkDataProcessorDeclarer<MeasurementUnitConverterParameters> implements ResolvesContainerProvidedOptions {
 
   private static final String CONVERT_PROPERTY = "convert-property";
-  private static final String OUTPUT_UNIT = "outputUnit";
+  private static final String OUTPUT_UNIT = "output-unit";
 
   @Override
   public DataProcessorDescription declareModel() {
-
-
-    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.measurement-unit-converter", "Measurement Unit " +
-                    "Converter",
-            "Converts a unit of measurement to another one")
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.measurement-unit-converter")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .iconUrl(TransformationFlinkConfig.getIconUrl("unit_conversion"))
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredPropertyWithUnaryMapping(PropertyRequirementsBuilder
                             .create()
                             .measurementUnitPresence()
-                            .build(), Labels.from
-                            (CONVERT_PROPERTY, "Property", "The" +
-                                    " property to convert"), PropertyScope.MEASUREMENT_PROPERTY)
+                            .build(), Labels.withId
+                            (CONVERT_PROPERTY), PropertyScope.MEASUREMENT_PROPERTY)
                     .build())
-            .requiredSingleValueSelectionFromContainer(Labels.from(OUTPUT_UNIT, "The output type unit of " +
-                    "measurement", ""), "convert-property")
+            .requiredSingleValueSelectionFromContainer(Labels.withId(OUTPUT_UNIT), "convert-property")
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
             .outputStrategy(OutputStrategies.transform(TransformOperations
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricher.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricher.java
deleted file mode 100644
index 8bf9c0f..0000000
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricher.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.transformation.flink.processor.measurementUnitEnricher;
-
-public class MeasurementUnitEnricher {
-}
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherController.java
deleted file mode 100644
index fa4e124..0000000
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherController.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.transformation.flink.processor.measurementUnitEnricher;
-
-public class MeasurementUnitEnricherController {
-}
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherParameters.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherParameters.java
deleted file mode 100644
index a9d6e7e..0000000
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherParameters.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.transformation.flink.processor.measurementUnitEnricher;
-
-public class MeasurementUnitEnricherParameters {
-}
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherProgram.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherProgram.java
deleted file mode 100644
index efa44c9..0000000
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/measurementUnitEnricher/MeasurementUnitEnricherProgram.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2018 FZI Forschungszentrum Informatik
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.streampipes.processors.transformation.flink.processor.measurementUnitEnricher;
-
-public class MeasurementUnitEnricherProgram {
-}
diff --git a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/rename/FieldRenamerController.java b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/rename/FieldRenamerController.java
index 474fbd2..333c323 100644
--- a/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/rename/FieldRenamerController.java
+++ b/streampipes-processors-transformation-flink/src/main/java/org/streampipes/processors/transformation/flink/processor/rename/FieldRenamerController.java
@@ -20,16 +20,17 @@
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.transformation.flink.config.TransformationFlinkConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
 import org.streampipes.sdk.helpers.TransformOperations;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.flink.FlinkDataProcessorDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataProcessorRuntime;
 
@@ -40,15 +41,15 @@
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.field-renamer", "Field Renamer", "Replaces the runtime name of an event property with a custom defined name. Useful for data ingestion purposes where a specific event schema is needed.")
-            .iconUrl(TransformationFlinkConfig.getIconUrl("field_renamer"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.flink.field-renamer")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(), Labels.from
-                            (CONVERT_PROPERTY, "Property", "The" +
-                                    " property to convert"), PropertyScope.NONE)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(), Labels.withId
+                            (CONVERT_PROPERTY), PropertyScope.NONE)
                     .build())
-            .requiredTextParameter(Labels.from(FIELD_NAME, "The new field name", ""))
+            .requiredTextParameter(Labels.withId(FIELD_NAME))
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .supportedFormats(SupportedFormats.jsonFormat())
             .outputStrategy(OutputStrategies.transform(TransformOperations
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/documentation.md b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/documentation.md
new file mode 100644
index 0000000..9e00602
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/documentation.md
@@ -0,0 +1,30 @@
+## Field Converter
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Converts a string value to a number data type
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/icon.png b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/icon.png
new file mode 100644
index 0000000..c33841f
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/strings.en b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/strings.en
new file mode 100644
index 0000000..42d4faf
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-converter/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.flink.field-converter.title=Field Converter
+org.streampipes.processors.transformation.flink.field-converter.description=Converts a string value to a number data type
+
+convert-property.title=Field
+convert-property.description=The field to convert
+
+target-type.title=Datatype
+target-type.description=The target datatype
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-mapper/documentation.md b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-mapper/documentation.md
new file mode 100644
index 0000000..c8a7db4
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-mapper/documentation.md
@@ -0,0 +1,30 @@
+## Field Mapper
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Replaces one or more field with a new field and computes a hash value of these fields
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-mapper/strings.en b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-mapper/strings.en
new file mode 100644
index 0000000..b4c07ab
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-mapper/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.flink.field-mapper.title=Field Mapper
+org.streampipes.processors.transformation.flink.field-mapper.description=Replaces one or more field with a new field and computes a hash value of these fields
+
+replaceProperties.title=Fields
+replaceProperties.description=The fields to replace
+
+fieldName.title=New Field Name
+fieldName.description=The name of the new field
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/documentation.md b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/documentation.md
new file mode 100644
index 0000000..fc40c8d
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/documentation.md
@@ -0,0 +1,30 @@
+## Field Renamer
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Replaces the runtime name of an event property with a custom defined name. Useful for data ingestion purposes where a specific event schema is needed.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/icon.png b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/icon.png
new file mode 100644
index 0000000..12593b5
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/strings.en b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/strings.en
new file mode 100644
index 0000000..1dd1ad8
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.field-renamer/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.flink.field-renamer.title=Field Renamer
+org.streampipes.processors.transformation.flink.field-renamer.description=Replaces the runtime name of an event property with a custom defined name.
+
+convert-property.title=Field
+convert-property.description=The field to rename
+
+field-name.title=The new field name
+field-name.description=
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/documentation.md b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/documentation.md
new file mode 100644
index 0000000..5fff1af
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/documentation.md
@@ -0,0 +1,30 @@
+## Field Hasher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+The Field Hasher uses an algorithm to encode values in a field. The Field Hasher can use MD5, SHA1 or SHA2 to hash field values.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/icon.png b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/icon.png
new file mode 100644
index 0000000..f9fa3a2
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/strings.en b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/strings.en
new file mode 100644
index 0000000..b441404
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.fieldhasher/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.flink.fieldhasher.title=Field Hasher
+org.streampipes.processors.transformation.flink.fieldhasher.description=Hashes the value of a field using various hash functions.
+
+property-mapping.title=Field
+property-mapping.description=The field the hash function should be applied on
+
+hash-algorithm.title=Hash Algorithm
+hash-algorithm.description=The hash algorithm that should be used.
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/documentation.md b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/documentation.md
new file mode 100644
index 0000000..a7f9bde
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/documentation.md
@@ -0,0 +1,30 @@
+## Measurement Unit Converter
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Converts a unit of measurement to another one
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/icon.png b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/icon.png
new file mode 100644
index 0000000..ebe9f3a
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/strings.en b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/strings.en
new file mode 100644
index 0000000..1937949
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.measurement-unit-converter/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.flink.measurement-unit-converter.title=Measurement Unit Converter
+org.streampipes.processors.transformation.flink.measurement-unit-converter.description=Converts a unit of measurement to another one
+
+convert-property.title=Field
+convert-property.description=The field to convert
+
+output-unit.title=Output Unit
+output-unit.description=The output type unit of measurement
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/documentation.md b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/documentation.md
new file mode 100644
index 0000000..ecbb4af
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/documentation.md
@@ -0,0 +1,30 @@
+## Boilerplate Removal
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Removes boilerplate and extract fulltext from HTML
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/icon.png b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/icon.png
new file mode 100644
index 0000000..bdeef5d
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/strings.en b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/strings.en
new file mode 100644
index 0000000..f54ddd0
--- /dev/null
+++ b/streampipes-processors-transformation-flink/src/main/resources/org.streampipes.processors.transformation.flink.processor.boilerplate/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.transformation.flink.processor.boilerplate.title=Boilerplate Removal
+org.streampipes.processors.transformation.flink.processor.boilerplate.description=Removes boilerplate and extract fulltext from HTML
+
+stringProperty.title=HTML Field
+stringProperty.description=The field containing the HTML
+
+extractor.title=Extractor
+extractor.description=Common use: Article Extractor
+
+outputMode.title=Output Mode
+outputMode.description=
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/pom.xml b/streampipes-processors-transformation-jvm/pom.xml
index d4c6b43..f760c23 100644
--- a/streampipes-processors-transformation-jvm/pom.xml
+++ b/streampipes-processors-transformation-jvm/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/TransformationJvmInit.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/TransformationJvmInit.java
index 74611f5..bccf371 100644
--- a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/TransformationJvmInit.java
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/TransformationJvmInit.java
@@ -25,6 +25,9 @@
 import org.streampipes.processors.transformation.jvm.config.TransformationJvmConfig;
 import org.streampipes.processors.transformation.jvm.processor.array.count.CountArrayController;
 import org.streampipes.processors.transformation.jvm.processor.array.split.SplitArrayController;
+import org.streampipes.processors.transformation.jvm.processor.value.change.ChangedValueDetectionController;
+import org.streampipes.processors.transformation.jvm.processor.value.duration.CalculateDurationController;
+import org.streampipes.processors.transformation.jvm.processor.timestampextractor.TimestampExtractorController;
 
 public class TransformationJvmInit extends StandaloneModelSubmitter {
 
@@ -32,7 +35,10 @@
     DeclarersSingleton
             .getInstance()
             .add(new CountArrayController())
-            .add(new SplitArrayController());
+            .add(new SplitArrayController())
+            .add(new CalculateDurationController())
+            .add(new ChangedValueDetectionController())
+            .add(new TimestampExtractorController());
 
     DeclarersSingleton.getInstance().registerDataFormat(new JsonDataFormatFactory());
     DeclarersSingleton.getInstance().registerProtocol(new SpKafkaProtocolFactory());
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/count/CountArrayController.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/count/CountArrayController.java
index 16f7a7c..1f7df9b 100644
--- a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/count/CountArrayController.java
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/count/CountArrayController.java
@@ -20,50 +20,49 @@
 import org.streampipes.model.graph.DataProcessorDescription;
 import org.streampipes.model.graph.DataProcessorInvocation;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.transformation.jvm.config.TransformationJvmConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpProperties;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.vocabulary.SO;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
 public class CountArrayController extends StandaloneEventProcessingDeclarer<CountArrayParameters> {
 
-    public final static String COUNT_NAME = "countValue";
-    public final static String ARRAY_FIELD = "array_field";
+  public final static String COUNT_NAME = "countValue";
+  public final static String ARRAY_FIELD = "array-field";
 
-    @Override
-    public DataProcessorDescription declareModel() {
-        return ProcessingElementBuilder.create("org.streampipes.processors" +
-                ".transformation.jvm.count-array", "Count Array", "This processor takes " +
-                "an array of event properties counts them and appends the result to the event")
-                .iconUrl(TransformationJvmConfig.getIconUrl( "countarray"))
-                .requiredStream(
-                        StreamRequirementsBuilder.create()
-                                            .requiredPropertyWithUnaryMapping(EpRequirements.listRequirement(),
-                    Labels.from(ARRAY_FIELD, "Array of Events", "Contains an array with events"),
-                    PropertyScope.NONE)
-                                .build())
-                .outputStrategy(OutputStrategies.append(EpProperties.doubleEp(Labels.empty(), COUNT_NAME,
-                        SO.Number)))
-                .supportedFormats(SupportedFormats.jsonFormat())
-                .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-                .build();
-    }
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.jvm.count-array")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .requiredStream(
+                    StreamRequirementsBuilder.create()
+                            .requiredPropertyWithUnaryMapping(EpRequirements.listRequirement(),
+                                    Labels.withId(ARRAY_FIELD), PropertyScope.NONE)
+                            .build())
+            .outputStrategy(OutputStrategies.append(EpProperties.doubleEp(Labels.empty(), COUNT_NAME,
+                    SO.Number)))
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .build();
+  }
 
-    @Override
-    public ConfiguredEventProcessor<CountArrayParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
-        String arrayField = extractor.mappingPropertyValue(ARRAY_FIELD);
+  @Override
+  public ConfiguredEventProcessor<CountArrayParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+    String arrayField = extractor.mappingPropertyValue(ARRAY_FIELD);
 
-        CountArrayParameters params = new CountArrayParameters(graph, arrayField);
-        return new ConfiguredEventProcessor<>(params, CountArray::new);
-    }
+    CountArrayParameters params = new CountArrayParameters(graph, arrayField);
+    return new ConfiguredEventProcessor<>(params, CountArray::new);
+  }
 
 }
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArray.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArray.java
index 78cc343..93cf725 100644
--- a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArray.java
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArray.java
@@ -20,7 +20,9 @@
 import org.streampipes.logging.api.Logger;
 import org.streampipes.model.runtime.Event;
 import org.streampipes.model.runtime.field.AbstractField;
+import org.streampipes.model.runtime.field.ListField;
 import org.streampipes.model.runtime.field.NestedField;
+import org.streampipes.model.runtime.field.PrimitiveField;
 import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
 import org.streampipes.wrapper.routing.SpOutputCollector;
 import org.streampipes.wrapper.runtime.EventProcessor;
@@ -46,14 +48,27 @@
     String arrayField = splitArrayParameters.getArrayField();
     List<String> keepProperties = splitArrayParameters.getKeepProperties();
 
-    List<NestedField> allEvents = inputEvent.getFieldBySelector(arrayField).getAsList()
-            .parseAsCustomType(o -> (NestedField) o);
+    List<AbstractField> allEvents = inputEvent.getFieldBySelector(arrayField).getAsList()
+            .parseAsCustomType(o -> {
+              if (o instanceof NestedField){
+                return (NestedField) o;
+              } else if (o instanceof ListField) {
+                return (ListField) o;
+              } else {
+                return (PrimitiveField) o;
+              }
+            });
 
-    for (NestedField field : allEvents) {
+    for (AbstractField field : allEvents) {
       Event outEvent = new Event();
-      for (Map.Entry<String, AbstractField> key : field.getRawValue().entrySet()) {
-        outEvent.addField(key.getValue());
+      if (field instanceof NestedField) {
+        for (Map.Entry<String, AbstractField> key : ((NestedField) field).getRawValue().entrySet()) {
+          outEvent.addField(key.getValue());
+        }
+      } else {
+        outEvent.addField("value", field);
       }
+
       for (String propertyName : keepProperties) {
         outEvent.addField(inputEvent.getFieldBySelector(propertyName));
       }
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArrayController.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArrayController.java
index 9e85d14..645a0b6 100644
--- a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArrayController.java
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/array/split/SplitArrayController.java
@@ -24,15 +24,16 @@
 import org.streampipes.model.schema.EventProperty;
 import org.streampipes.model.schema.EventSchema;
 import org.streampipes.model.schema.PropertyScope;
-import org.streampipes.processors.transformation.jvm.config.TransformationJvmConfig;
 import org.streampipes.sdk.builder.ProcessingElementBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OutputStrategies;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
 
@@ -43,21 +44,19 @@
         implements ResolvesContainerProvidedOutputStrategy<DataProcessorInvocation, ProcessingElementParameterExtractor> {
 
   public static final String KEEP_PROPERTIES_ID = "keep";
-  public static final String ARRAY_FIELD_ID = "array_field";
+  public static final String ARRAY_FIELD_ID = "array-field";
 
   @Override
   public DataProcessorDescription declareModel() {
-    return ProcessingElementBuilder.create("org.streampipes.processors" +
-            ".transformation.jvm.split-array", "Split Array", "This processor takes " +
-            "an array of event properties and creates an event for each of them. Further property of the events can be added to each element")
-            .iconUrl(TransformationJvmConfig.getIconUrl("splitarray"))
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.jvm.split-array")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder.create()
                     .requiredPropertyWithNaryMapping(EpRequirements.anyProperty(),
-                            Labels.from(KEEP_PROPERTIES_ID, "Keep Properties", "The " +
-                                    "properties that should be added to the events of array"),
+                            Labels.withId(KEEP_PROPERTIES_ID),
                             PropertyScope.NONE)
                     .requiredPropertyWithUnaryMapping(EpRequirements.listRequirement(),
-                            Labels.from(ARRAY_FIELD_ID, "Array of Events", "Contains an array with events"),
+                            Labels.withId(ARRAY_FIELD_ID),
                             PropertyScope.NONE)
                     .build())
             .outputStrategy(OutputStrategies.customTransformation())
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/OutputFields.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/OutputFields.java
new file mode 100644
index 0000000..c8ff5fc
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/OutputFields.java
@@ -0,0 +1,44 @@
+/*
+Copyright 2019 FZI Forschungszentrum Informatik
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.streampipes.processors.transformation.jvm.processor.timestampextractor;
+
+public enum OutputFields {
+
+    YEAR("Year"),
+    MONTH("Month"),
+    DAY("Day"),
+    HOUR("Hour"),
+    MINUTE("Minute"),
+    SECOND("Second"),
+    WEEKDAY("Weekday (e.g 'Monday')"),
+    ;
+
+    private final String value;
+
+    private OutputFields(String value) {
+        this.value = value;
+    }
+
+    public String getField() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return value;
+    }
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractor.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractor.java
new file mode 100644
index 0000000..4b4ab44
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractor.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.timestampextractor;
+
+import org.streampipes.logging.api.Logger;
+import org.streampipes.model.runtime.Event;
+import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
+import org.streampipes.wrapper.routing.SpOutputCollector;
+import org.streampipes.wrapper.runtime.EventProcessor;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+public class TimestampExtractor implements EventProcessor<TimestampExtractorParameters> {
+
+    private static Logger LOG;
+
+    private String timestampField;
+    private List<String> outputFields;
+
+    @Override
+    public void onInvocation(TimestampExtractorParameters params, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext runtimeContext) {
+        LOG = params.getGraph().getLogger(TimestampExtractor.class);
+
+        this.timestampField = params.getTimestampField();
+        this.outputFields = params.getOutputFields();
+    }
+
+    @Override
+    public void onEvent(Event event, SpOutputCollector out) {
+        Long timestamp = event.getFieldBySelector(timestampField).getAsPrimitive().getAsLong();
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date(timestamp));
+
+        for (String field : outputFields) {
+            if(field.equals(OutputFields.YEAR.toString())) {
+                event.addField("timestampYear", calendar.get(Calendar.YEAR));
+            }
+            if(field.equals(OutputFields.MONTH.toString())) {
+                event.addField("timestampMonth", calendar.get(Calendar.MONTH) + 1);
+            }
+            if(field.equals(OutputFields.DAY.toString())) {
+                event.addField("timestampDay", calendar.get(Calendar.DAY_OF_MONTH));
+            }
+            if(field.equals(OutputFields.HOUR.toString())) {
+                event.addField("timestampHour", calendar.get(Calendar.HOUR_OF_DAY));
+            }
+            if(field.equals(OutputFields.MINUTE.toString())) {
+                event.addField("timestampMinute", calendar.get(Calendar.MINUTE));
+            }
+            if(field.equals(OutputFields.SECOND.toString())) {
+                event.addField("timestampSecond", calendar.get(Calendar.SECOND));
+            }
+            if(field.equals(OutputFields.WEEKDAY.toString())) {
+                int day =  calendar.get(Calendar.DAY_OF_WEEK);
+                String dayString = "";
+                switch (day) {
+                    case Calendar.MONDAY: dayString = "Monday";
+                        break;
+                    case Calendar.TUESDAY: dayString = "Tuesday";
+                        break;
+                    case Calendar.WEDNESDAY: dayString = "Wednesday";
+                        break;
+                    case Calendar.THURSDAY: dayString = "Thursday";
+                        break;
+                    case Calendar.FRIDAY: dayString = "Friday";
+                        break;
+                    case Calendar.SATURDAY: dayString = "Saturday";
+                        break;
+                    case Calendar.SUNDAY: dayString = "Sunday";
+                        break;
+                }
+                event.addField("timestampWeekday", dayString);
+            }
+        }
+
+        out.collect(event);
+    }
+
+
+    @Override
+    public void onDetach() {
+    }
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractorController.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractorController.java
new file mode 100644
index 0000000..9724465
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractorController.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.timestampextractor;
+
+import org.streampipes.commons.exceptions.SpRuntimeException;
+import org.streampipes.container.api.ResolvesContainerProvidedOutputStrategy;
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.model.schema.EventSchema;
+import org.streampipes.model.schema.PropertyScope;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.EpProperties;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.vocabulary.SO;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+import java.util.List;
+
+public class TimestampExtractorController extends StandaloneEventProcessingDeclarer<TimestampExtractorParameters>
+        implements ResolvesContainerProvidedOutputStrategy<DataProcessorInvocation, ProcessingElementParameterExtractor> {
+
+  public final static String TIMESTAMP_FIELD = "timestampField";
+  public final static String SELECTED_OUTPUT_FIELDS = "selectedOutputFields";
+
+
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.jvm.processor.timestampextractor")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
+            .requiredStream(
+                    StreamRequirementsBuilder.create()
+                            .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(),
+                                    Labels.withId(TIMESTAMP_FIELD), PropertyScope.NONE)
+                            .build())
+            .requiredMultiValueSelection(Labels.withId(SELECTED_OUTPUT_FIELDS),
+                    Options.from(OutputFields.YEAR.toString(), OutputFields.MONTH.toString(), OutputFields.DAY.toString(), OutputFields.HOUR.toString(),
+                            OutputFields.MINUTE.toString(), OutputFields.SECOND.toString(), OutputFields.WEEKDAY.toString()))
+            .outputStrategy(OutputStrategies.customTransformation())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<TimestampExtractorParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+    String timestampField = extractor.mappingPropertyValue(TIMESTAMP_FIELD);
+    List<String> selectedMultiValue = extractor.selectedMultiValues(SELECTED_OUTPUT_FIELDS, String.class);
+
+    TimestampExtractorParameters params = new TimestampExtractorParameters(graph, timestampField, selectedMultiValue);
+    return new ConfiguredEventProcessor<>(params, TimestampExtractor::new);
+  }
+
+  @Override
+  public EventSchema resolveOutputStrategy(DataProcessorInvocation processingElement, ProcessingElementParameterExtractor extractor) throws SpRuntimeException {
+    EventSchema eventSchema = processingElement.getInputStreams().get(0).getEventSchema();
+
+    List<String> selectedOutputField = extractor.selectedMultiValues(SELECTED_OUTPUT_FIELDS, String.class);
+
+    for (String field : selectedOutputField) {
+      if (field.equals(OutputFields.YEAR.toString())) {
+        eventSchema.addEventProperty(EpProperties.numberEp(Labels.from("timestampYear", "Timestamp Year", ""), "timestampYear", SO.Number));
+      }
+      if (field.equals(OutputFields.MONTH.toString())) {
+        eventSchema.addEventProperty(EpProperties.numberEp(Labels.from("timestampMonth", "Timestamp Month", ""), "timestampMonth", SO.Number));
+      }
+      if (field.equals(OutputFields.DAY.toString())) {
+        eventSchema.addEventProperty(EpProperties.numberEp(Labels.from("timestampDay", "Timestamp Day", ""), "timestampDay", SO.Number));
+      }
+      if (field.equals(OutputFields.HOUR.toString())) {
+        eventSchema.addEventProperty(EpProperties.numberEp(Labels.from("timestampHour", "Timestamp Hour", ""), "timestampHour", SO.Number));
+      }
+      if (field.equals(OutputFields.MINUTE.toString())) {
+        eventSchema.addEventProperty(EpProperties.numberEp(Labels.from("timestampMinute", "Timestamp Minute", ""), "timestampMinute", SO.Number));
+      }
+      if (field.equals(OutputFields.SECOND.toString())) {
+        eventSchema.addEventProperty(EpProperties.numberEp(Labels.from("timestampSecond", "Timestamp Second", ""), "timestampSecond", SO.Number));
+      }
+      if (field.equals(OutputFields.WEEKDAY.toString())) {
+        eventSchema.addEventProperty(EpProperties.stringEp(Labels.from("timestampWeekday", "Timestamp Weekday", ""), "timestampWeekday", SO.Text));
+      }
+    }
+
+
+    return eventSchema;
+  }
+
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractorParameters.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractorParameters.java
new file mode 100644
index 0000000..1e5d9fd
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/timestampextractor/TimestampExtractorParameters.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.timestampextractor;
+
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
+
+import java.util.List;
+
+public class TimestampExtractorParameters extends EventProcessorBindingParams {
+
+    private String timestampField;
+    private List<String> outputFields;
+
+
+    public TimestampExtractorParameters(DataProcessorInvocation graph, String timestampField, List<String> outputFields) {
+        super(graph);
+        this.timestampField = timestampField;
+        this.outputFields = outputFields;
+    }
+
+    public String getTimestampField() {
+        return timestampField;
+    }
+
+    public List<String> getOutputFields() {
+        return outputFields;
+    }
+}
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetection.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetection.java
new file mode 100644
index 0000000..968d349
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetection.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.value.change;
+
+import org.streampipes.logging.api.Logger;
+import org.streampipes.model.runtime.Event;
+import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
+import org.streampipes.wrapper.routing.SpOutputCollector;
+import org.streampipes.wrapper.runtime.EventProcessor;
+
+public class ChangedValueDetection implements EventProcessor<ChangedValueDetectionParameters> {
+
+  private static Logger LOG;
+
+  private String compareParameter;
+  private String changeFieldName;
+  private Object lastObject = null;
+
+  @Override
+  public void onInvocation(ChangedValueDetectionParameters changedValueDetectionParameters,
+                            SpOutputCollector spOutputCollector,
+                            EventProcessorRuntimeContext runtimeContext) {
+    LOG = changedValueDetectionParameters.getGraph().getLogger(ChangedValueDetection.class);
+    this.compareParameter = changedValueDetectionParameters.getCompareField();
+    this.changeFieldName = changedValueDetectionParameters.getChangeFieldName();
+  }
+
+  @Override
+  public void onEvent(Event inputEvent, SpOutputCollector out) {
+    Object newObject = inputEvent.getFieldBySelector(compareParameter).getRawValue();
+
+    if (newObject != null) {
+      if (!newObject.equals(lastObject)) {
+        lastObject = newObject;
+        //TODO: Better handling of multiple timestamps (if the field "change_detected" is already in the input)?
+        inputEvent.addField(changeFieldName, System.currentTimeMillis());
+        out.collect(inputEvent);
+      }
+    }
+  }
+
+  @Override
+  public void onDetach() {
+  }
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetectionController.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetectionController.java
new file mode 100644
index 0000000..466500b
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetectionController.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.value.change;
+
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.model.schema.PropertyScope;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.EpProperties;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+public class ChangedValueDetectionController extends StandaloneEventProcessingDeclarer<ChangedValueDetectionParameters> {
+
+  public static final String COMPARE_FIELD_ID = "compare";
+  public static final String CHANGE_FIELD_NAME = "change_detected";
+
+  //TODO: Change Icon
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.jvm.changed-value")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
+            .requiredStream(StreamRequirementsBuilder.create()
+                    .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(),
+                            Labels.withId(COMPARE_FIELD_ID),
+                            PropertyScope.NONE)
+                    .build())
+            .outputStrategy(OutputStrategies.append(EpProperties.timestampProperty(CHANGE_FIELD_NAME)))
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<ChangedValueDetectionParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+
+    String compare = extractor.mappingPropertyValue(COMPARE_FIELD_ID);
+
+    ChangedValueDetectionParameters params = new ChangedValueDetectionParameters(graph, compare, CHANGE_FIELD_NAME);
+    return new ConfiguredEventProcessor<>(params, ChangedValueDetection::new);
+  }
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetectionParameters.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetectionParameters.java
new file mode 100644
index 0000000..fa3b8a0
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/change/ChangedValueDetectionParameters.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.value.change;
+
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
+
+public class ChangedValueDetectionParameters extends EventProcessorBindingParams {
+    private String compareField;
+    private String changeFieldName;
+
+    public ChangedValueDetectionParameters(DataProcessorInvocation graph, String compareField, String changeFieldName) {
+        super(graph);
+        this.compareField = compareField;
+        this.changeFieldName = changeFieldName;
+    }
+
+    public String getCompareField() {
+        return compareField;
+    }
+
+    public String getChangeFieldName() {
+        return changeFieldName;
+    }
+}
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDuration.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDuration.java
new file mode 100644
index 0000000..bc750f9
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDuration.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.value.duration;
+
+import org.streampipes.logging.api.Logger;
+import org.streampipes.model.runtime.Event;
+import org.streampipes.wrapper.context.EventProcessorRuntimeContext;
+import org.streampipes.wrapper.routing.SpOutputCollector;
+import org.streampipes.wrapper.runtime.EventProcessor;
+
+public class CalculateDuration implements EventProcessor<CalculateDurationParameters> {
+
+  private static Logger LOG;
+
+  private String startTs;
+  private String endTs;
+  private String unit;
+  private String durationName;
+
+  @Override
+  public void onInvocation(CalculateDurationParameters calculateDurationParameters,
+                            SpOutputCollector spOutputCollector,
+                            EventProcessorRuntimeContext runtimeContext) {
+    LOG = calculateDurationParameters.getGraph().getLogger(
+        CalculateDuration.class);
+
+    this.startTs = calculateDurationParameters.getStartTs();
+    this.endTs= calculateDurationParameters.getEndTs();
+    this.unit = calculateDurationParameters.getUnit();
+    this.durationName = calculateDurationParameters.getDurationName();
+  }
+
+  @Override
+  public void onEvent(Event inputEvent, SpOutputCollector out) {
+    Long start = inputEvent.getFieldBySelector(startTs).getAsPrimitive().getAsLong();
+    Long end = inputEvent.getFieldBySelector(endTs).getAsPrimitive().getAsLong();
+    Long duration = end - start;
+
+    if (unit.equals(CalculateDurationController.MS)) {
+      inputEvent.addField(durationName, duration);
+    } else if (unit.equals(CalculateDurationController.SECONDS)) {
+      inputEvent.addField(durationName, (duration + 500) / 1000);
+    } else if (unit.equals(CalculateDurationController.MINUTES)) {
+      inputEvent.addField(durationName, (duration + 30000) / 60000);
+    } else {
+      // Hours
+      inputEvent.addField(durationName, (duration + 1800000) / 3600000);
+    }
+    out.collect(inputEvent);
+  }
+
+  @Override
+  public void onDetach() {
+  }
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDurationController.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDurationController.java
new file mode 100644
index 0000000..1a773eb
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDurationController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.value.duration;
+
+import org.streampipes.model.graph.DataProcessorDescription;
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.model.schema.PropertyScope;
+import org.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.ProcessingElementParameterExtractor;
+import org.streampipes.sdk.helpers.EpProperties;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.OutputStrategies;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.vocabulary.SO;
+import org.streampipes.wrapper.standalone.ConfiguredEventProcessor;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventProcessingDeclarer;
+
+public class CalculateDurationController extends StandaloneEventProcessingDeclarer<CalculateDurationParameters> {
+
+  public static final String START_TS_FIELD_ID = "start-ts";
+  public static final String END_TS_FIELD_ID = "end-ts";
+  public static final String DURATION_FIELD_NAME = "duration";
+  public static final String UNIT_FIELD_ID = "unit-field"; // hours,
+
+  public static final String MS = "Milliseconds";
+  public static final String SECONDS = "Seconds";
+  public static final String MINUTES = "Minutes";
+  public static final String HOURS = "Hours";
+
+
+  //TODO: Change Icon
+  @Override
+  public DataProcessorDescription declareModel() {
+    return ProcessingElementBuilder.create("org.streampipes.processors.transformation.jvm.duration-value")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
+            .requiredStream(StreamRequirementsBuilder.create()
+                    .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(),
+                            Labels.withId(START_TS_FIELD_ID),
+                            PropertyScope.NONE)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(),
+                            Labels.withId(END_TS_FIELD_ID),
+                            PropertyScope.NONE)
+                    .build())
+            .requiredSingleValueSelection(Labels.withId(UNIT_FIELD_ID),
+                    Options.from(MS, SECONDS, MINUTES, HOURS))
+            .outputStrategy(OutputStrategies.append(EpProperties.doubleEp(Labels.empty(), DURATION_FIELD_NAME,
+                    SO.Number)))
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventProcessor<CalculateDurationParameters> onInvocation(DataProcessorInvocation graph, ProcessingElementParameterExtractor extractor) {
+
+    String startTs = extractor.mappingPropertyValue(START_TS_FIELD_ID);
+    String endTs = extractor.mappingPropertyValue(END_TS_FIELD_ID);
+    String unit = extractor.selectedSingleValue(UNIT_FIELD_ID, String.class);
+
+    CalculateDurationParameters params = new CalculateDurationParameters(graph, startTs, endTs, unit, DURATION_FIELD_NAME);
+    return new ConfiguredEventProcessor<>(params, CalculateDuration::new);
+  }
+}
diff --git a/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDurationParameters.java b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDurationParameters.java
new file mode 100644
index 0000000..f15bdf4
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/java/org/streampipes/processors/transformation/jvm/processor/value/duration/CalculateDurationParameters.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.streampipes.processors.transformation.jvm.processor.value.duration;
+
+import org.streampipes.model.graph.DataProcessorInvocation;
+import org.streampipes.wrapper.params.binding.EventProcessorBindingParams;
+
+public class CalculateDurationParameters extends EventProcessorBindingParams {
+    private String startTs;
+    private String endTs;
+    private String unit;
+    private String durationName;
+
+    public CalculateDurationParameters(DataProcessorInvocation graph,
+        String startTs,
+        String endTs,
+        String unit,
+        String durationName) {
+        super(graph);
+        this.startTs = startTs;
+        this.endTs = endTs;
+        this.unit = unit;
+        this.durationName = durationName;
+    }
+
+    public String getStartTs() {
+        return startTs;
+    }
+
+    public String getEndTs() {
+        return endTs;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public String getDurationName() {
+        return durationName;
+    }
+}
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.changed-value/documentation.md b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.changed-value/documentation.md
new file mode 100644
index 0000000..3ea6956
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.changed-value/documentation.md
@@ -0,0 +1,29 @@
+## Value Changed
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This processor sends out an event everytime a specific object changes. It also adds a timestamp in ms from the system time.
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.changed-value/strings.en b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.changed-value/strings.en
new file mode 100644
index 0000000..a21f864
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.changed-value/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.processors.transformation.jvm.changed-value.title=Value Changed
+org.streampipes.processors.transformation.jvm.changed-value.description=Outpus an event every time a specific field changes.
+
+compare.title=Keep Fields
+compare.description=The field which might change over time
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/documentation.md b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/documentation.md
new file mode 100644
index 0000000..3ca9d1b
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/documentation.md
@@ -0,0 +1,31 @@
+## Count Array
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This processor takes a list field, computes the size of the list and appends the result to the event.
+
+***
+
+## Required input
+
+This processor works with any event that has a field of type ``list``.
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### List Field
+
+The field containing the list that should be used.
+
+## Output
+
+Outputs the incoming event while appending the list size (named ``countValue``) to the incoming event.
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/icon.png b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/icon.png
new file mode 100644
index 0000000..be48510
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/strings.en b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/strings.en
new file mode 100644
index 0000000..edf798a
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.count-array/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.processors.transformation.jvm.count-array.title=Count Array
+org.streampipes.processors.transformation.jvm.count-array.description=Counts the size of list items.
+
+array-field.title=List Field
+array-field.description=Contains a list of fields.
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.duration-value/documentation.md b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.duration-value/documentation.md
new file mode 100644
index 0000000..3f065af
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.duration-value/documentation.md
@@ -0,0 +1,30 @@
+## Calculate Duration
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This processor calculates the duration for a given stream with a start timestamp and an end timestamp.
+Add a detailed description here
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### 1st parameter
+
+
+### 2nd parameter
+
+## Output
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.duration-value/strings.en b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.duration-value/strings.en
new file mode 100644
index 0000000..2b1f59c
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.duration-value/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.processors.transformation.jvm.duration-value.title=Calculate Duration
+org.streampipes.processors.transformation.jvm.duration-value.description=Calculates the time between two timestamps.
+
+start-ts.title=Start Timestamp
+start-ts.description=The timestamp of the start event
+
+end-ts.title=End Timestamp
+end-ts.description=The timestamp of the end event
+
+unit-field.title=Time Unit
+unit-field.description=
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.processor.timestampextractor/documentation.md b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.processor.timestampextractor/documentation.md
new file mode 100644
index 0000000..efbd044
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.processor.timestampextractor/documentation.md
@@ -0,0 +1,34 @@
+## Timestamp Extractor
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This processor extracts a timestamp into the individual time fields (e.g. day field, hour field, ....)
+
+***
+
+## Required input
+
+This processor requires an event that provides a timestamp value (a field that is marked to be of type ``http://schema
+.org/DateTime``.
+
+***
+
+## Configuration
+
+### Timestamp Field
+
+The field of the event containing the timestamp to parse.
+
+### Extract Fields
+
+Select the individual parts of the timestamp that should be extracted, e.g., Year, Minute and Day.
+
+## Output
+
+The output of this processor is a new event that contains the fields selected by the ``Extract Fields`` parameter.
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.processor.timestampextractor/strings.en b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.processor.timestampextractor/strings.en
new file mode 100644
index 0000000..4fb38fd
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.processor.timestampextractor/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.jvm.processor.timestampextractor.title=Timestamp Extractor
+org.streampipes.processors.transformation.jvm.processor.timestampextractor.description=Extracts a timestamp into its individual time fields.
+
+timestampField.title=Timestamp Field
+timestampField.description=
+
+selectedOutputFields.title=Extract Fields
+selectedOutputFields.description=
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/documentation.md b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/documentation.md
new file mode 100644
index 0000000..ed203f1
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/documentation.md
@@ -0,0 +1,36 @@
+## Split Array
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This processor takes an array of event properties and creates an event for each of them. Further property of the events can be added to each element
+Add a detailed description here
+
+***
+
+## Required input
+
+This processor works with any event that has a field of type ``list``.
+
+***
+
+## Configuration
+
+### Keep Fields
+
+Fields of the event that should be kept in each resulting event.
+
+### List field
+
+The name of the field that contains the list values that should be split.
+
+
+## Output
+
+This data processor produces an event with all fields selected by the ``Keep Fields`` parameter and all fields of the
+ selected list field.
\ No newline at end of file
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/icon.png b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/icon.png
new file mode 100644
index 0000000..0d22dfd
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/icon.png
Binary files differ
diff --git a/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/strings.en b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/strings.en
new file mode 100644
index 0000000..0360e0d
--- /dev/null
+++ b/streampipes-processors-transformation-jvm/src/main/resources/org.streampipes.processors.transformation.jvm.split-array/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.processors.transformation.jvm.split-array.title=Split Array
+org.streampipes.processors.transformation.jvm.split-array.description=Outputs an event for each entry of a list.
+
+keep.title=Keep fields
+keep.description=The fields that should be added to the events of array
+
+array-field.title=List Field
+array-field.description=Contains an array with events
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/pom.xml b/streampipes-sinks-brokers-jvm/pom.xml
index 9b396e0..15fc6cd 100644
--- a/streampipes-sinks-brokers-jvm/pom.xml
+++ b/streampipes-sinks-brokers-jvm/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/BrokersJvmInit.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/BrokersJvmInit.java
index b354fbd..adcbe78 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/BrokersJvmInit.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/BrokersJvmInit.java
@@ -25,6 +25,7 @@
 import org.streampipes.sinks.brokers.jvm.jms.JmsController;
 import org.streampipes.sinks.brokers.jvm.kafka.KafkaController;
 import org.streampipes.sinks.brokers.jvm.rabbitmq.RabbitMqController;
+import org.streampipes.sinks.brokers.jvm.rest.RestController;
 
 public class BrokersJvmInit extends StandaloneModelSubmitter {
 
@@ -33,7 +34,7 @@
             .getInstance()
             .add(new KafkaController())
             .add(new JmsController())
-            //.add(new RestController())
+            .add(new RestController())
             .add(new RabbitMqController());
 
     DeclarersSingleton.getInstance().registerDataFormat(new JsonDataFormatFactory());
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsController.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsController.java
index 42529ca..f4e9bf6 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsController.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsController.java
@@ -25,10 +25,11 @@
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OntologyProperties;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
-import org.streampipes.sinks.brokers.jvm.config.BrokersJvmConfig;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
@@ -42,16 +43,15 @@
 
   @Override
   public DataSinkDescription declareModel() {
-    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.jms", "JMS Publisher", "Publishes events to a JMS topic")
-            .iconUrl(BrokersJvmConfig.getIconUrl("jms_logo"))
+    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.jms")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
-            .requiredTextParameter(Labels.from(TOPIC_KEY, "JMS Topic", "Select a JMS " +
-                    "topic"), false, false)
-            .requiredOntologyConcept(Labels.from(JMS_BROKER_SETTINGS_KEY, "JMS Broker Settings", "Provide" +
-                            " settings of the JMS broker to connect with."),
+            .requiredTextParameter(Labels.withId(TOPIC_KEY), false, false)
+            .requiredOntologyConcept(Labels.withId(JMS_BROKER_SETTINGS_KEY),
                     OntologyProperties.mandatory(JMS_HOST_URI),
                     OntologyProperties.mandatory(JMS_PORT_URI))
             .supportedFormats(SupportedFormats.jsonFormat())
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsPublisher.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsPublisher.java
index e0f6bb2..a294177 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsPublisher.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/jms/JmsPublisher.java
@@ -38,6 +38,12 @@
   @Override
   public void onInvocation(JmsParameters params, EventSinkRuntimeContext runtimeContext) throws SpRuntimeException {
     this.publisher = new ActiveMQPublisher(params.getJmsHost() + ":" + params.getJmsPort(), params.getTopic());
+    if (!this.publisher.isConnected()) {
+      throw new SpRuntimeException("Could not connect to JMS server " + params.getJmsHost() + " on Port: " + params.getJmsPort() + " to topic: " + params.getTopic());
+    }
+
+
+
   }
 
   @Override
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/kafka/KafkaController.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/kafka/KafkaController.java
index b9371a4..00d456b 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/kafka/KafkaController.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/kafka/KafkaController.java
@@ -18,58 +18,58 @@
 
 import org.streampipes.model.graph.DataSinkDescription;
 import org.streampipes.model.graph.DataSinkInvocation;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sinks.brokers.jvm.config.BrokersJvmConfig;
 import org.streampipes.sdk.builder.DataSinkBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.OntologyProperties;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
 public class KafkaController extends StandaloneEventSinkDeclarer<KafkaParameters> {
 
-	private static final String KAFKA_BROKER_SETTINGS_KEY = "broker-settings";
-	private static final String TOPIC_KEY = "topic";
+  private static final String KAFKA_BROKER_SETTINGS_KEY = "broker-settings";
+  private static final String TOPIC_KEY = "topic";
 
-	private static final String KAFKA_HOST_URI = "http://schema.org/kafkaHost";
-	private static final String KAFKA_PORT_URI = "http://schema.org/kafkaPort";
+  private static final String KAFKA_HOST_URI = "http://schema.org/kafkaHost";
+  private static final String KAFKA_PORT_URI = "http://schema.org/kafkaPort";
 
-	@Override
-	public DataSinkDescription declareModel() {
-		return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.kafka", "Kafka Publisher", "Forwards an event to a Kafka Broker")
-						.iconUrl(BrokersJvmConfig.getIconUrl("kafka_logo"))
-						.requiredStream(StreamRequirementsBuilder
-										.create()
-										.requiredProperty(EpRequirements.anyProperty())
-										.build())
-						.requiredTextParameter(Labels.from(TOPIC_KEY, "Kafka Topic", "Select a Kafka " +
-										"topic"), false, false)
-						.requiredOntologyConcept(Labels.from(KAFKA_BROKER_SETTINGS_KEY, "Kafka Broker Settings", "Provide" +
-														" settings of the Kafka broker to connect with."),
-										OntologyProperties.mandatory(KAFKA_HOST_URI),
-										OntologyProperties.mandatory(KAFKA_PORT_URI))
-						.supportedFormats(SupportedFormats.jsonFormat())
-						.supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-						.build();
-	}
+  @Override
+  public DataSinkDescription declareModel() {
+    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.kafka")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .requiredTextParameter(Labels.withId(TOPIC_KEY), false, false)
+            .requiredOntologyConcept(Labels.withId(KAFKA_BROKER_SETTINGS_KEY),
+                    OntologyProperties.mandatory(KAFKA_HOST_URI),
+                    OntologyProperties.mandatory(KAFKA_PORT_URI))
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .build();
+  }
 
-	@Override
-	public ConfiguredEventSink<KafkaParameters> onInvocation(DataSinkInvocation graph,
-																													 DataSinkParameterExtractor extractor) {
-		String topic = extractor.singleValueParameter(TOPIC_KEY, String.class);
+  @Override
+  public ConfiguredEventSink<KafkaParameters> onInvocation(DataSinkInvocation graph,
+                                                           DataSinkParameterExtractor extractor) {
+    String topic = extractor.singleValueParameter(TOPIC_KEY, String.class);
 
-		String kafkaHost = extractor.supportedOntologyPropertyValue(KAFKA_BROKER_SETTINGS_KEY, KAFKA_HOST_URI,
-						String.class);
-		Integer kafkaPort = extractor.supportedOntologyPropertyValue(KAFKA_BROKER_SETTINGS_KEY, KAFKA_PORT_URI,
-						Integer.class);
+    String kafkaHost = extractor.supportedOntologyPropertyValue(KAFKA_BROKER_SETTINGS_KEY, KAFKA_HOST_URI,
+            String.class);
+    Integer kafkaPort = extractor.supportedOntologyPropertyValue(KAFKA_BROKER_SETTINGS_KEY, KAFKA_PORT_URI,
+            Integer.class);
 
-		KafkaParameters params = new KafkaParameters(graph, kafkaHost, kafkaPort, topic);
+    KafkaParameters params = new KafkaParameters(graph, kafkaHost, kafkaPort, topic);
 
-		return new ConfiguredEventSink<>(params, KafkaPublisher::new);
-	}
+    return new ConfiguredEventSink<>(params, KafkaPublisher::new);
+  }
 
 }
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqConsumer.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqConsumer.java
index 261c746..3223879 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqConsumer.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqConsumer.java
@@ -30,8 +30,6 @@
 
 public class RabbitMqConsumer implements EventSink<RabbitMqParameters> {
 
-  // For testing: rabbitMQ default port is 15700 for the Axoom use case
-
   private RabbitMqPublisher publisher;
   private JsonDataFormatDefinition dataFormatDefinition;
   private String topic;
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqController.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqController.java
index 217eb46..ab7dc85 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqController.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqController.java
@@ -22,8 +22,13 @@
 import org.streampipes.sdk.builder.DataSinkBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
-import org.streampipes.sdk.helpers.*;
-import org.streampipes.sinks.brokers.jvm.config.BrokersJvmConfig;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.OntologyProperties;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
@@ -40,17 +45,15 @@
 
   @Override
   public DataSinkDescription declareModel() {
-    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.rabbitmq", "RabbitMQ Publisher", "Forwards events to a " +
-            "RabbitMQ broker")
-            .iconUrl(BrokersJvmConfig.getIconUrl("rabbitmq-icon"))
+    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.rabbitmq")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
-            .requiredTextParameter(Labels.from(TOPIC_KEY, "RabbitMQ Topic", "Select a RabbitMQ " +
-                    "topic"), false, true)
-            .requiredOntologyConcept(Labels.from(RABBITMQ_BROKER_SETTINGS_KEY, "RabbitMQ Broker Settings", "Provide" +
-                    " settings of the RabbitMQ broker to connect with."),
+            .requiredTextParameter(Labels.withId(TOPIC_KEY), false, true)
+            .requiredOntologyConcept(Labels.withId(RABBITMQ_BROKER_SETTINGS_KEY),
                     OntologyProperties.mandatory(RABBITMQ_HOST_URI),
                     OntologyProperties.mandatory(RABBITMQ_PORT_URI),
                     OntologyProperties.mandatory(RABBITMQ_USER_URI),
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqPublisher.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqPublisher.java
index 8e0695c..0fe9d7c 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqPublisher.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rabbitmq/RabbitMqPublisher.java
@@ -38,13 +38,14 @@
 
   private RabbitMqParameters params;
 
-  private static final String EXCHANGE_NAME = "Axoom.IoT";
+  private String exchangeName;
   private static final Logger LOG = LoggerFactory.getLogger(RabbitMqPublisher.class);
 
   public RabbitMqPublisher(RabbitMqParameters params) {
     try {
       this.queueMap = new HashMap<>();
       this.params = params;
+      this.exchangeName = params.getExchangeName();
       setupConnection();
       this.errorMode = false;
     } catch (IOException e) {
@@ -71,7 +72,7 @@
       setupChannel(topic);
     }
     try {
-      queueMap.get(topic).basicPublish(EXCHANGE_NAME, topic, null, event);
+      queueMap.get(topic).basicPublish(exchangeName, topic, null, event);
     } catch (IOException e) {
       e.printStackTrace();
     }
@@ -80,7 +81,7 @@
   private void setupChannel(String topic) {
     try {
       Channel channel = connection.createChannel();
-      channel.exchangeDeclare(EXCHANGE_NAME, "topic", true, false, null);
+      channel.exchangeDeclare(exchangeName, "topic", true, false, null);
 
       queueMap.put(topic, channel);
     } catch (IOException e) {
diff --git a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rest/RestController.java b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rest/RestController.java
index ec986cb..310e47d 100644
--- a/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rest/RestController.java
+++ b/streampipes-sinks-brokers-jvm/src/main/java/org/streampipes/sinks/brokers/jvm/rest/RestController.java
@@ -25,23 +25,28 @@
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
 public class RestController extends StandaloneEventSinkDeclarer<RestParameters> {
 
-  private static final String URL_KEY = "url_key";
+  private static final String URL_KEY = "url-key";
 
   @Override
   public DataSinkDescription declareModel() {
-    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.rest", "REST Publisher", "Posts events to a REST interface")
+    return DataSinkBuilder.create("org.streampipes.sinks.brokers.jvm.rest")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION)
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
-            .requiredTextParameter(Labels.from(URL_KEY, "REST URL", "URL of the REST endoint"), false, false)
+            .requiredTextParameter(Labels.withId(URL_KEY),
+                    false, false)
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .build();
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/documentation.md b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/documentation.md
new file mode 100644
index 0000000..a5cc80b
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/documentation.md
@@ -0,0 +1,36 @@
+## JMS Publisher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Publishes events to a message broker (e.g., ActiveMQ) using the Java Message Service (JMS) protocol.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+### JMS Broker Settings
+
+The basic settings to connect to the broker. 
+The JMS broker URL indicates the URL of the broker (e.g., tcp://localhost), the port indicates the port of the broker
+ (e.g., 61616)
+
+
+### JMS Topic
+
+The topic where events should be sent to.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/icon.png b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/icon.png
new file mode 100644
index 0000000..c26419d
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/icon.png
Binary files differ
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/strings.en b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/strings.en
new file mode 100644
index 0000000..3d61043
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.jms/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.sinks.brokers.jvm.jms.title=JMS Publisher
+org.streampipes.sinks.brokers.jvm.jms.description=Publishes events to a JMS topic
+
+topic.title=JMS Topic
+topic.description=Select a JMS topic
+
+broker-settings.title=JMS broker settings (use prefix tcp://)
+broker-settings.description=Provide settings of the JMS broker to connect with.
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/documentation.md b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/documentation.md
new file mode 100644
index 0000000..58278a6
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/documentation.md
@@ -0,0 +1,37 @@
+## Kafka Publisher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Publishes events to Apache Kafka.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+### Kafka Broker Settings
+
+The basic settings to connect to the broker. 
+The Kafka broker URL indicates the URL of the broker (e.g., localhost), the port indicates the port of the broker
+ (e.g., 9092)
+
+
+### Kafka Topic
+
+The topic where events should be sent to.
+
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/icon.png b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/icon.png
new file mode 100644
index 0000000..2e55952
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/icon.png
Binary files differ
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/strings.en b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/strings.en
new file mode 100644
index 0000000..fb7a3f2
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.kafka/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.sinks.brokers.jvm.kafka.title=Kafka Publisher
+org.streampipes.sinks.brokers.jvm.kafka.description=Publish events to Apache Kafka
+
+topic.title=Kafka Topic
+topic.description=Select a Kafka topic
+
+broker-settings.title=Kafka broker settings
+broker-settings.description=Provide settings of the Kafka broker to connect with.
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/documentation.md b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/documentation.md
new file mode 100644
index 0000000..1d48963
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/documentation.md
@@ -0,0 +1,50 @@
+## RabbitMQ Publisher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Forwards events to a RabbitMQ broker
+Add a detailed description here
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+### Host
+
+The hostname of the RabbitMQ broker.
+
+### Port
+
+The port of the RabbitMQ broker.
+
+### User
+
+The username used to connect to the RabbitMQ broker.
+
+### Password
+
+The password used to connect to the RabbitMQ broker.
+
+### Exchange Name
+
+The name of the exchange.
+
+### RabbitMQ Topic
+
+The topic where events should be sent to.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/icon.png b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/icon.png
new file mode 100644
index 0000000..af0ddf6
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/icon.png
Binary files differ
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/strings.en b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/strings.en
new file mode 100644
index 0000000..8b65ec6
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rabbitmq/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.sinks.brokers.jvm.rabbitmq.title=RabbitMQ Publisher
+org.streampipes.sinks.brokers.jvm.rabbitmq.description=Forwards events to a RabbitMQ broker
+
+topic.title=RabbitMQ Topic
+topic.description=Select a RabbitMQ topic
+
+broker-settings.title=RabbitMQ broker settings
+broker-settings.description=Provide settings of the RabbitMQ broker to connect with.
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rest/documentation.md b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rest/documentation.md
new file mode 100644
index 0000000..4996216
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rest/documentation.md
@@ -0,0 +1,29 @@
+## REST Publisher
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Posts a JSON representation of an event to a REST interface.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+### REST URL
+
+The complete URL of the REST endpoint.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rest/strings.en b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rest/strings.en
new file mode 100644
index 0000000..98424de
--- /dev/null
+++ b/streampipes-sinks-brokers-jvm/src/main/resources/org.streampipes.sinks.brokers.jvm.rest/strings.en
@@ -0,0 +1,5 @@
+org.streampipes.sinks.brokers.jvm.rest.title=REST Publisher
+org.streampipes.sinks.brokers.jvm.rest.description=Posts events to a REST interface
+
+url-key.title=REST URL
+url-key.description=URL of the REST endoint
\ No newline at end of file
diff --git a/streampipes-sinks-databases-flink/pom.xml b/streampipes-sinks-databases-flink/pom.xml
index 49ffdc6..2e0b063 100644
--- a/streampipes-sinks-databases-flink/pom.xml
+++ b/streampipes-sinks-databases-flink/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-sinks-databases-flink/src/main/java/org/streampipes/sinks/databases/flink/elasticsearch/ElasticSearchController.java b/streampipes-sinks-databases-flink/src/main/java/org/streampipes/sinks/databases/flink/elasticsearch/ElasticSearchController.java
index 4d83114..f1ae500 100644
--- a/streampipes-sinks-databases-flink/src/main/java/org/streampipes/sinks/databases/flink/elasticsearch/ElasticSearchController.java
+++ b/streampipes-sinks-databases-flink/src/main/java/org/streampipes/sinks/databases/flink/elasticsearch/ElasticSearchController.java
@@ -25,8 +25,10 @@
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.sinks.databases.flink.config.DatabasesFlinkConfig;
 import org.streampipes.wrapper.flink.FlinkDataSinkDeclarer;
 import org.streampipes.wrapper.flink.FlinkDataSinkRuntime;
@@ -38,15 +40,16 @@
 
   @Override
   public DataSinkDescription declareModel() {
-    return DataSinkBuilder.create("org.streampipes.sinks.databases.flink.elasticsearch", "Elasticsearch", "Stores data in an elasticsearch cluster")
+    return DataSinkBuilder.create("org.streampipes.sinks.databases.flink.elasticsearch")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .category(DataSinkType.STORAGE)
-            .iconUrl(DatabasesFlinkConfig.getIconUrl("elasticsearch_icon"))
             .requiredStream(StreamRequirementsBuilder
                     .create()
-                    .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(), Labels.from(TIMESTAMP_MAPPING,
-                            "Timestamp Property", "Timestamp Mapping"), PropertyScope.HEADER_PROPERTY)
+                    .requiredPropertyWithUnaryMapping(EpRequirements.timestampReq(),
+                            Labels.withId(TIMESTAMP_MAPPING), PropertyScope.HEADER_PROPERTY)
                     .build())
-            .requiredTextParameter(Labels.from(INDEX_NAME, "Index Name", "Elasticsearch index name property"))
+            .requiredTextParameter(Labels.withId(INDEX_NAME))
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .build();
diff --git a/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/documentation.md b/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/documentation.md
new file mode 100644
index 0000000..5f1c634
--- /dev/null
+++ b/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/documentation.md
@@ -0,0 +1,36 @@
+## Elasticsearch
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Stores data in an Elasticsearch database.
+
+***
+
+## Required input
+
+This sink requires an event that provides a timestamp value (a field that is marked to be of type ``http://schema
+.org/DateTime``.
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### Timestamp Field
+
+The field which contains the required timestamp.
+
+### Index Name
+
+The name of the Elasticsearch index where events are stored to.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/icon.png b/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/icon.png
new file mode 100644
index 0000000..2046e24
--- /dev/null
+++ b/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/icon.png
Binary files differ
diff --git a/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/strings.en b/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/strings.en
new file mode 100644
index 0000000..9569e0a
--- /dev/null
+++ b/streampipes-sinks-databases-flink/src/main/resources/org.streampipes.sinks.databases.flink.elasticsearch/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.sinks.databases.flink.elasticsearch.title=Elasticsearch
+org.streampipes.sinks.databases.flink.elasticsearch.description=Stores data in an elasticsearch cluster
+
+timestamp-mapping.title=Timestamp Field
+timestamp-mapping.description=The field containing the timestamp for an Elasticsearch index
+
+index-name.title=Index Name
+index-name.description=Elasticsearch index name
\ No newline at end of file
diff --git a/streampipes-sinks-databases-jvm/pom.xml b/streampipes-sinks-databases-jvm/pom.xml
index 08886b9..b444957 100644
--- a/streampipes-sinks-databases-jvm/pom.xml
+++ b/streampipes-sinks-databases-jvm/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -43,6 +43,16 @@
             <artifactId>lightcouch</artifactId>
             <version>${lightcouch.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>42.2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.influxdb</groupId>
+            <artifactId>influxdb-java</artifactId>
+            <version>2.14</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/DatabasesJvmInit.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/DatabasesJvmInit.java
index ebc0033..7337749 100644
--- a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/DatabasesJvmInit.java
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/DatabasesJvmInit.java
@@ -24,13 +24,17 @@
 import org.streampipes.messaging.kafka.SpKafkaProtocolFactory;
 import org.streampipes.sinks.databases.jvm.config.DatabasesJvmConfig;
 import org.streampipes.sinks.databases.jvm.couchdb.CouchDbController;
+import org.streampipes.sinks.databases.jvm.influxdb.InfluxDbController;
+import org.streampipes.sinks.databases.jvm.postgresql.PostgreSqlController;
 
 public class DatabasesJvmInit extends StandaloneModelSubmitter {
 
   public static void main(String[] args) {
     DeclarersSingleton
             .getInstance()
-            .add(new CouchDbController());
+            .add(new CouchDbController())
+            .add(new InfluxDbController())
+            .add(new PostgreSqlController());
 
     DeclarersSingleton.getInstance().registerDataFormat(new JsonDataFormatFactory());
     DeclarersSingleton.getInstance().registerProtocol(new SpKafkaProtocolFactory());
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/couchdb/CouchDbController.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/couchdb/CouchDbController.java
index 07cfece..4585a79 100644
--- a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/couchdb/CouchDbController.java
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/couchdb/CouchDbController.java
@@ -24,9 +24,10 @@
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
-import org.streampipes.sinks.databases.jvm.config.DatabasesJvmConfig;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
@@ -40,19 +41,19 @@
 
   @Override
   public DataSinkDescription declareModel() {
-    return DataSinkBuilder.create("org.streampipes.sinks.databases.jvm.couchdb", "CouchDB", "Stores events in a couchdb database.")
+    return DataSinkBuilder.create("org.streampipes.sinks.databases.jvm.couchdb")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .category(DataSinkType.STORAGE)
-            .iconUrl(DatabasesJvmConfig.getIconUrl("couchdb_icon"))
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-            .requiredTextParameter(Labels.from(DATABASE_HOST_KEY, "Hostname", "The hostname of the CouchDB instance"))
-            .requiredIntegerParameter(Labels.from(DATABASE_PORT_KEY, "Port", "The port of the CouchDB instance"))
-            .requiredTextParameter(Labels.from(DATABASE_NAME_KEY, "Database Name", "The name of the database where events will " +
-                    "be stored"))
+            .requiredTextParameter(Labels.withId(DATABASE_HOST_KEY))
+            .requiredIntegerParameter(Labels.withId(DATABASE_PORT_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_NAME_KEY))
             .build();
   }
 
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDb.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDb.java
new file mode 100644
index 0000000..6bdb7de
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDb.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Ap<ache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.streampipes.sinks.databases.jvm.influxdb;
+
+import java.util.Map;
+import org.streampipes.commons.exceptions.SpRuntimeException;
+import org.streampipes.logging.api.Logger;
+import org.streampipes.model.runtime.Event;
+import org.streampipes.wrapper.context.EventSinkRuntimeContext;
+import org.streampipes.wrapper.runtime.EventSink;
+
+public class InfluxDb implements EventSink<InfluxDbParameters> {
+
+  private InfluxDbClient influxDbClient;
+
+  private static Logger LOG;
+
+  @Override
+  public void onInvocation(InfluxDbParameters parameters, EventSinkRuntimeContext runtimeContext) throws SpRuntimeException {
+    LOG = parameters.getGraph().getLogger(InfluxDb.class);
+
+    this.influxDbClient = new InfluxDbClient(
+        parameters.getInfluxDbHost(),
+        parameters.getInfluxDbPort(),
+        parameters.getDatabaseName(),
+        parameters.getMeasurementName(),
+        parameters.getUsername(),
+        parameters.getPassword(),
+        parameters.getTimestampField(),
+        parameters.getBatchSize(),
+        parameters.getFlushDuration(),
+        LOG
+    );
+  }
+
+  @Override
+  public void onEvent(Event event) {
+    try {
+      influxDbClient.save(event);
+    } catch (SpRuntimeException e) {
+      LOG.error(e.getMessage());
+    }
+  }
+
+  @Override
+  public void onDetach() throws SpRuntimeException {
+    influxDbClient.stop();
+  }
+}
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbClient.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbClient.java
new file mode 100644
index 0000000..8bad3fb
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbClient.java
@@ -0,0 +1,193 @@
+/*

+ * Copyright 2019 FZI Forschungszentrum Informatik

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package org.streampipes.sinks.databases.jvm.influxdb;

+

+import org.influxdb.BatchOptions;

+import org.influxdb.InfluxDB;

+import org.influxdb.InfluxDBFactory;

+import org.influxdb.dto.Point;

+import org.influxdb.dto.Pong;

+import org.influxdb.dto.Query;

+import org.influxdb.dto.QueryResult;

+import org.streampipes.commons.exceptions.SpRuntimeException;

+import org.streampipes.logging.api.Logger;

+import org.streampipes.model.runtime.Event;

+

+import java.util.List;

+import java.util.Map;

+import java.util.concurrent.TimeUnit;

+

+public class InfluxDbClient {

+	private Integer influxDbPort;

+	private String influxDbHost;

+	private String databaseName;

+	private String measureName;

+	private String user;

+	private String password;

+	private String timestampField;

+  private Integer batchSize;

+  private Integer flushDuration;

+

+	private Logger logger;

+

+	private InfluxDB influxDb = null;

+

+	InfluxDbClient(String influxDbHost,

+			Integer influxDbPort,

+			String databaseName,

+			String measureName,

+			String user,

+			String password,

+			String timestampField,

+      Integer batchSize,

+      Integer flushDuration,

+			Logger logger) throws SpRuntimeException {

+		this.influxDbHost = influxDbHost;

+		this.influxDbPort = influxDbPort;

+		this.databaseName = databaseName;

+		this.measureName = measureName;

+		this.user = user;

+		this.password = password;

+		this.timestampField = timestampField;

+		this.batchSize = batchSize;

+		this.flushDuration = flushDuration;

+		this.logger = logger;

+

+		validate();

+		connect();

+	}

+

+  /**

+   * Checks whether the {@link InfluxDbClient#influxDbHost} is valid

+   *

+   * @throws SpRuntimeException If the hostname is not valid

+   */

+	private void validate() throws SpRuntimeException {

+    //TODO: replace regex with validation method (import org.apache.commons.validator.routines.InetAddressValidator;)

+    // Validates the database name and the attributes

+    // See following link for regular expressions:

+    // https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address

+    /*String ipRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|"

+        + "[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";

+    String hostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*"

+        + "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$";*/

+    // https://stackoverflow.com/questions/3114595/java-regex-for-accepting-a-valid-hostname-ipv4-or-ipv6-address)

+    //if (!influxDbHost.matches(ipRegex) && !influxDbHost.matches(hostnameRegex)) {

+    //  throw new SpRuntimeException("Error: Hostname '" + influxDbHost

+    //      + "' not allowed");

+    //}

+  }

+

+  /**

+   * Connects to the InfluxDB Server, sets the database and initializes the batch-behaviour

+   *

+   * @throws SpRuntimeException If not connection can be established or if the database could not

+   * be found

+   */

+	private void connect() throws SpRuntimeException {

+	  // Connecting to the server

+    // "http://" must be in front

+    String urlAndPort = influxDbHost + ":" + influxDbPort;

+    influxDb = InfluxDBFactory.connect(urlAndPort, user, password);

+

+    // Checking, if server is available

+    Pong response = influxDb.ping();

+    if (response.getVersion().equalsIgnoreCase("unknown")) {

+      throw new SpRuntimeException("Could not connect to InfluxDb Server: " + urlAndPort);

+    }

+

+    // Checking whether the database exists

+    System.out.println(databaseExists(databaseName));

+    if(!databaseExists(databaseName)) {

+      logger.info("Database '" + databaseName + "' not found. Gets created ...");

+      createDatabase(databaseName);

+    }

+

+    // setting up the database

+    influxDb.setDatabase(databaseName);

+    influxDb.enableBatch(BatchOptions.DEFAULTS.actions(batchSize).flushDuration(flushDuration));

+	}

+

+  /**

+   * Checks whether the given database exists. Needs a working connection to an InfluxDB Server

+   * ({@link InfluxDbClient#influxDb} needs to be initialized)

+   *

+   * @param dbName The name of the database, the method should look for

+   * @return True if the database exists, false otherwise

+   */

+	private boolean databaseExists(String dbName) {

+    QueryResult queryResult = influxDb.query(new Query("SHOW DATABASES", ""));

+    for(List<Object> a : queryResult.getResults().get(0).getSeries().get(0).getValues()) {

+      if(a.get(0).equals(dbName)) {

+        return true;

+      }

+    }

+    return false;

+  }

+

+  /**

+   * Creates a new database with the given name

+   *

+   * @param dbName The name of the database which should be created

+   */

+  private void createDatabase(String dbName) throws SpRuntimeException {

+    if(!dbName.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {

+      throw new SpRuntimeException("Databasename '" + dbName + "' not allowed. Allowed names: ^[a-zA-Z_][a-zA-Z0-9_]*$");

+    }

+    influxDb.query(new Query("CREATE DATABASE \"" + dbName + "\"", ""));

+  }

+

+  /**

+   * Saves an event to the connnected InfluxDB database

+   *

+   * @param event The event which should be saved

+   * @throws SpRuntimeException If the column name (key-value of the event map) is not allowed

+   */

+	void save(Event event) throws SpRuntimeException {

+		if (event == null) {

+			throw new SpRuntimeException("event is null");

+		}

+		Long timestampValue = event.getFieldBySelector(timestampField).getAsPrimitive().getAsLong();

+    Point.Builder p = Point.measurement(measureName).time(timestampValue, TimeUnit.MILLISECONDS);

+		for (Map.Entry<String, Object> pair : event.getRaw().entrySet()) {

+      if(!pair.getKey().matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {

+        throw new SpRuntimeException("Column name '" + pair.getKey() + "' not allowed "

+            + "(allowed: '^[a-zA-Z_][a-zA-Z0-9_]*$')");

+      }

+      if (pair.getValue() instanceof Integer) {

+        p.addField(pair.getKey(), (Integer)pair.getValue());

+      } else if (pair.getValue() instanceof Long) {

+        p.addField(pair.getKey(), (Long)pair.getValue());

+      } else if (pair.getValue() instanceof Double) {

+        p.addField(pair.getKey(), (Double)pair.getValue());

+      } else if (pair.getValue() instanceof Boolean) {

+        p.addField(pair.getKey(), (Boolean)pair.getValue());

+      } else {

+        p.addField(pair.getKey(), pair.getValue().toString());

+      }

+    }

+

+    influxDb.write(p.build());

+	}

+

+  /**

+   * Shuts down the connection to the InfluxDB server

+   */

+	void stop() {

+    influxDb.close();

+	}

+}

diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbController.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbController.java
new file mode 100644
index 0000000..13a3fcb
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbController.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.streampipes.sinks.databases.jvm.influxdb;
+
+import org.streampipes.model.DataSinkType;
+import org.streampipes.model.graph.DataSinkDescription;
+import org.streampipes.model.graph.DataSinkInvocation;
+import org.streampipes.model.schema.PropertyScope;
+import org.streampipes.sdk.builder.DataSinkBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventSink;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
+
+public class InfluxDbController extends StandaloneEventSinkDeclarer<InfluxDbParameters> {
+
+  private static final String DATABASE_HOST_KEY = "db_host";
+  private static final String DATABASE_PORT_KEY = "db_port";
+  private static final String DATABASE_NAME_KEY = "db_name";
+  private static final String DATABASE_MEASUREMENT_KEY = "db_measurement";
+  private static final String DATABASE_USER_KEY = "db_user";
+  private static final String DATABASE_PASSWORD_KEY = "db_password";
+  private static final String TIMESTAMP_MAPPING_KEY = "timestamp_mapping";
+  private static final String BATCH_INTERVAL_ACTIONS_KEY = "batch_interval_actions";
+  private static final String MAX_FLUSH_DURATION_KEY = "max_flush_duration";
+
+
+  @Override
+  public DataSinkDescription declareModel() {
+    return DataSinkBuilder.create("org.streampipes.sinks.databases.jvm.influxdb")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .category(DataSinkType.STORAGE)
+            .requiredStream(StreamRequirementsBuilder.create().requiredPropertyWithUnaryMapping(
+                    EpRequirements.timestampReq(),
+                    Labels.withId(TIMESTAMP_MAPPING_KEY),
+                    PropertyScope.NONE).build())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .requiredTextParameter(Labels.withId(DATABASE_HOST_KEY))
+            .requiredIntegerParameter(Labels.withId(DATABASE_PORT_KEY), 8086)
+            .requiredIntegerParameter(Labels.withId(BATCH_INTERVAL_ACTIONS_KEY))
+            .requiredIntegerParameter(Labels.withId(MAX_FLUSH_DURATION_KEY), 2000)
+            .requiredTextParameter(Labels.withId(DATABASE_NAME_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_MEASUREMENT_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_USER_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_PASSWORD_KEY))
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventSink<InfluxDbParameters> onInvocation(DataSinkInvocation graph,
+                                                              DataSinkParameterExtractor extractor) {
+
+    String hostname = extractor.singleValueParameter(DATABASE_HOST_KEY, String.class);
+    Integer port = extractor.singleValueParameter(DATABASE_PORT_KEY, Integer.class);
+    String dbName = extractor.singleValueParameter(DATABASE_NAME_KEY, String.class);
+    String measureName = extractor.singleValueParameter(DATABASE_MEASUREMENT_KEY, String.class);
+    String user = extractor.singleValueParameter(DATABASE_USER_KEY, String.class);
+    String password = extractor.singleValueParameter(DATABASE_PASSWORD_KEY, String.class);
+    String timestampField = extractor.mappingPropertyValue(TIMESTAMP_MAPPING_KEY);
+    Integer batch_size = extractor.singleValueParameter(BATCH_INTERVAL_ACTIONS_KEY, Integer.class);
+    Integer flush_duration = extractor.singleValueParameter(MAX_FLUSH_DURATION_KEY, Integer.class);
+
+    InfluxDbParameters params = new InfluxDbParameters(graph,
+            hostname,
+            port,
+            dbName,
+            measureName,
+            user,
+            password,
+            timestampField,
+            batch_size,
+            flush_duration);
+
+    return new ConfiguredEventSink<>(params, InfluxDb::new);
+  }
+}
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbParameters.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbParameters.java
new file mode 100644
index 0000000..d4627a6
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/influxdb/InfluxDbParameters.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2019 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.streampipes.sinks.databases.jvm.influxdb;
+
+import org.streampipes.model.graph.DataSinkInvocation;
+import org.streampipes.wrapper.params.binding.EventSinkBindingParams;
+
+public class InfluxDbParameters extends EventSinkBindingParams {
+
+  private String influxDbHost;
+  private Integer influxDbPort;
+  private String databaseName;
+  private String measureName;
+  private String user;
+  private String password;
+  private String timestampField;
+  private Integer batchSize;
+  private Integer flushDuration;
+
+  public InfluxDbParameters(DataSinkInvocation graph,
+      String influxDbHost,
+      Integer influxDbPort,
+      String databaseName,
+      String measureName,
+      String user,
+      String password,
+      String timestampField,
+      Integer batchSize,
+      Integer flushDuration) {
+    super(graph);
+
+    this.influxDbHost = influxDbHost;
+    this.influxDbPort = influxDbPort;
+    this.databaseName = databaseName;
+    this.measureName = measureName;
+    this.user = user;
+    this.password = password;
+    this.timestampField = timestampField;
+    this.batchSize = batchSize;
+    this.flushDuration = flushDuration;
+  }
+
+  public String getInfluxDbHost() {
+    return influxDbHost;
+  }
+
+  public Integer getInfluxDbPort() {
+    return influxDbPort;
+  }
+
+  public String getDatabaseName() {
+    return databaseName;
+  }
+
+  public String getMeasurementName() {
+    return measureName;
+  }
+
+  public String getUsername() {
+    return user;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public String getTimestampField() {
+    return timestampField;
+  }
+
+  public Integer getBatchSize() {
+    return batchSize;
+  }
+
+  public Integer getFlushDuration() {
+    return flushDuration;
+  }
+}
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/jdbcclient/JdbcClient.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/jdbcclient/JdbcClient.java
new file mode 100644
index 0000000..d7792ff
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/jdbcclient/JdbcClient.java
@@ -0,0 +1,559 @@
+/*

+ * Copyright 2018 FZI Forschungszentrum Informatik

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package org.streampipes.sinks.databases.jvm.jdbcclient;

+

+import java.sql.Connection;

+import java.sql.DatabaseMetaData;

+import java.sql.DriverManager;

+import java.sql.PreparedStatement;

+import java.sql.ResultSet;

+import java.sql.SQLException;

+import java.sql.Statement;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import org.streampipes.commons.exceptions.SpRuntimeException;

+import org.streampipes.logging.api.Logger;

+import org.streampipes.model.runtime.Event;

+import org.streampipes.model.schema.EventProperty;

+import org.streampipes.model.schema.EventPropertyNested;

+import org.streampipes.model.schema.EventPropertyPrimitive;

+import org.streampipes.vocabulary.XSD;

+

+

+public class JdbcClient {

+	private String allowedRegEx;

+	private String urlName;

+

+	private Integer port;

+	private String host;

+	private String databaseName;

+	private String tableName;

+	private String user;

+	private String password;

+

+	private boolean tableExists = false;

+

+	private Logger logger;

+

+	private Connection c = null;

+	private Statement st = null;

+	private PreparedStatement ps = null;

+

+  /**

+   * The list of properties extracted from the graph

+   */

+	private List<EventProperty> eventProperties;

+	/**

+	 * The parameters in the prepared statement {@code ps} together with their index and data type

+	 */

+	private HashMap<String, Parameterinfo> parameters = new HashMap<>();

+

+	/**

+	 * A wrapper class for all supported SQL data types (INT, BIGINT, FLOAT, DOUBLE, VARCHAR(255)).

+	 * If no matching type is found, it is interpreted as a String (VARCHAR(255))

+	 */

+	private enum SqlAttribute {

+		INTEGER("INT"), LONG("BIGINT"), FLOAT("FLOAT"), DOUBLE("DOUBLE"), STRING("VARCHAR(255)");

+		private final String sqlName;

+

+		SqlAttribute(String s) {

+			sqlName = s;

+		}

+

+		/**

+		 * Tries to identify the data type of the object {@code o}. In case it is not supported, it is

+		 * interpreted as a String (VARCHAR(255))

+		 *

+		 * @param o The object which should be identified

+		 * @return An {@link SqlAttribute} of the identified type

+		 */

+    public static SqlAttribute getFromObject(final Object o) {

+      SqlAttribute r;

+      if (o instanceof Integer) {

+        r = SqlAttribute.INTEGER;

+      } else if (o instanceof Long) {

+        r = SqlAttribute.LONG;

+      } else if (o instanceof Float) {

+        r = SqlAttribute.FLOAT;

+      } else if (o instanceof Double) {

+        r = SqlAttribute.DOUBLE;

+      } else {

+        r = SqlAttribute.STRING;

+      }

+      return r;

+    }

+

+    public static SqlAttribute getFromUri(final String s) {

+      SqlAttribute r;

+      if (s.equals(XSD._integer)) {

+        r = SqlAttribute.INTEGER;

+      } else if (s.equals(XSD._long)) {

+        r = SqlAttribute.LONG;

+      } else if (s.equals(XSD._float)) {

+        r = SqlAttribute.FLOAT;

+      } else if (s.equals(XSD._double)) {

+        r = SqlAttribute.DOUBLE;

+      } else {

+        r = SqlAttribute.STRING;

+      }

+      return r;

+    }

+

+		/**

+		 * Sets the value in the prepardStatement {@code ps}

+		 *

+		 * @param p The needed info about the parameter (index and type)

+		 * @param value The value of the object, which should be filled in the

+		 * @param ps The prepared statement, which will be filled

+		 * @throws SpRuntimeException When the data type in {@code p} is unknown

+		 * @throws SQLException When the setters of the statement throw an

+     * exception (e.g. {@code setInt()})

+		 */

+		public static void setValue(Parameterinfo p, Object value, PreparedStatement ps)

+												throws SQLException, SpRuntimeException {

+			switch (p.type) {

+				case INTEGER:

+					ps.setInt(p.index, (Integer)value);

+					break;

+				case LONG:

+					ps.setLong(p.index, (Long)value);

+					break;

+				case FLOAT:

+					ps.setFloat(p.index, (Float)value);

+					break;

+				case DOUBLE:

+					ps.setDouble(p.index, (Double)value);

+					break;

+				case STRING:

+					ps.setString(p.index, value.toString());

+					break;

+				default:

+					throw new SpRuntimeException("Unknown SQL datatype");

+			}

+		}

+

+		@Override

+		public String toString() {

+			return sqlName;

+		}

+	}

+

+	/**

+	 * Contains all information needed to "fill" a prepared statement (index and the data type)

+	 */

+	private static class Parameterinfo {

+		private int index;

+		private SqlAttribute type;

+

+		private Parameterinfo(final int index, final SqlAttribute type) {

+			this.index = index;

+			this.type = type;

+		}

+	}

+

+

+	public JdbcClient(List<EventProperty> eventProperties,

+			String host,

+			Integer post,

+			String databaseName,

+			String tableName,

+			String user,

+			String password,

+			String allowedRegEx,

+			String driver,

+			String urlName,

+			Logger logger) throws SpRuntimeException {

+		this.host = host;

+		this.port = post;

+		this.databaseName = databaseName;

+		this.tableName = tableName;

+		this.user = user;

+		this.password = password;

+		this.allowedRegEx = allowedRegEx;

+		this.urlName = urlName;

+		this.logger = logger;

+		this.eventProperties = eventProperties;

+		try {

+			Class.forName(driver);

+		} catch (ClassNotFoundException e) {

+			throw new SpRuntimeException("Driver '" + driver + "' not found.");

+		}

+

+		validate();

+		connect();

+	}

+

+	/**

+	 * Checks whether the given {@link JdbcClient#host} and the {@link JdbcClient#databaseName}

+   * are allowed

+	 *

+	 * @throws SpRuntimeException If either the hostname or the databasename is not allowed

+	 */

+	private void validate() throws SpRuntimeException {

+		// Validates the database name and the attributes

+    // See following link for regular expressions:

+    // https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address

+		String ipRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|"

+        + "[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";

+    String hostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*"

+        + "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$";

+		//TODO: replace regex with validation method (import org.apache.commons.validator.routines.InetAddressValidator;)

+    // https://stackoverflow.com/questions/3114595/java-regex-for-accepting-a-valid-hostname-ipv4-or-ipv6-address)

+		/*if (!host.matches(ipRegex) && !host.matches(hostnameRegex)) {

+			throw new SpRuntimeException("Error: Hostname '" + postgreSqlHost

+					+ "' not allowed");

+		}*/

+		checkRegEx(databaseName, "Databasename");

+	}

+

+	/**

+	 * Connects to the HadoopFileSystem Server and initilizes {@link JdbcClient#c} and

+	 * {@link JdbcClient#st}

+	 *

+	 * @throws SpRuntimeException When the connection could not be established (because of a

+	 * wrong identification, missing database etc.)

+	 */

+	private void connect() throws SpRuntimeException {

+    checkRegEx(databaseName, "databasename");

+    String u = "jdbc:" + urlName + "://" + host + ":" + port + "/";

+    try {

+      // Checks whether the database already exists (using catalogs has not worked with postgres)

+      c = DriverManager.getConnection(u, user, password);

+      st = c.createStatement();

+      st.executeUpdate("CREATE DATABASE " + databaseName + ";");

+      logger.info("Created new database '" + databaseName + "'");

+    } catch (SQLException e1) {

+      if (!e1.getSQLState().substring(0, 2).equals("42")) {

+        throw new SpRuntimeException("Error while creating database: " + e1.getMessage());

+      }

+    }

+    closeAll();

+

+    try {

+      // Database should exist by now

+      c = DriverManager.getConnection(u + databaseName, user, password);

+      st = c.createStatement();

+      ResultSet rs = c.getMetaData().getTables(null, null, tableName, null);;

+			if (rs.next()) {

+			  //TODO: Add validation of an existing table

+				//validateTable();

+			} else {

+				createTable();

+			}

+			tableExists = true;

+			rs.close();

+		} catch (SQLException e) {

+      closeAll();

+			throw new SpRuntimeException(e.getMessage());

+		}

+	}

+

+	//TODO: Add batch support (https://stackoverflow.com/questions/3784197/efficient-way-to-do-batch-inserts-with-jdbc)

+	/**

+	 * Prepares a statement for the insertion of values or the

+	 *

+	 * @param event The event which should be saved to the Postgres table

+	 * @throws SpRuntimeException When there was an error in the saving process

+	 */

+	public void save(final Event event) throws SpRuntimeException {

+		Map<String, Object> eventMap = event.getRaw();

+		if (event == null) {

+			throw new SpRuntimeException("event is null");

+		}

+		if (!tableExists) {

+			// Creates the table

+			createTable();

+      tableExists = true;

+		}

+		try {

+			executePreparedStatement(eventMap);

+		} catch (SQLException e) {

+			if (e.getSQLState().substring(0, 2).equals("42")) {

+				// If the table does not exists (because it got deleted or something, will cause the error

+        // code "42") we will try to create a new one. Otherwise we do not handle the exception.

+				logger.warn("Table '" + tableName + "' was unexpectedly not found and gets recreated.");

+        tableExists = false;

+				createTable();

+        tableExists = true;

+

+        try {

+          executePreparedStatement(eventMap);

+        } catch (SQLException e1) {

+          throw new SpRuntimeException(e1.getMessage());

+        }

+      } else {

+				throw new SpRuntimeException(e.getMessage());

+			}

+		}

+	}

+

+	/**

+	 * Clears, fills and executes the saved prepared statement {@code ps} with the data found in

+   * event. To fill in the values it calls {@link JdbcClient#fillPreparedStatement(Map)}.

+	 *

+	 * @param event Data to be saved in the SQL table

+	 * @throws SQLException When the statement cannot be executed

+	 * @throws SpRuntimeException When the table name is not allowed or it is thrown

+	 * by {@link SqlAttribute#setValue(Parameterinfo, Object, PreparedStatement)}

+	 */

+	private void executePreparedStatement(final Map<String, Object> event)

+			throws SQLException, SpRuntimeException {

+		if (ps != null) {

+			ps.clearParameters();

+		}

+		fillPreparedStatement(event);

+		ps.executeUpdate();

+	}

+

+  private void fillPreparedStatement(final Map<String, Object> event)

+      throws SQLException, SpRuntimeException {

+    fillPreparedStatement(event, "");

+  }

+

+  /**

+   * Fills a prepared statement with the actual values base on {@link JdbcClient#parameters}. If

+   * {@link JdbcClient#parameters} is empty or not complete (which should only happen once in the

+   * begining), it calls {@link JdbcClient#generatePreparedStatement(Map)} to generate a new one.

+   * @param event

+   * @param pre

+   * @throws SQLException

+   * @throws SpRuntimeException

+   */

+  private void fillPreparedStatement(final Map<String, Object> event, String pre)

+      throws SQLException, SpRuntimeException {

+    //TODO: Possible error: when the event does not contain all objects of the parameter list

+    for (Map.Entry<String, Object> pair : event.entrySet()) {

+      String newKey = pre + pair.getKey();

+      if (pair.getValue() instanceof Map) {

+        // recursively extracts nested values

+        fillPreparedStatement((Map<String, Object>)pair.getValue(), newKey + "_");

+      } else {

+        if (!parameters.containsKey(newKey)) {

+          //TODO: start the for loop all over again

+          generatePreparedStatement(event);

+        }

+        Parameterinfo p = parameters.get(newKey);

+        SqlAttribute.setValue(p, pair.getValue(), ps);

+      }

+    }

+  }

+

+	/**

+	 * Initializes the variables {@link JdbcClient#parameters} and {@link JdbcClient#ps}

+	 * according to the parameter event.

+	 *

+	 * @param  event The event which is getting analyzed

+	 * @throws SpRuntimeException When the tablename is not allowed

+	 * @throws SQLException When the prepareStatment cannot be evaluated

+	 */

+	private void generatePreparedStatement(final Map<String, Object> event)

+			throws SQLException, SpRuntimeException {

+		// input: event

+		// wanted: INSERT INTO test4321 ( randomString, randomValue ) VALUES ( ?,? );

+		parameters.clear();

+		StringBuilder statement1 = new StringBuilder("INSERT  INTO ");

+		StringBuilder statement2 = new StringBuilder("VALUES ( ");

+		checkRegEx(tableName, "Tablename");

+		statement1.append(tableName).append(" ( ");

+

+    // Starts index at 1, since the parameterIndex in the PreparedStatement starts at 1 as well

+		extendPreparedStatement(event, statement1, statement2, 1);

+

+		statement1.append(" ) ");

+		statement2.append(" );");

+		String finalStatement = statement1.append(statement2).toString();

+		ps = c.prepareStatement(finalStatement);

+	}

+

+

+  private int extendPreparedStatement(final Map<String, Object> event,

+    StringBuilder s1, StringBuilder s2, int index) throws SpRuntimeException {

+    return extendPreparedStatement(event, s1, s2, index, "", "");

+  }

+

+  /**

+   *

+   * @param event

+   * @param s1

+   * @param s2

+   * @param index

+   * @param preProperty

+   * @param pre

+   * @return

+   * @throws SpRuntimeException

+   */

+  private int extendPreparedStatement(final Map<String, Object> event,

+      StringBuilder s1, StringBuilder s2, int index, String preProperty, String pre)

+      throws SpRuntimeException {

+	  for (Map.Entry<String, Object> pair : event.entrySet()) {

+	    if (pair.getValue() instanceof Map) {

+	      index = extendPreparedStatement((Map<String, Object>)pair.getValue(), s1, s2, index,

+            pair.getKey() + "_", pre);

+      } else {

+        checkRegEx(pair.getKey(), "Columnname");

+        parameters.put(pair.getKey(),

+            new Parameterinfo(index, SqlAttribute.getFromObject(pair.getValue())));

+        s1.append(pre).append("\"").append(preProperty).append(pair.getKey()).append("\"");

+        s2.append(pre).append("?");

+        index++;

+      }

+      pre = ", ";

+    }

+    return index;

+  }

+

+  /**

+   * Creates a table with the name {@link JdbcClient#tableName} and the

+   * properties {@link JdbcClient#eventProperties}. Calls

+   * {@link JdbcClient#extractEventProperties(List)} internally with the

+   * {@link JdbcClient#eventProperties} to extract all possible columns.

+   *

+   * @throws SpRuntimeException If the {@link JdbcClient#tableName}  is not allowed, if

+   *    executeUpdate throws an SQLException or if {@link JdbcClient#extractEventProperties(List)}

+   *    throws an exception

+   */

+	private void createTable() throws SpRuntimeException {

+	  checkRegEx(tableName, "Tablename");

+

+	  StringBuilder statement = new StringBuilder("CREATE TABLE \"");

+	  statement.append(tableName).append("\" ( ");

+	  statement.append(extractEventProperties(eventProperties)).append(" );");

+

+    try {

+      st.executeUpdate(statement.toString());

+    } catch (SQLException e) {

+      throw new SpRuntimeException(e.getMessage());

+    }

+  }

+

+  /**

+   * Creates a SQL-Query with the given Properties (SQL-Injection save). Calls

+   * {@link JdbcClient#extractEventProperties(List, String)} with an empty string

+   *

+   * @param properties The list of properties which should be included in the query

+   * @return A StringBuilder with the query which needs to be executed in order to create the table

+   * @throws SpRuntimeException See {@link JdbcClient#extractEventProperties(List, String)} for details

+   */

+	private StringBuilder extractEventProperties(List<EventProperty> properties)

+      throws SpRuntimeException {

+    return extractEventProperties(properties, "");

+  }

+

+  /**

+   * Creates a SQL-Query with the given Properties (SQL-Injection save). For nested properties it

+   * recursively extracts the information. EventPropertyList are getting converted to a string (so

+   * in SQL to a VARCHAR(255)). For each type it uses {@link SqlAttribute#getFromUri(String)}

+   * internally to identify the SQL-type from the runtimeType.

+   *

+   * @param properties The list of properties which should be included in the query

+   * @param preProperty A string which gets prepended to all property runtimeNames

+   * @return A StringBuilder with the query which needs to be executed in order to create the table

+   * @throws SpRuntimeException If the runtimeName of any property is not allowed

+   */

+	private StringBuilder extractEventProperties(List<EventProperty> properties, String preProperty)

+      throws SpRuntimeException {

+	  //IDEA: test, if the string is empty and maybe throw an exception (if it is the bottom layer)

+	  // output: "randomString VARCHAR(255), randomValue INT"

+    StringBuilder s = new StringBuilder();

+    String pre = "";

+    for (EventProperty property : properties) {

+      // Protection against SqlInjection

+

+      checkRegEx(property.getRuntimeName(), "Column name");

+      if (property instanceof EventPropertyNested) {

+        // if it is a nested property, recursively extract the needed properties

+        StringBuilder tmp = extractEventProperties(((EventPropertyNested)property).getEventProperties(),

+            preProperty + property.getRuntimeName() + "_");

+        if(tmp.length() > 0) {

+          s.append(pre).append(tmp);

+        }

+      } else {

+        // Adding the name of the property (e.g. "randomString")

+        // Or for properties in a nested structure: input1_randomValue

+        // "pre" is there for the ", " part

+        s.append(pre).append("\"").append(preProperty).append(property.getRuntimeName()).append("\" ");

+

+        // adding the type of the property (e.g. "VARCHAR(255)")

+	      if (property instanceof EventPropertyPrimitive) {

+          s.append(SqlAttribute.getFromUri(((EventPropertyPrimitive)property).getRuntimeType()));

+        } else {

+	        // Must be an EventPropertyList then

+          s.append(SqlAttribute.getFromUri(XSD._string.toString()));

+        }

+      }

+      pre = ", ";

+    }

+

+	  return s;

+	}

+

+  /**

+   * Checks if the input string is allowed (regEx match and length > 0)

+   *

+   * @param input String which is getting matched with the regEx

+   * @param as Information about the use of the input. Gets included in the exception message

+   * @throws SpRuntimeException If {@code input} does not match with {@link JdbcClient#allowedRegEx}

+   * or if the length of {@code input} is 0

+   */

+	private void checkRegEx(String input, String as) throws SpRuntimeException {

+    if (!input.matches(allowedRegEx) || input.length() == 0) {

+      throw new SpRuntimeException(as + " '" + input

+          + "' not allowed (allowed: '" + allowedRegEx + "') with a min length of 1");

+    }

+  }

+

+	private void validateTable() throws SpRuntimeException {

+		if(false) {

+		  throw new SpRuntimeException("Table '" + tableName + "' does not match the eventproperties");

+    }

+	}

+

+	/**

+	 * Closes all open connections and statements of JDBC

+	 */

+	public void closeAll() {

+	  boolean error = false;

+		try {

+      if (st != null) {

+        st.close();

+      }

+    } catch (SQLException e) {

+		  error = true;

+      logger.warn("Exception when closing the statement: " + e.getMessage());

+    }

+    try {

+      if (c != null) {

+        c.close();

+      }

+    } catch (SQLException e) {

+      error = true;

+      logger.warn("Exception when closing the connection: " + e.getMessage());

+    }

+    try {

+      if (ps != null) {

+        ps.close();

+      }

+    } catch (SQLException e) {

+      error = true;

+      logger.warn("Exception when closing the prepared statement: " + e.getMessage());

+    }

+    if(!error) {

+      logger.info("Shutdown all connections successfully.");

+    }

+  }

+}

diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSql.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSql.java
new file mode 100644
index 0000000..265900c
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSql.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.streampipes.sinks.databases.jvm.postgresql;
+
+import org.streampipes.commons.exceptions.SpRuntimeException;
+import org.streampipes.logging.api.Logger;
+import org.streampipes.model.runtime.Event;
+import org.streampipes.sinks.databases.jvm.jdbcclient.JdbcClient;
+import org.streampipes.wrapper.context.EventSinkRuntimeContext;
+import org.streampipes.wrapper.runtime.EventSink;
+
+import java.util.Map;
+
+public class PostgreSql implements EventSink<PostgreSqlParameters> {
+
+  private JdbcClient jdbcClient;
+
+  private static Logger LOG;
+
+  @Override
+  public void onInvocation(PostgreSqlParameters parameters, EventSinkRuntimeContext runtimeContext) throws SpRuntimeException {
+    LOG = parameters.getGraph().getLogger(PostgreSql.class);
+
+    // get(0) because it is the only input stream of the sink (and not two)
+    // See (https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS)
+    // for allowed postgres identifiers (for the regex)
+    this.jdbcClient = new JdbcClient(
+        parameters.getGraph().getInputStreams().get(0).getEventSchema().getEventProperties(),
+        parameters.getPostgreSqlHost(),
+        parameters.getPostgreSqlPort(),
+        parameters.getDatabaseName(),
+        parameters.getTableName(),
+        parameters.getUsername(),
+        parameters.getPassword(),
+        "^[a-zA-Z_][a-zA-Z0-9_]*$",
+        "org.postgresql.Driver",
+        "postgresql",
+        LOG
+    );
+  }
+
+  @Override
+  public void onEvent(Event event) {
+    try {
+      jdbcClient.save(event);
+    } catch (SpRuntimeException e) {
+      //TODO: error or warn?
+      LOG.error(e.getMessage());
+      //e.printStackTrace();
+    }
+  }
+
+  @Override
+  public void onDetach() throws SpRuntimeException {
+    jdbcClient.closeAll();
+  }
+}
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSqlController.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSqlController.java
new file mode 100644
index 0000000..c14a646
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSqlController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.streampipes.sinks.databases.jvm.postgresql;
+
+import org.streampipes.model.DataSinkType;
+import org.streampipes.model.graph.DataSinkDescription;
+import org.streampipes.model.graph.DataSinkInvocation;
+import org.streampipes.sdk.builder.DataSinkBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
+import org.streampipes.wrapper.standalone.ConfiguredEventSink;
+import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
+
+public class PostgreSqlController extends StandaloneEventSinkDeclarer<PostgreSqlParameters> {
+
+  private static final String DATABASE_HOST_KEY = "db_host";
+  private static final String DATABASE_PORT_KEY = "db_port";
+  private static final String DATABASE_NAME_KEY = "db_name";
+  private static final String DATABASE_TABLE_KEY = "db_table";
+  private static final String DATABASE_USER_KEY = "db_user";
+  private static final String DATABASE_PASSWORD_KEY = "db_password";
+
+  @Override
+  public DataSinkDescription declareModel() {
+    //TODO: Replace Icon, insert defaults (for the port)
+    return DataSinkBuilder.create("org.streampipes.sinks.databases.jvm.postgresql")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .category(DataSinkType.STORAGE)
+            .requiredStream(StreamRequirementsBuilder.create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .requiredTextParameter(Labels.withId(DATABASE_HOST_KEY))
+            .requiredIntegerParameter(Labels.withId(DATABASE_PORT_KEY), 5432)
+            .requiredTextParameter(Labels.withId(DATABASE_NAME_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_TABLE_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_USER_KEY))
+            .requiredTextParameter(Labels.withId(DATABASE_PASSWORD_KEY))
+            .build();
+  }
+
+  @Override
+  public ConfiguredEventSink<PostgreSqlParameters> onInvocation(DataSinkInvocation graph,
+                                                                DataSinkParameterExtractor extractor) {
+
+    String hostname = extractor.singleValueParameter(DATABASE_HOST_KEY, String.class);
+    Integer port = extractor.singleValueParameter(DATABASE_PORT_KEY, Integer.class);
+    String dbName = extractor.singleValueParameter(DATABASE_NAME_KEY, String.class);
+    String tableName = extractor.singleValueParameter(DATABASE_TABLE_KEY, String.class);
+    String user = extractor.singleValueParameter(DATABASE_USER_KEY, String.class);
+    String password = extractor.singleValueParameter(DATABASE_PASSWORD_KEY, String.class);
+
+    PostgreSqlParameters params = new PostgreSqlParameters(graph,
+            hostname,
+            port,
+            dbName,
+            tableName,
+            user,
+            password);
+
+    return new ConfiguredEventSink<>(params, PostgreSql::new);
+  }
+}
diff --git a/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSqlParameters.java b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSqlParameters.java
new file mode 100644
index 0000000..6a3da3c
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/java/org/streampipes/sinks/databases/jvm/postgresql/PostgreSqlParameters.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.streampipes.sinks.databases.jvm.postgresql;
+
+import org.streampipes.model.graph.DataSinkInvocation;
+import org.streampipes.wrapper.params.binding.EventSinkBindingParams;
+
+public class PostgreSqlParameters extends EventSinkBindingParams {
+
+  private String PostgreSqlHost;
+  private Integer PostgreSqlPort;
+  private String databaseName;
+  private String tableName;
+  private String user;
+  private String password;
+
+  public PostgreSqlParameters(DataSinkInvocation graph, String PostgreSqlHost, Integer PostgreSqlPort, String databaseName, String tableName, String user, String password) {
+    super(graph);
+    this.PostgreSqlHost = PostgreSqlHost;
+    this.PostgreSqlPort = PostgreSqlPort;
+    this.databaseName = databaseName;
+    this.tableName = tableName;
+    this.user = user;
+    this.password = password;
+  }
+
+  public String getPostgreSqlHost() {
+    return PostgreSqlHost;
+  }
+
+  public Integer getPostgreSqlPort() {
+    return PostgreSqlPort;
+  }
+
+  public String getDatabaseName() {
+    return databaseName;
+  }
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public String getUsername() {
+    return user;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+}
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/documentation.md b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/documentation.md
new file mode 100644
index 0000000..a42ebe5
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/documentation.md
@@ -0,0 +1,39 @@
+## CouchDB
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Stores events in an Apache CouchDB database.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### Hostname
+
+The hostname of the CouchDB instance.
+
+### Port
+
+The port of the CouchDB instance.
+
+### Database Name
+
+The name of the database where events will be stored
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/icon.png b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/icon.png
new file mode 100644
index 0000000..dbabb57
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/icon.png
Binary files differ
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/strings.en b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/strings.en
new file mode 100644
index 0000000..093935a
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.couchdb/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.sinks.databases.jvm.couchdb.title=CouchDB
+org.streampipes.sinks.databases.jvm.couchdb.description=Stores events in an Apache CouchDB database.
+
+db_host.title=Hostname
+db_host.description=The hostname of the CouchDB instance
+
+db_port.title=Port
+db_port.description=The port of the CouchDB instance
+
+db_name.title=Database Name
+db_name.description=The name of the database where events will be stored
\ No newline at end of file
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/documentation.md b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/documentation.md
new file mode 100644
index 0000000..7a5033a
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/documentation.md
@@ -0,0 +1,61 @@
+## InfluxDB
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Stores events in an InfluxDB.
+
+***
+
+## Required input
+
+This sink requires an event that provides a timestamp value (a field that is marked to be of type ``http://schema
+.org/DateTime``.
+
+***
+
+## Configuration
+
+### Hostname
+
+The hostname/URL of the InfluxDB instance. (Include http(s)://).
+
+### Port
+
+The port of the InfluxDB instance.
+
+### Database Name
+
+The name of the database where events will be stored.
+
+### Measurement Name
+
+The name of the Measurement where events will be stored (will be created if it does not exist).
+
+### Username
+
+The username for the InfluxDB Server.
+
+### Password
+
+The password for the InfluxDB Server.
+
+### Timestamp Field
+
+The field which contains the required timestamp.
+
+### Buffer Size
+
+Indicates how many events are written into a buffer, before they are written to the database.
+
+### Maximum Flush
+
+The maximum waiting time for the buffer to fill the Buffer size before it will be written to the database in ms.
+## Output
+
+(not applicable for data sinks)
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/icon.png b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/icon.png
new file mode 100644
index 0000000..1f9bb88
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/icon.png
Binary files differ
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/strings.en b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/strings.en
new file mode 100644
index 0000000..dd276f6
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.influxdb/strings.en
@@ -0,0 +1,29 @@
+org.streampipes.sinks.databases.jvm.influxdb.title=InfluxDB
+org.streampipes.sinks.databases.jvm.influxdb.description=Stores events in an InfluxDB.
+
+db_host.title=Hostname
+db_host.description=The hostname/URL of the InfluxDB instance. (Include http(s)://)
+
+db_port.title=Port
+db_port.description=The port of the InfluxDB instance
+
+db_name.title=Database Name
+db_name.description=The name of the database where events will be stored
+
+db_measurement.title=Measurement Name
+db_measurement.description=The name of the Measurement where events will be stored (will be created if it does not exist)
+
+db_user.title=Username
+db_user.description=The username for the InfluxDB Server
+
+db_password.title=Password
+db_password.description=The password for the InfluxDB Server
+
+timestamp_mapping.title=Timestamp Field
+timestamp_mapping.description=The value which contains a timestamp
+
+batch_interval_actions.title=Buffer Size
+batch_interval_actions.description=How many actions are written into a buffer, before it is written to the database
+
+max_flush_duration.title=Maximum Flush
+max_flush_duration.description=The maximum waiting time for the buffer to fill the Buffer size before it will be written to the database in ms
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/documentation.md b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/documentation.md
new file mode 100644
index 0000000..e44e1f6
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/documentation.md
@@ -0,0 +1,49 @@
+## PostgreSQL
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Stores events in a Postgres database.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+### Hostname
+
+The hostname of the PostgreSQL instance.
+
+### Port
+
+The port of the PostgreSQL instance (default 5432).
+
+### Database Name
+
+The name of the database where events will be stored
+
+### Table Name
+
+The name of the table where events will be stored (will be created if it does not exist)
+
+### Username
+
+The username for the PostgreSQL Server.
+
+### Password
+
+The password for the PostgreSQL Server.
+
+## Output
+
+(not applicable for data sinks)
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/icon.png b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/icon.png
new file mode 100644
index 0000000..a41005c
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/icon.png
Binary files differ
diff --git a/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/strings.en b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/strings.en
new file mode 100644
index 0000000..f16d439
--- /dev/null
+++ b/streampipes-sinks-databases-jvm/src/main/resources/org.streampipes.sinks.databases.jvm.postgresql/strings.en
@@ -0,0 +1,21 @@
+org.streampipes.sinks.databases.jvm.postgresql.title=PostgreSQL
+org.streampipes.sinks.databases.jvm.postgresql.description=Stores events in a Postgres database.
+
+db_host.title=Hostname
+db_host.description=The hostname of the PostgreSQL instance
+
+db_port.title=Port
+db_port.description=The port of the PostgreSQL instance (default 5432)
+
+db_name.title=Database Name
+db_name.description=The name of the database where events will be stored
+
+db_table.title=Table Name
+db_table.description=The name of the table where events will be stored (will be created if it does not exist)
+
+db_user.title=Username
+db_user.description=The username for the PostgreSQL Server
+
+db_password.title=Password
+db_password.description=The password for the PostgreSQL Server
+
diff --git a/streampipes-sinks-internal-jvm/pom.xml b/streampipes-sinks-internal-jvm/pom.xml
index 6de42d7..59335bf 100644
--- a/streampipes-sinks-internal-jvm/pom.xml
+++ b/streampipes-sinks-internal-jvm/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/dashboard/DashboardController.java b/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/dashboard/DashboardController.java
index 56bf3f8..7ab04f9 100644
--- a/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/dashboard/DashboardController.java
+++ b/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/dashboard/DashboardController.java
@@ -19,13 +19,14 @@
 import org.streampipes.model.DataSinkType;
 import org.streampipes.model.graph.DataSinkDescription;
 import org.streampipes.model.graph.DataSinkInvocation;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sinks.internal.jvm.config.SinksInternalJvmConfig;
 import org.streampipes.sdk.builder.DataSinkBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
@@ -33,15 +34,14 @@
 
     @Override
     public DataSinkDescription declareModel() {
-        return DataSinkBuilder.create("org.streampipes.sinks.internal.jvm.dashboard", "Dashboard Sink", "This sink will be used to visualize data" +
-                " " +
-                "streams in the StreamPipes dashboard")
+        return DataSinkBuilder.create("org.streampipes.sinks.internal.jvm.dashboard")
+                .withLocales(Locales.EN)
+                .withAssets(Assets.DOCUMENTATION, Assets.ICON)
                 .category(DataSinkType.VISUALIZATION_CHART)
                 .requiredStream(StreamRequirementsBuilder
                         .create()
                         .requiredProperty(EpRequirements.anyProperty())
                         .build())
-                .iconUrl(SinksInternalJvmConfig.getIconUrl("dashboard-icon"))
                 .supportedFormats(SupportedFormats.jsonFormat())
                 .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
                 .build();
diff --git a/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/notification/NotificationController.java b/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/notification/NotificationController.java
index 0e8c9ea..06cd8c7 100644
--- a/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/notification/NotificationController.java
+++ b/streampipes-sinks-internal-jvm/src/main/java/org/streampipes/sinks/internal/jvm/notification/NotificationController.java
@@ -19,49 +19,50 @@
 import org.streampipes.model.DataSinkType;
 import org.streampipes.model.graph.DataSinkDescription;
 import org.streampipes.model.graph.DataSinkInvocation;
-import org.streampipes.sdk.builder.StreamRequirementsBuilder;
-import org.streampipes.sinks.internal.jvm.config.SinksInternalJvmConfig;
 import org.streampipes.sdk.builder.DataSinkBuilder;
+import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
 public class NotificationController extends StandaloneEventSinkDeclarer<NotificationParameters> {
 
-	private static final String TITLE_KEY = "title";
-	private static final String CONTENT_KEY = "content";
+  private static final String TITLE_KEY = "title";
+  private static final String CONTENT_KEY = "content";
 
-	@Override
-	public DataSinkDescription declareModel() {
-		return DataSinkBuilder.create("org.streampipes.sinks.internal.jvm.notification", "Notification", "Displays a notification in the UI panel")
-						.category(DataSinkType.NOTIFICATION)
-						.iconUrl(SinksInternalJvmConfig.getIconUrl("notification_icon"))
-						.requiredStream(StreamRequirementsBuilder
-										.create()
-										.requiredProperty(EpRequirements.anyProperty())
-										.build())
-						.supportedFormats(SupportedFormats.jsonFormat())
-						.supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-						.requiredTextParameter(Labels.from(TITLE_KEY, "Notification title", "Notification title"))
-						.requiredHtmlInputParameter(Labels.from(CONTENT_KEY, "Content", "Enter the notification text. You can " +
-										"use place holders like #fieldName# to add the value of a stream variable."))
-						.build();
-	}
+  @Override
+  public DataSinkDescription declareModel() {
+    return DataSinkBuilder.create("org.streampipes.sinks.internal.jvm.notification")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+            .category(DataSinkType.NOTIFICATION)
+            .requiredStream(StreamRequirementsBuilder
+                    .create()
+                    .requiredProperty(EpRequirements.anyProperty())
+                    .build())
+            .supportedFormats(SupportedFormats.jsonFormat())
+            .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
+            .requiredTextParameter(Labels.withId(TITLE_KEY))
+            .requiredHtmlInputParameter(Labels.withId(CONTENT_KEY))
+            .build();
+  }
 
-	@Override
-	public ConfiguredEventSink<NotificationParameters> onInvocation(DataSinkInvocation graph,
-																																	DataSinkParameterExtractor extractor) {
+  @Override
+  public ConfiguredEventSink<NotificationParameters> onInvocation(DataSinkInvocation graph,
+                                                                  DataSinkParameterExtractor extractor) {
 
-		String title = extractor.singleValueParameter(TITLE_KEY, String.class);
-		String content = extractor.singleValueParameter(CONTENT_KEY, String.class);
+    String title = extractor.singleValueParameter(TITLE_KEY, String.class);
+    String content = extractor.singleValueParameter(CONTENT_KEY, String.class);
 
-		NotificationParameters params = new NotificationParameters(graph, title, content);
+    NotificationParameters params = new NotificationParameters(graph, title, content);
 
-		return new ConfiguredEventSink<>(params, NotificationProducer::new);
-	}
+    return new ConfiguredEventSink<>(params, NotificationProducer::new);
+  }
 
 }
diff --git a/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/documentation.md b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/documentation.md
new file mode 100644
index 0000000..96aa5a4
--- /dev/null
+++ b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/documentation.md
@@ -0,0 +1,28 @@
+## Dashboard Sink
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This sink visualizes data streams in the StreamPipes dashboard. 
+Visualizations can be configured in Live Dashboard of StreamPipes after the pipeline has been started.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+No further configuration necessary, individual visualizations can be configured in the Dashboard itself.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/icon.png b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/icon.png
new file mode 100644
index 0000000..8a4d45b
--- /dev/null
+++ b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/icon.png
Binary files differ
diff --git a/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/strings.en b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/strings.en
new file mode 100644
index 0000000..ae44c41
--- /dev/null
+++ b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.dashboard/strings.en
@@ -0,0 +1,2 @@
+org.streampipes.sinks.internal.jvm.dashboard.title=Dashboard Sink
+org.streampipes.sinks.internal.jvm.dashboard.description=Visualizes data streams in the StreamPipes dashboard
\ No newline at end of file
diff --git a/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/documentation.md b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/documentation.md
new file mode 100644
index 0000000..72e037c
--- /dev/null
+++ b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/documentation.md
@@ -0,0 +1,34 @@
+## Notification
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Displays a notification in the UI panel of StreamPipes.
+
+***
+
+## Required input
+
+
+***
+
+## Configuration
+
+This sink does not have any requirements and works with any incoming event type.
+
+### Notification Title
+
+The title of the notification.
+
+### Content
+
+The notification message.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/icon.png b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/icon.png
new file mode 100644
index 0000000..57d1d63
--- /dev/null
+++ b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/icon.png
Binary files differ
diff --git a/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/strings.en b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/strings.en
new file mode 100644
index 0000000..b95e7d7
--- /dev/null
+++ b/streampipes-sinks-internal-jvm/src/main/resources/org.streampipes.sinks.internal.jvm.notification/strings.en
@@ -0,0 +1,8 @@
+org.streampipes.sinks.internal.jvm.notification.title=Notification
+org.streampipes.sinks.internal.jvm.notification.description=Publish a notification to the StreamPipes UI.
+
+title.title=Notification Title
+title.description=
+
+content.title=Content
+content.description=Enter the notification text. You can  use placeholders like #fieldName# to add the value of a stream variable.
\ No newline at end of file
diff --git a/streampipes-sinks-notifications-jvm/pom.xml b/streampipes-sinks-notifications-jvm/pom.xml
index 67f6cfc..f340f85 100644
--- a/streampipes-sinks-notifications-jvm/pom.xml
+++ b/streampipes-sinks-notifications-jvm/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailController.java b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailController.java
index 78d2a03..509c644 100644
--- a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailController.java
+++ b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailController.java
@@ -25,9 +25,10 @@
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
 import org.streampipes.sdk.helpers.EpRequirements;
 import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
 import org.streampipes.sdk.helpers.SupportedFormats;
 import org.streampipes.sdk.helpers.SupportedProtocols;
-import org.streampipes.sinks.notifications.jvm.config.SinksNotificationsJvmConfig;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
@@ -40,17 +41,17 @@
 
   @Override
   public DataSinkDescription declareModel() {
-    return DataSinkBuilder.create("org.streampipes.sinks.notifications.jvm.email", "Email Notification", "Email bot to send notifications emails")
+    return DataSinkBuilder.create("org.streampipes.sinks.notifications.jvm.email")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .category(DataSinkType.NOTIFICATION)
-            .iconUrl(SinksNotificationsJvmConfig.getIconUrl("email"))
-            .requiredTextParameter(Labels.from(TO_EMAIL_ADRESS, "To", "Receiver E-mail address"))
-            .requiredTextParameter(Labels.from(EMAIL_SUBJECT, "Subject", "The subject of the email"))
+            .requiredTextParameter(Labels.withId(TO_EMAIL_ADRESS))
+            .requiredTextParameter(Labels.withId(EMAIL_SUBJECT))
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
-            .requiredHtmlInputParameter(Labels.from(EMAIL_CONTENT, "Content", "Enter the email text. You can" +
-                    "use place holders like #fieldName# to add the value of a stream variable."))
+            .requiredHtmlInputParameter(Labels.withId(EMAIL_CONTENT))
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
             .build();
diff --git a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailPublisher.java b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailPublisher.java
index 533d2ef..88d055a 100644
--- a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailPublisher.java
+++ b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/email/EmailPublisher.java
@@ -63,10 +63,12 @@
         properties.setProperty("mail.smtp.host", host);
         properties.setProperty("mail.smtp.port", String.valueOf(port));
 
-        if(starttls)
-            properties.put("mail.smtp.starttls.enable","true");
-        if(ssl)
+        if (starttls) {
+            properties.put("mail.smtp.starttls.enable", "true");
+        }
+        if (ssl) {
             properties.put("mail.smtp.ssl.enable", "true");
+        }
         properties.put("mail.smtp.auth", "true");
 
         Session session = Session.getDefaultInstance(properties, new Authenticator() {
@@ -85,7 +87,6 @@
         } catch (MessagingException e) {
            LOG.error(e.toString());
         }
-
     }
 
     @Override
diff --git a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/onesignal/OneSignalController.java b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/onesignal/OneSignalController.java
index 908db99..94c54a8 100644
--- a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/onesignal/OneSignalController.java
+++ b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/onesignal/OneSignalController.java
@@ -23,8 +23,12 @@
 import org.streampipes.sdk.builder.DataSinkBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
-import org.streampipes.sdk.helpers.*;
-import org.streampipes.sinks.notifications.jvm.config.SinksNotificationsJvmConfig;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
 import org.streampipes.wrapper.standalone.declarer.StandaloneEventSinkDeclarer;
 
@@ -36,18 +40,19 @@
 
     @Override
     public DataSinkDescription declareModel() {
-        return DataSinkBuilder.create("org.streampipes.sinks.notifications.jvm.onesignal", "OneSignal", "Send Push Message to OneSignal-Application")
+        return DataSinkBuilder.create("org.streampipes.sinks.notifications.jvm.onesignal")
+                .withLocales(Locales.EN)
+                .withAssets(Assets.DOCUMENTATION, Assets.ICON)
                 .category(DataSinkType.NOTIFICATION)
-                .iconUrl(SinksNotificationsJvmConfig.getIconUrl("one_signal"))
                 .requiredStream(StreamRequirementsBuilder
                         .create()
                         .requiredProperty(EpRequirements.anyProperty())
                         .build())
                 .supportedFormats(SupportedFormats.jsonFormat())
                 .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-                .requiredHtmlInputParameter(Labels.from(CONTENT_KEY, "Content", "Push Message"))
-                .requiredTextParameter(Labels.from(APP_ID, "App-ID", "OneSignal App ID"))
-                .requiredTextParameter(Labels.from(REST_API_KEY, "API-Key", "REST API Key"))
+                .requiredHtmlInputParameter(Labels.withId(CONTENT_KEY))
+                .requiredTextParameter(Labels.withId(APP_ID))
+                .requiredTextParameter(Labels.withId(REST_API_KEY))
                 .build();
     }
 
diff --git a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/slack/SlackNotificationController.java b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/slack/SlackNotificationController.java
index 7732e89..9080c5e 100644
--- a/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/slack/SlackNotificationController.java
+++ b/streampipes-sinks-notifications-jvm/src/main/java/org/streampipes/sinks/notifications/jvm/slack/SlackNotificationController.java
@@ -27,7 +27,13 @@
 import org.streampipes.sdk.builder.DataSinkBuilder;
 import org.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.streampipes.sdk.extractor.DataSinkParameterExtractor;
-import org.streampipes.sdk.helpers.*;
+import org.streampipes.sdk.helpers.EpRequirements;
+import org.streampipes.sdk.helpers.Labels;
+import org.streampipes.sdk.helpers.Locales;
+import org.streampipes.sdk.helpers.Options;
+import org.streampipes.sdk.helpers.SupportedFormats;
+import org.streampipes.sdk.helpers.SupportedProtocols;
+import org.streampipes.sdk.utils.Assets;
 import org.streampipes.sinks.notifications.jvm.config.ConfigKeys;
 import org.streampipes.sinks.notifications.jvm.config.SinksNotificationsJvmConfig;
 import org.streampipes.wrapper.standalone.ConfiguredEventSink;
@@ -44,18 +50,20 @@
   @Override
   public DataSinkDescription declareModel() {
 
-    return DataSinkBuilder.create("org.streampipes.sinks.notifications.jvm.slack", "Slack Notification", "Slack bot to send notifications directly into your slack")
+    return DataSinkBuilder.create("org.streampipes.sinks.notifications.jvm.slack")
+            .withLocales(Locales.EN)
+            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
             .category(DataSinkType.NOTIFICATION)
-            .iconUrl(SinksNotificationsJvmConfig.getIconUrl("slack_icon"))
             .requiredStream(StreamRequirementsBuilder
                     .create()
                     .requiredProperty(EpRequirements.anyProperty())
                     .build())
             .supportedFormats(SupportedFormats.jsonFormat())
             .supportedProtocols(SupportedProtocols.kafka(), SupportedProtocols.jms())
-            .requiredTextParameter(Labels.from(RECEIVER, "Send to", "Enter the username or channel you want to notify"))
-            .requiredTextParameter(Labels.from(CONTENT, "Message", "The message that should be sent"))
-            .requiredSingleValueSelection(Labels.from(CHANNEL_TYPE, "User or Channel", "Decide wether you want to sent a notification to a user or to a channel"), Options.from("User", "Channel"))
+            .requiredTextParameter(Labels.withId(RECEIVER))
+            .requiredTextParameter(Labels.withId(CONTENT))
+            .requiredSingleValueSelection(Labels.withId(CHANNEL_TYPE),
+                    Options.from("User", "Channel"))
             .build();
   }
 
@@ -88,7 +96,8 @@
       } else {
         SlackChannel channel = session.findChannelByName(userChannel);
         if (channel == null || channel.getId() == null) {
-          //throw new SpRuntimeException("The channel: '" + userChannel + "' does not exists or the bot has no rights to access it");
+          //throw new SpRuntimeException("The channel: '" + userChannel + "' does not exists or " +
+                  //"the bot has no rights to access it");
         }
       }
 
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/documentation.md b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/documentation.md
new file mode 100644
index 0000000..cf9db21
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/documentation.md
@@ -0,0 +1,43 @@
+## Email Notification
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This sink sends an email to a specified receiver.
+
+Before you use this sink, the settings of your email server need to be configured.
+After you've installed the element, navigate to ``Settings``, open the panel ``Sinks Notifications JVM`` and add your
+ mail server and credentials.
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+The following configuration is required:
+
+### Receiver Address
+
+The email address of the receiver.
+
+### Subject
+
+The subject of the email.
+
+### Content
+
+The mail text.
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/icon.png b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/icon.png
new file mode 100644
index 0000000..2fd0ce5
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/icon.png
Binary files differ
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/strings.en b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/strings.en
new file mode 100644
index 0000000..c4353a9
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.email/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.sinks.notifications.jvm.email.title=Email Notification
+org.streampipes.sinks.notifications.jvm.email.description=Email service to send notifications emails
+
+to_email.title=To
+to_email.description=Receiver E-mail address
+
+email_subject.title=Subject
+email_subject.description=The subject of the email
+
+email_content.title=Content
+email_content.description=Enter the email text. You can use place holders like #fieldName# to add the value of a field.
\ No newline at end of file
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/documentation.md b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/documentation.md
new file mode 100644
index 0000000..c446dfa
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/documentation.md
@@ -0,0 +1,39 @@
+## OneSignal
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+This sink sends a push message to the OneSignal application
+
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### App Id
+
+The OneSignal application ID.
+
+### API Key
+
+The OneSignal API key.
+
+### Content
+
+The message that should be sent to OneSignal
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/icon.png b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/icon.png
new file mode 100644
index 0000000..f866d48
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/icon.png
Binary files differ
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/strings.en b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/strings.en
new file mode 100644
index 0000000..7d1a60f
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.onesignal/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.sinks.notifications.jvm.onesignal.title=OneSignal
+org.streampipes.sinks.notifications.jvm.onesignal.description=Send Push Message to OneSignal-Application
+
+content.title=Content
+content.description=Push Message
+
+app_id.title=App-ID
+app_id.description=OneSignal App ID
+
+api_key.title=API-Key
+api_key.description=REST API Key
\ No newline at end of file
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/documentation.md b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/documentation.md
new file mode 100644
index 0000000..212c75c
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/documentation.md
@@ -0,0 +1,44 @@
+## Slack Notification
+
+<p align="center"> 
+    <img src="icon.png" width="150px;" class="pe-image-documentation"/>
+</p>
+
+***
+
+## Description
+
+Slack bot to send notifications directly into your slack
+
+Before you use this sink, the Slack token needs to be configured.
+After you've installed the element, navigate to ``Settings``, open the panel ``Sinks Notifications JVM`` and add your
+Slack API token.
+***
+
+## Required input
+
+This sink does not have any requirements and works with any incoming event type.
+
+***
+
+## Configuration
+
+Describe the configuration parameters here
+
+### Receiver
+
+The receiver of the Slack message.
+
+### Channel Type
+
+The channel type, should be "User" or "Channel"
+
+### Content
+
+The message that should be sent.
+
+### 2nd parameter
+
+## Output
+
+(not applicable for data sinks)
\ No newline at end of file
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/icon.png b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/icon.png
new file mode 100644
index 0000000..b9eb9ab
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/icon.png
Binary files differ
diff --git a/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/strings.en b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/strings.en
new file mode 100644
index 0000000..d35fc09
--- /dev/null
+++ b/streampipes-sinks-notifications-jvm/src/main/resources/org.streampipes.sinks.notifications.jvm.slack/strings.en
@@ -0,0 +1,11 @@
+org.streampipes.sinks.notifications.jvm.slack.title=Slack Notification
+org.streampipes.sinks.notifications.jvm.slack.description=Slack bot to send notifications to Slack
+
+receiver.title=Send to
+receiver.description=Enter the username or channel you want to notify
+
+content.title=Message
+content.description=The message that should be sent
+
+channel-type.title=User or Channel
+channel-type.description=Decide wether you want to sent a notification to a user or to a channel
\ No newline at end of file
diff --git a/streampipes-sources-random-data-generator/pom.xml b/streampipes-sources-random-data-generator/pom.xml
index 2d5e62b..ec027f0 100644
--- a/streampipes-sources-random-data-generator/pom.xml
+++ b/streampipes-sources-random-data-generator/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-sources-random-data-generator/src/main/java/org/streampipes/sources/random/config/SourcesConfig.java b/streampipes-sources-random-data-generator/src/main/java/org/streampipes/sources/random/config/SourcesConfig.java
index dba99c5..449d647 100644
--- a/streampipes-sources-random-data-generator/src/main/java/org/streampipes/sources/random/config/SourcesConfig.java
+++ b/streampipes-sources-random-data-generator/src/main/java/org/streampipes/sources/random/config/SourcesConfig.java
@@ -32,7 +32,8 @@
 
   SourcesConfig() {
     config = SpConfig.getSpConfig(SERVICE_ID);
-    config.register(ConfigKeys.HOST, "pe-sources-random", "Hostname for the pe sources samples");
+    config.register(ConfigKeys.HOST, "sources-random-data-generator", "Hostname for the pe " +
+            "sources samples");
     config.register(ConfigKeys.PORT, 8090, "Port for the pe sources samples");
     config.register(ConfigKeys.KAFKA_HOST, "kafka", "Host for kafka of the pe sources samples project");
     config.register(ConfigKeys.KAFKA_PORT, 9092, "Port for kafka of the pe sources samples project");
diff --git a/streampipes-sources-vehicle-simulator/pom.xml b/streampipes-sources-vehicle-simulator/pom.xml
index a93933c..81b6e3b 100644
--- a/streampipes-sources-vehicle-simulator/pom.xml
+++ b/streampipes-sources-vehicle-simulator/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/streampipes-sources-watertank-simulator/pom.xml b/streampipes-sources-watertank-simulator/pom.xml
index 29907bc..092a263 100644
--- a/streampipes-sources-watertank-simulator/pom.xml
+++ b/streampipes-sources-watertank-simulator/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>streampipes-pipeline-elements</artifactId>
         <groupId>org.streampipes</groupId>
-        <version>0.61.0</version>
+        <version>0.62.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>