Repository: apache/streampipes
Pull request #1682 (2023-06-14 08:00:33)

Harmonize OPC-UA adapter and sink, add timestamp to metadata (#899)
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one or more
  ~ contributor license agreements.  See the NOTICE file distributed with
  ~ this work for additional information regarding copyright ownership.
  ~ The ASF licenses this file to You 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.
  ~
  -->
  
  <!--
Thanks for contributing! Here are some tips you can follow to help us incorporate your contribution quickly and easily:
1. If this is your first time, please read our contributor guidelines:
    - https://streampipes.apache.org/getinvolved.html
    - https://cwiki.apache.org/confluence/display/STREAMPIPES/Getting+Started
2. Make sure the PR title is formatted like: `[#<GitHub issue id>] PR title ...`
3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., `[WIP][#<GitHub issue id>] PR title ...`.
4. Please write your PR title to summarize what this PR proposes/fixes.
5. Link the PR to the corresponding GitHub issue (if present) in the `Development` section in the right menu bar. 
6. Be sure to keep the PR description updated to reflect all changes.
7. If possible, provide a concise example to reproduce the issue for a faster review.
8. Make sure tests pass via `mvn clean install`.
9. (Optional) If the contribution is large, please file an Apache ICLA
    - http://apache.org/licenses/icla.pdf
-->

### Purpose
<!--
Please clarify what changes you are proposing and describe how those changes will address the issue.
Furthermore, describe potential consequences the changes might have.
-->

### Remarks
<!--
Is there anything left we need to pay attention on?
Are there some references that might be important? E.g. links to Confluence, or discussions
on the mailing list or GitHub.
-->
PR introduces (a) breaking change(s): <yes/no>

PR introduces (a) deprecation(s): <yes/no>



Patch:
diff --git a/README.md b/README.md
index 9266f9b931..2c995a10ce 100644
--- a/README.md
+++ b/README.md
@@ -22,11 +22,13 @@
 [![Maven central](https://img.shields.io/maven-central/v/org.apache.streampipes/streampipes-service-core.svg)](https://img.shields.io/maven-central/v/org.apache.streampipes/streampipes-service-core.svg)
 [![License](https://img.shields.io/github/license/apache/streampipes.svg)](http://www.apache.org/licenses/LICENSE-2.0)
 [![Last commit](https://img.shields.io/github/last-commit/apache/streampipes.svg)]()
-[![Twitter](https://img.shields.io/twitter/follow/StreamPipes.svg?label=Follow&style=social)](https://twitter.com/StreamPipes)
 [![Apache StreamPipes](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/q1jdu2&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/q1jdu2/runs)
 [![Contributors](https://img.shields.io/github/contributors/apache/streampipes)](https://github.com/apache/streampipes/graphs/contributors)
 ![GitHub commit activity](https://img.shields.io/github/commit-activity/y/apache/streampipes)
 [![GitHub issues by-label](https://img.shields.io/github/issues/apache/streampipes/good%20first%20issue)](https://github.com/apache/streampipes/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
+<br>
+[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://linkedin.com/company/apache-streampipes)
+[![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/StreamPipes)
 
 <h1 align="center">
   <br>
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 3eff615f47..ed1cf2450c 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -21,6 +21,137 @@ All notable changes to this project will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
+
+# [0.92.0]
+
+## What's Changed
+
+### Enhancement 🌟
+
+* [[#1564](https://github.com/apache/streampipes/issues/1564)]: Add feature to assign labels to StreamPipes resources
+* [[#1522](https://github.com/apache/streampipes/issues/1522)]: Return 404 if requested pipeline does not exist
+* [[#1520](https://github.com/apache/streampipes/issues/1520)]: Map http 404 to Java Optional.empty in Java Client
+* [[#1518](https://github.com/apache/streampipes/issues/1518)]: Compiling maven submodule with checkstyle check
+* [[#1467](https://github.com/apache/streampipes/pull/1467)]: Implement create method in Java client PipelineApi
+* [[#1405](https://github.com/apache/streampipes/issues/1405)]: Enable search for Python docs
+* [[#1339](https://github.com/apache/streampipes/pull/1339)]: Support backend-only development mode (#1327)
+* [[#1319](https://github.com/apache/streampipes/pull/1319)]: chore(ui): provide some more references for support in the 'about' view
+* [[#1307](https://github.com/apache/streampipes/issues/1307)]: Geometry Validation processor
+* [[#1296](https://github.com/apache/streampipes/issues/1296)]: Swinging Door Trending (SDT) Filter Processor
+* [[#1272](https://github.com/apache/streampipes/issues/1272)]: Buffer Processor
+* [[#1261](https://github.com/apache/streampipes/issues/1261)]: Add Python changes to release notes
+* [[#1259](https://github.com/apache/streampipes/issues/1259)]: Verify authentication on startup of Python client
+* [[#1113](https://github.com/apache/streampipes/issues/1113)]: Add buttons to start and stop all adapters
+* [[#1107](https://github.com/apache/streampipes/issues/1107)]: Build Github worfklow with OSV scanner
+* [[#1101](https://github.com/apache/streampipes/issues/1101)]: Extend StreamPipes API by a health-check endpoint
+
+
+### Bug fixes 🧰
+
+* [[#1547](https://github.com/apache/streampipes/issues/1547)]: standalone dashborad empty
+* [[#1527](https://github.com/apache/streampipes/issues/1527)]: Fix logo url of email templates
+* [[#1501](https://github.com/apache/streampipes/pull/1501)]: [hotfix] Fix handling of count queries in data explorer
+* [[#1479](https://github.com/apache/streampipes/issues/1479)]: Truncate does not work in data lake configuration
+* [[#1439](https://github.com/apache/streampipes/issues/1439)]: Past data exists twice in raw widget
+* [[#1391](https://github.com/apache/streampipes/issues/1391)]: Data Explorer filter doesn't work for boolean and `false` value
+* [[#1333](https://github.com/apache/streampipes/issues/1333)]: Endpoint to receive pipelines is broken
+* [[#1329](https://github.com/apache/streampipes/issues/1329)]: Data Lake measurements endpoint returns no data series when no data between `startDate` and `endDate`
+* [[#1327](https://github.com/apache/streampipes/issues/1327)]: Failed to start local backend enviroment
+* [[#1308](https://github.com/apache/streampipes/issues/1308)]: [CI] label-pr workflow fails on fork-based PRs
+* [[#1291](https://github.com/apache/streampipes/issues/1291)]: Can't aggregate calculation results of the Math processing element
+* [[#1199](https://github.com/apache/streampipes/issues/1199)]: UI Semantik Type field is too small to see full term
+* [[#793](https://github.com/apache/streampipes/issues/793)]: Empty string as API token name
+
+
+### Breaking Change 💣
+
+* [[#1040](https://github.com/apache/streampipes/issues/1040)]: Change Event Runtime Name of geometry field
+
+
+### Deprecation ⚠️
+
+* [[#1115](https://github.com/apache/streampipes/discussions/1115)] **IMPORTANT** In the future we will remove support for data set adapters
+
+
+### Documentation & Website 📚
+
+* [[#1623](https://github.com/apache/streampipes/pull/1623)]: chore: mark streampipes-wrapper-python as deprecated
+* [[#1535](https://github.com/apache/streampipes/pull/1535)]: Add vulnerability report
+* [[#1442](https://github.com/apache/streampipes/issues/1442)]: Extend Python docs with dark mode
+* [[#1415](https://github.com/apache/streampipes/pull/1415)]: [doc](readme)Enhancement in some Hyperlinks.
+* [[#1411](https://github.com/apache/streampipes/issues/1411)]: Create custom error page for Python docs
+* [[#1405](https://github.com/apache/streampipes/issues/1405)]: Enable search for Python docs
+* [[#1327](https://github.com/apache/streampipes/issues/1327)]: Failed to start local backend enviroment
+* [[#1326](https://github.com/apache/streampipes/pull/1326)]: chore(docs): add information on how to develop the UI locally
+* [[#1051](https://github.com/apache/streampipes/issues/1051)]: Add further badges to README of Python client
+
+
+### Dependency Updates 📦
+
+* [[#1623](https://github.com/apache/streampipes/pull/1623)]: chore: mark streampipes-wrapper-python as deprecated
+* [[#1577](https://github.com/apache/streampipes/pull/1577)]: Bump tubemq-client from 1.5.0 to 1.6.0
+* [[#1574](https://github.com/apache/streampipes/pull/1574)]: Bump amqp-client from 5.16.0 to 5.17.0
+* [[#1571](https://github.com/apache/streampipes/pull/1571)]: Remove guice from dependencies
+* [[#1570](https://github.com/apache/streampipes/pull/1570)]: Bump annotations from 16.0.2 to 24.0.1
+* [[#1566](https://github.com/apache/streampipes/pull/1566)]: Bump mypy from 1.2.0 to 1.3.0 in /streampipes-client-python
+* [[#1562](https://github.com/apache/streampipes/pull/1562)]: Bump jackson-databind from 2.14.1 to 2.15.0
+* [[#1560](https://github.com/apache/streampipes/pull/1560)]: Bump google-maps-services from 2.1.2 to 2.2.0
+* [[#1559](https://github.com/apache/streampipes/pull/1559)]: Bump pyupgrade from 3.3.1 to 3.4.0 in /streampipes-client-python
+* [[#1558](https://github.com/apache/streampipes/pull/1558)]: Bump types-requests from 2.29.0.0 to 2.30.0.0 in /streampipes-client-python
+* [[#1552](https://github.com/apache/streampipes/pull/1552)]: Bump opencsv from 5.5.2 to 5.7.1
+* [[#1550](https://github.com/apache/streampipes/pull/1550)]: Bump commons-compress from 1.22 to 1.23.0
+* [[#1549](https://github.com/apache/streampipes/pull/1549)]: Bump engine.io and socket.io in /ui
+* [[#1545](https://github.com/apache/streampipes/pull/1545)]: Bump consul from 1.17.6 to 1.18.0
+* [[#1542](https://github.com/apache/streampipes/pull/1542)]: Bump jackson.version from 2.14.1 to 2.15.0
+* [[#1541](https://github.com/apache/streampipes/pull/1541)]: Bump pre-commit from 3.2.0 to 3.3.0 in /streampipes-client-python
+* [[#1540](https://github.com/apache/streampipes/pull/1540)]: Bump flask from 1.1.2 to 2.3.2 in /streampipes-wrapper-python
+* [[#1539](https://github.com/apache/streampipes/pull/1539)]: chore(deps): bump several dependencies to resolve vulnerability issues
+* [[#1536](https://github.com/apache/streampipes/pull/1536)]: Bump types-requests from 2.28.11.7 to 2.29.0.0 in /streampipes-client-python
+* [[#1525](https://github.com/apache/streampipes/pull/1525)]: Bump mkdocs-gen-files from 0.4.0 to 0.5.0 in /streampipes-client-python
+* [[#1516](https://github.com/apache/streampipes/pull/1516)]: Bump karma-chrome-launcher from 3.1.1 to 3.2.0 in /ui/projects/streampipes/platform-services
+* [[#1512](https://github.com/apache/streampipes/pull/1512)]: Bump jetty-server from 10.0.10 to 10.0.14
+* [[#1511](https://github.com/apache/streampipes/pull/1511)]: Bump spring-core from 6.0.7 to 6.0.8 & spring-bot from 3.0.5 to 3.0.6 & spring-security from 6.0.2 to 6.0.3
+* [[#1510](https://github.com/apache/streampipes/pull/1510)]: Bump type-parser from 0.7.0 to 0.8.1
+* [[#1507](https://github.com/apache/streampipes/pull/1507)]: Bump maven-plugin-plugin from 3.7.0 to 3.8.1
+* [[#1506](https://github.com/apache/streampipes/pull/1506)]: Bump pandas-stubs from 1.5.2.230105 to 2.0.0.230412 in /streampipes-client-python
+* [[#1503](https://github.com/apache/streampipes/pull/1503)]: Bump peter-evans/create-pull-request from 4 to 5
+* [[#1502](https://github.com/apache/streampipes/pull/1502)]: Bump mkdocs-awesome-pages-plugin from 2.8.0 to 2.9.0 in /streampipes-client-python
+* [[#1499](https://github.com/apache/streampipes/pull/1499)]: Bump log4j.version from 2.19.0 to 2.20.0
+* [[#1498](https://github.com/apache/streampipes/pull/1498)]: Bump pytest from 7.2.1 to 7.3.0 in /streampipes-client-python
+* [[#1472](https://github.com/apache/streampipes/pull/1472)]: Bump rdf4j.version from 3.5.0 to 3.7.7
+
+
+### Uncategorized ❓
+
+* [[#1532](https://github.com/apache/streampipes/pull/1532)]: [hotfix] exclude versions file from pydocs update
+* [[#1524](https://github.com/apache/streampipes/pull/1524)]: feature: add workflow that stales PRs
+* [[#1517](https://github.com/apache/streampipes/pull/1517)]: [FEATURE] add division as operation for data harmonization rules
+* [[#1504](https://github.com/apache/streampipes/issues/1504)]: Data streams are removed from pipelines when exported
+* [[#1497](https://github.com/apache/streampipes/pull/1497)]: [hotfix] Move sp-split-section to shared-ui module
+* [[#1484](https://github.com/apache/streampipes/pull/1484)]: [hotfix] Improve handling of count queries, improve table widget
+* [[#1478](https://github.com/apache/streampipes/issues/1478)]: Distinguish between Consumer and Publisher for the broker
+* [[#1475](https://github.com/apache/streampipes/issues/1475)]: Fulfill PEP 561 compatibility
+* [[#1465](https://github.com/apache/streampipes/pull/1465)]: [hotfix] Fix configuration for pipeline element development
+* [[#1445](https://github.com/apache/streampipes/pull/1445)]: Improve Log info in Processor Test
+* [[#1433](https://github.com/apache/streampipes/pull/1433)]: update archetypes template
+* [[#1428](https://github.com/apache/streampipes/pull/1428)]: Maintain the same directory structure for source and test
+* [[#1406](https://github.com/apache/streampipes/issues/1406)]: Cleanup data explorer query management
+* [[#1385](https://github.com/apache/streampipes/issues/1385)]: Remove unused features from data explorer module
+* [[#1383](https://github.com/apache/streampipes/issues/1383)]: Introduce environment variable to provide path to file storage of backend
+* [[#1368](https://github.com/apache/streampipes/pull/1368)]: Improve create client model script
+* [[#1367](https://github.com/apache/streampipes/issues/1367)]: Add `QueryResult` as data type for `DataLakeMeasureEndpoint`
+* [[#1362](https://github.com/apache/streampipes/issues/1362)]: Support Kafka in Python client
+* [[#1361](https://github.com/apache/streampipes/pull/1361)]: Fix UI container cannot resolve backend IP correctly
+* [[#1350](https://github.com/apache/streampipes/pull/1350)]: [hotfix] Use try-with-resource way to fix the potential InfluxDB connection leak in `DataExplorerQueryV4#executeQuery`
+* [[#1336](https://github.com/apache/streampipes/issues/1336)]: Create builder for SpQueryResult
+* [[#1311](https://github.com/apache/streampipes/pull/1311)]: chore(ci): improve caching for dependencies in pr-validation workflow
+* [[#1293](https://github.com/apache/streampipes/issues/1293)]: Rename java module name `streampipes-extensions-management`
+* [[#1264](https://github.com/apache/streampipes/issues/1264)]: CLI Installer clean does not delete volumes anymore
+* [[#841](https://github.com/apache/streampipes/issues/841)]: Include supported Java versions in CI
+* [[#777](https://github.com/apache/streampipes/issues/777)]: 1-class processor model and stylechecks on all processors.geo.jvm
+* [[#655](https://github.com/apache/streampipes/issues/655)]: Support change of username and password in profile view
+
+
 # [0.91.0]
 
 ## Appreciation
diff --git a/archetypes/streampipes-archetype-extensions-jvm/pom.xml b/archetypes/streampipes-archetype-extensions-jvm/pom.xml
index 0b3fc03b01..a9d848d9a6 100644
--- a/archetypes/streampipes-archetype-extensions-jvm/pom.xml
+++ b/archetypes/streampipes-archetype-extensions-jvm/pom.xml
@@ -51,6 +51,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/archetypes/streampipes-archetype-pe-processors-flink/pom.xml b/archetypes/streampipes-archetype-pe-processors-flink/pom.xml
index 8e6286c919..2a6196d766 100644
--- a/archetypes/streampipes-archetype-pe-processors-flink/pom.xml
+++ b/archetypes/streampipes-archetype-pe-processors-flink/pom.xml
@@ -51,6 +51,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/archetypes/streampipes-archetype-pe-sinks-flink/pom.xml b/archetypes/streampipes-archetype-pe-sinks-flink/pom.xml
index 42f57597d7..25e9cb76a3 100644
--- a/archetypes/streampipes-archetype-pe-sinks-flink/pom.xml
+++ b/archetypes/streampipes-archetype-pe-sinks-flink/pom.xml
@@ -51,6 +51,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/pom.xml b/pom.xml
index ab4c1c4151..d16ffb3fec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,7 +42,7 @@
 	<asm.version>9.4</asm.version>
 	<cloning.version>1.9.12</cloning.version>
 	<commons-beanutils.version>1.9.4</commons-beanutils.version>
-	<commons-codec.version>1.11</commons-codec.version>
+	<commons-codec.version>1.15</commons-codec.version>
 	<commons-collections.version>3.2.2</commons-collections.version>
 	<commons-io.version>2.11.0</commons-io.version>
 	<commons-lang3.version>3.12.0</commons-lang3.version>
@@ -54,7 +54,7 @@
 	<fogsy-qudt.version>1.0</fogsy-qudt.version>
 	<fst.version>2.57</fst.version>
 	<geojson-jackson.version>1.14</geojson-jackson.version>
-	<guava.version>31.1-jre</guava.version>
+	<guava.version>32.0.1-jre</guava.version>
 	<gson.version>2.10</gson.version>
 	<hibernate-validator.version>8.0.0.Final</hibernate-validator.version>
 	<httpclient.version>4.5.13</httpclient.version>
@@ -115,7 +115,7 @@
 	<simple-java-mail.version>7.8.0</simple-java-mail.version>
 	<slf4j.version>2.0.6</slf4j.version>
 	<snakeyaml.version>1.33</snakeyaml.version>
-	<snappy-java.version>1.1.7.7</snappy-java.version>
+	<snappy-java.version>1.1.10.1</snappy-java.version>
 	<spring.version>6.0.8</spring.version>
 	<spring-boot.version>3.1.0</spring-boot.version>
 	<spring-security.version>6.0.3</spring-security.version>
@@ -130,7 +130,7 @@
 
 	<!-- Test dependencies -->
 	<junit.version>4.13.2</junit.version>
-	<mockito.version>5.3.1</mockito.version>
+	<mockito.version>5.4.0</mockito.version>
 	<powermock.version>2.0.9</powermock.version>
 	<rest-assured.version>2.9.0</rest-assured.version>
 	<wiremock.version>2.27.2</wiremock.version>
@@ -201,11 +201,11 @@
 	<checksum-maven-plugin.version>1.11</checksum-maven-plugin.version>
 	<checkstyle.version>10.6.0</checkstyle.version>
 	<extra-enforcer-rules.version>1.6.1</extra-enforcer-rules.version>
-	<formatter-maven-plugin.version>2.21.0</formatter-maven-plugin.version>
+	<formatter-maven-plugin.version>2.23.0</formatter-maven-plugin.version>
 	<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
 	<maven-checkstyle-plugin.version>3.2.1</maven-checkstyle-plugin.version>
 	<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
-	<maven.dependency.check.plugin.version>6.5.1</maven.dependency.check.plugin.version>
+	<maven.dependency.check.plugin.version>8.3.1</maven.dependency.check.plugin.version>
 	<maven-dependency-plugin.version>3.5.0</maven-dependency-plugin.version>
 	<maven-javadoc-plugin.version>3.4.1</maven-javadoc-plugin.version>
 	<mave-release-plugin.version>3.0.0-M5</mave-release-plugin.version>
diff --git a/streampipes-client-python/README.md b/streampipes-client-python/README.md
index aece5a73c3..35f7b76964 100644
--- a/streampipes-client-python/README.md
+++ b/streampipes-client-python/README.md
@@ -34,6 +34,9 @@ and the amazing universe of data analytics libraries in Python. </p>
 <br>
 
 <p align="center">
+<a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">
+    <img src="https://img.shields.io/github/license/apache/streampipes.svg" alt="License Apache 2.0">
+</a>
 <a href="https://github.com/apache/streampipes/tree/dev/streampipes-client-python" target="_blank">
     <img src="https://img.shields.io/pypi/pyversions/streampipes" alt="Supported Python versions">
 </a>
diff --git a/streampipes-client-python/setup.py b/streampipes-client-python/setup.py
index 6a5d118efc..7aa3a7bf31 100644
--- a/streampipes-client-python/setup.py
+++ b/streampipes-client-python/setup.py
@@ -33,6 +33,7 @@ PROJECT_URLS = {
     "Documentation": "https://streampipes.apache.org/docs/docs/python/latest/",
     "Bug Tracker": "https://github.com/apache/streampipes/issues",
     "Source Code": "https://github.com/apache/streampipes",
+    "Changelog": "https://github.com/apache/streampipes/releases",
 }
 
 # Package requirements.
@@ -46,18 +47,18 @@ base_packages = [
 ]
 
 dev_packages = base_packages + [
-    "autoflake==2.1.0",
+    "autoflake==2.2.0",
     "black==23.3.0",
     "blacken-docs==1.14.0",
     "flake8==6.0.0",
     "interrogate[png]==1.5.0",
     "isort==5.12.0",
-    "mypy==1.3.0",
+    "mypy==1.4.0",
     "pandas-stubs==2.0.0.230412",
     "pre-commit==3.3.0",
-    "pytest==7.3.0",
+    "pytest==7.4.0",
     "pytest-cov==4.1.0",
-    "pyupgrade==3.6.0",
+    "pyupgrade==3.7.0",
     "types-Jinja2==2.11.9",
     "types-requests==2.31.0.0",
 ]
diff --git a/streampipes-client/pom.xml b/streampipes-client/pom.xml
index 3eb39855d0..263ffa43d6 100644
--- a/streampipes-client/pom.xml
+++ b/streampipes-client/pom.xml
@@ -83,10 +83,6 @@
         </dependency>
 
         <!-- 3rd party Dependencies -->
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-        </dependency>
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
diff --git a/streampipes-commons/pom.xml b/streampipes-commons/pom.xml
index 18cf8dc381..3667bc39aa 100644
--- a/streampipes-commons/pom.xml
+++ b/streampipes-commons/pom.xml
@@ -39,10 +39,20 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <extensions>
diff --git a/streampipes-commons/src/main/java/org/apache/streampipes/commons/resources/Resources.java b/streampipes-commons/src/main/java/org/apache/streampipes/commons/resources/Resources.java
new file mode 100644
index 0000000000..32c0bdd2f7
--- /dev/null
+++ b/streampipes-commons/src/main/java/org/apache/streampipes/commons/resources/Resources.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.commons.resources;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+public class Resources {
+
+  public static String asString(String resourceName,
+                                Charset charset) throws IOException {
+    return IOUtils.resourceToString(resourceName, charset, ClassLoader.getSystemClassLoader());
+  }
+
+  public static URL asUrl(String resourceName) throws IOException {
+    return IOUtils.resourceToURL(resourceName, ClassLoader.getSystemClassLoader());
+  }
+}
diff --git a/streampipes-config/pom.xml b/streampipes-config/pom.xml
index 1c57e371d5..6f70e62e59 100644
--- a/streampipes-config/pom.xml
+++ b/streampipes-config/pom.xml
@@ -49,12 +49,6 @@
             <artifactId>streampipes-service-discovery</artifactId>
             <version>0.93.0-SNAPSHOT</version>
         </dependency>
-
-        <!-- External dependencies -->
-        <dependency>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>jsr305</artifactId>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/SelectClauseParams.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/SelectClauseParams.java
index 6861b4915e..fe7f8d0f65 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/SelectClauseParams.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/SelectClauseParams.java
@@ -22,8 +22,6 @@ package org.apache.streampipes.dataexplorer.param.model;
 import org.apache.streampipes.dataexplorer.api.IQueryStatement;
 import org.apache.streampipes.dataexplorer.querybuilder.IDataLakeQueryBuilder;
 
-import javax.annotation.Nullable;
-
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -56,8 +54,8 @@ public class SelectClauseParams implements IQueryStatement {
     }
   }
 
-  public static SelectClauseParams from(@Nullable String columns,
-                                        @Nullable String aggregationFunction) {
+  public static SelectClauseParams from(String columns,
+                                        String aggregationFunction) {
     return new SelectClauseParams(columns, aggregationFunction);
   }
 
diff --git a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/locales/LabelGenerator.java b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/locales/LabelGenerator.java
index 2bfb9a6d0d..3ce1807a3d 100644
--- a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/locales/LabelGenerator.java
+++ b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/locales/LabelGenerator.java
@@ -34,6 +34,8 @@ import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
 import java.util.Properties;
 
 import static org.apache.streampipes.extensions.management.util.LocalesUtil.makePath;
@@ -126,7 +128,7 @@ public class LabelGenerator {
 
   private Properties makeProperties() throws IOException {
     Properties props = new Properties();
-    props.load(loadResource());
+    props.load(new InputStreamReader(loadResource(), StandardCharsets.UTF_8));
 
     return props;
   }
diff --git a/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/java/org/apache/streampipes/connect/iiot/protocol/stream/KafkaProtocol.java b/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/java/org/apache/streampipes/connect/iiot/protocol/stream/KafkaProtocol.java
index 9f5ce94f32..e65806cb1b 100644
--- a/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/java/org/apache/streampipes/connect/iiot/protocol/stream/KafkaProtocol.java
+++ b/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/java/org/apache/streampipes/connect/iiot/protocol/stream/KafkaProtocol.java
@@ -33,6 +33,7 @@ import org.apache.streampipes.extensions.api.extractor.IStaticPropertyExtractor;
 import org.apache.streampipes.extensions.api.runtime.SupportsRuntimeConfig;
 import org.apache.streampipes.extensions.management.connect.adapter.parser.Parsers;
 import org.apache.streampipes.messaging.kafka.SpKafkaConsumer;
+import org.apache.streampipes.messaging.kafka.config.KafkaConfigAppender;
 import org.apache.streampipes.model.AdapterType;
 import org.apache.streampipes.model.connect.guess.GuessSchema;
 import org.apache.streampipes.model.grounding.KafkaTransportProtocol;
@@ -40,10 +41,10 @@ import org.apache.streampipes.model.grounding.SimpleTopicDefinition;
 import org.apache.streampipes.model.staticproperty.Option;
 import org.apache.streampipes.model.staticproperty.RuntimeResolvableOneOfStaticProperty;
 import org.apache.streampipes.model.staticproperty.StaticProperty;
+import org.apache.streampipes.model.staticproperty.StaticPropertyAlternative;
 import org.apache.streampipes.pe.shared.config.kafka.kafka.KafkaConfig;
 import org.apache.streampipes.pe.shared.config.kafka.kafka.KafkaConnectUtils;
 import org.apache.streampipes.sdk.builder.adapter.AdapterConfigurationBuilder;
-import org.apache.streampipes.sdk.helpers.Labels;
 import org.apache.streampipes.sdk.helpers.Locales;
 import org.apache.streampipes.sdk.utils.Assets;
 
@@ -89,6 +90,7 @@ public class KafkaProtocol implements StreamPipesAdapter, SupportsRuntimeConfig
     final Properties props = new Properties();
 
     kafkaConfig.getSecurityConfig().appendConfig(props);
+    kafkaConfig.getAutoOffsetResetConfig().appendConfig(props);
 
     props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
         kafkaConfig.getKafkaHost() + ":" + kafkaConfig.getKafkaPort());
@@ -137,6 +139,10 @@ public class KafkaProtocol implements StreamPipesAdapter, SupportsRuntimeConfig
 
   @Override
   public IAdapterConfiguration declareConfig() {
+
+    StaticPropertyAlternative latestAlternative = KafkaConnectUtils.getAlternativesLatest();
+    latestAlternative.setSelected(true);
+
     return AdapterConfigurationBuilder
         .create(ID, KafkaProtocol::new)
         .withSupportedParsers(Parsers.defaultParsers())
@@ -144,7 +150,7 @@ public class KafkaProtocol implements StreamPipesAdapter, SupportsRuntimeConfig
         .withLocales(Locales.EN)
         .withCategory(AdapterType.Generic, AdapterType.Manufacturing)
 
-        .requiredAlternatives(Labels.withId(KafkaConnectUtils.ACCESS_MODE),
+        .requiredAlternatives(KafkaConnectUtils.getAccessModeLabel(),
             KafkaConnectUtils.getAlternativeUnauthenticatedPlain(),
             KafkaConnectUtils.getAlternativeUnauthenticatedSSL(),
             KafkaConnectUtils.getAlternativesSaslPlain(),
@@ -158,6 +164,10 @@ public class KafkaProtocol implements StreamPipesAdapter, SupportsRuntimeConfig
         .requiredSingleValueSelectionFromContainer(KafkaConnectUtils.getTopicLabel(), Arrays.asList(
             KafkaConnectUtils.HOST_KEY,
             KafkaConnectUtils.PORT_KEY))
+        .requiredAlternatives(KafkaConnectUtils.getAutoOffsetResetConfigLabel(),
+                KafkaConnectUtils.getAlternativesEarliest(),
+                latestAlternative,
+                KafkaConnectUtils.getAlternativesNone())
         .buildConfiguration();
   }
 
@@ -171,12 +181,17 @@ public class KafkaProtocol implements StreamPipesAdapter, SupportsRuntimeConfig
     protocol.setBrokerHostname(config.getKafkaHost());
     protocol.setTopicDefinition(new SimpleTopicDefinition(config.getTopic()));
 
+    List<KafkaConfigAppender> kafkaConfigAppenderList = new ArrayList<>(2);
+    kafkaConfigAppenderList.add(this.config.getSecurityConfig());
+    kafkaConfigAppenderList.add(this.config.getAutoOffsetResetConfig());
+
     this.kafkaConsumer = new SpKafkaConsumer(protocol,
         config.getTopic(),
         new BrokerEventProcessor(extractor.selectedParser(), (event) -> {
           collector.collect(event);
         }),
-        Collections.singletonList(this.config.getSecurityConfig()));
+        kafkaConfigAppenderList
+        );
 
     thread = new Thread(this.kafkaConsumer);
     thread.start();
diff --git a/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/resources/org.apache.streampipes.connect.iiot.protocol.stream.kafka/strings.en b/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/resources/org.apache.streampipes.connect.iiot.protocol.stream.kafka/strings.en
index 15d3dce848..fd8ef54bc4 100644
--- a/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/resources/org.apache.streampipes.connect.iiot.protocol.stream.kafka/strings.en
+++ b/streampipes-extensions/streampipes-connect-adapters-iiot/src/main/resources/org.apache.streampipes.connect.iiot.protocol.stream.kafka/strings.en
@@ -59,3 +59,15 @@ value-deserialization.description=
 
 hide-internal-topics.title=Hide internal topics
 hide-internal-topics.description=Do not show topics that are only used internally
+
+auto.offset.reset.title=Auto Offset Reset
+auto.offset.reset.description=Configure the starting offset for consumer consumption when there is no initial offset in Kafka or when the current offset does not exist
+
+earliest.title=Earliest
+earliest.description=Offsets are initialized to the earliest
+
+latest.title=Latest
+latest.description=Offsets are initialized to the Latest
+
+none.title=None
+none.description=Consumer throws exceptions
\ No newline at end of file
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java
index e4d4718693..bfa035c0cc 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java
@@ -29,8 +29,12 @@ import org.apache.streampipes.extensions.api.connect.context.IAdapterRuntimeCont
 import org.apache.streampipes.extensions.api.extractor.IAdapterParameterExtractor;
 import org.apache.streampipes.extensions.api.extractor.IStaticPropertyExtractor;
 import org.apache.streampipes.extensions.api.runtime.SupportsRuntimeConfig;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.configuration.SpOpcUaConfigBuilder;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.utils.OpcUaUtil;
+import org.apache.streampipes.extensions.connectors.opcua.client.SpOpcUaClient;
+import org.apache.streampipes.extensions.connectors.opcua.config.OpcUaAdapterConfig;
+import org.apache.streampipes.extensions.connectors.opcua.config.SharedUserConfiguration;
+import org.apache.streampipes.extensions.connectors.opcua.config.SpOpcUaConfigExtractor;
+import org.apache.streampipes.extensions.connectors.opcua.model.OpcNode;
+import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaUtil;
 import org.apache.streampipes.extensions.management.connect.PullAdapterScheduler;
 import org.apache.streampipes.extensions.management.connect.adapter.util.PollingSettings;
 import org.apache.streampipes.model.AdapterType;
@@ -53,7 +57,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -62,26 +65,11 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
 
-import static org.apache.streampipes.extensions.connectors.opcua.adapter.utils.OpcUaUtil.getSchema;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.ACCESS_MODE;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.ADAPTER_TYPE;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.AVAILABLE_NODES;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.HOST_PORT;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.NAMESPACE_INDEX;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.NODE_ID;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_HOST;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_HOST_OR_URL;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_HOST;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_PORT;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_URL;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_URL;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.PASSWORD;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.PULLING_INTERVAL;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.PULL_MODE;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.SUBSCRIPTION_MODE;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.UNAUTHENTICATED;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.USERNAME;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.USERNAME_GROUP;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaUtil.getSchema;
 
 public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsRuntimeConfig {
 
@@ -89,7 +77,7 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR
   private static final Logger LOG = LoggerFactory.getLogger(OpcUaAdapter.class);
 
   private int pullingIntervalMilliSeconds;
-  private SpOpcUaClient spOpcUaClient;
+  private SpOpcUaClient<OpcUaAdapterConfig> spOpcUaClient;
   private List<OpcNode> allNodes;
   private List<NodeId> allNodeIds;
   private int numberProperties;
@@ -129,11 +117,11 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR
 
 
       for (OpcNode node : this.allNodes) {
-        this.allNodeIds.add(node.nodeId);
+        this.allNodeIds.add(node.getNodeId());
       }
 
-      if (spOpcUaClient.inPullMode()) {
-        this.pullingIntervalMilliSeconds = spOpcUaClient.getPullIntervalMilliSeconds();
+      if (spOpcUaClient.getSpOpcConfig().inPullMode()) {
+        this.pullingIntervalMilliSeconds = spOpcUaClient.getSpOpcConfig().getPullIntervalMilliSeconds();
       } else {
         this.numberProperties = this.allNodeIds.size();
         this.spOpcUaClient.createListSubscription(this.allNodeIds, this);
@@ -213,11 +201,13 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR
   public void onAdapterStarted(IAdapterParameterExtractor extractor,
                                IEventCollector collector,
                                IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {
-    this.spOpcUaClient = new SpOpcUaClient(SpOpcUaConfigBuilder.from(extractor.getStaticPropertyExtractor()));
+    this.spOpcUaClient = new SpOpcUaClient<>(
+        SpOpcUaConfigExtractor.extractAdapterConfig(extractor.getStaticPropertyExtractor())
+    );
     this.collector = collector;
     this.prepareAdapter(extractor);
 
-    if (this.spOpcUaClient.inPullMode()) {
+    if (this.spOpcUaClient.getSpOpcConfig().inPullMode()) {
       this.pullAdapterScheduler = new PullAdapterScheduler();
       this.pullAdapterScheduler.schedule(this, extractor.getAdapterDescription().getElementId());
     }
@@ -228,7 +218,7 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR
                                IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {
     this.spOpcUaClient.disconnect();
 
-    if (this.spOpcUaClient.inPullMode()) {
+    if (this.spOpcUaClient.getSpOpcConfig().inPullMode()) {
       this.pullAdapterScheduler.shutdown();
     }
   }
@@ -241,7 +231,7 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR
 
   @Override
   public IAdapterConfiguration declareConfig() {
-    return AdapterConfigurationBuilder.create(ID, OpcUaAdapter::new)
+    var builder = AdapterConfigurationBuilder.create(ID, OpcUaAdapter::new)
         .withAssets(Assets.DOCUMENTATION, Assets.ICON)
         .withLocales(Locales.EN)
         .withCategory(AdapterType.Generic, AdapterType.Manufacturing)
@@ -249,41 +239,9 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR
             Alternatives.from(Labels.withId(PULL_MODE),
                 StaticProperties.integerFreeTextProperty(
                     Labels.withId(PULLING_INTERVAL))),
-            Alternatives.from(Labels.withId(SUBSCRIPTION_MODE)))
-        .requiredAlternatives(Labels.withId(ACCESS_MODE),
-            Alternatives.from(Labels.withId(UNAUTHENTICATED)),
-            Alternatives.from(Labels.withId(USERNAME_GROUP),
-                StaticProperties.group(
-                    Labels.withId(USERNAME_GROUP),
-                    StaticProperties.stringFreeTextProperty(
-                        Labels.withId(USERNAME)),
-                    StaticProperties.secretValue(Labels.withId(PASSWORD))
-                ))
-        )
-        .requiredAlternatives(Labels.withId(OPC_HOST_OR_URL),
-            Alternatives.from(
-                Labels.withId(OPC_URL),
-                StaticProperties.stringFreeTextProperty(
-                    Labels.withId(OPC_SERVER_URL), "opc.tcp://localhost:4840"))
-            ,
-            Alternatives.from(Labels.withId(OPC_HOST),
-                StaticProperties.group(
-                    Labels.withId(HOST_PORT),
-                    StaticProperties.stringFreeTextProperty(
-                        Labels.withId(OPC_SERVER_HOST)),
-                    StaticProperties.stringFreeTextProperty(
-                        Labels.withId(OPC_SERVER_PORT))
-                ))
-        )
-        .requiredRuntimeResolvableTreeInput(
-            Labels.withId(AVAILABLE_NODES.name()),
-            List.of(
-                ADAPTER_TYPE.name(),
-                ACCESS_MODE.name(),
-                OPC_HOST_OR_URL.name()),
-            true
-        )
-        .buildConfiguration();
+            Alternatives.from(Labels.withId(SUBSCRIPTION_MODE)));
+    SharedUserConfiguration.appendSharedOpcUaConfig(builder, true);
+    return builder.buildConfiguration();
   }
 
 
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java
index 10456a8bbf..b9ef833c53 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java
@@ -18,8 +18,9 @@
 
 package org.apache.streampipes.extensions.connectors.opcua.adapter;
 
-import org.apache.streampipes.extensions.connectors.opcua.adapter.configuration.SpOpcUaConfig;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.utils.OpcUaTypes;
+import org.apache.streampipes.extensions.connectors.opcua.config.OpcUaConfig;
+import org.apache.streampipes.extensions.connectors.opcua.model.OpcNode;
+import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaTypes;
 import org.apache.streampipes.model.staticproperty.TreeInputNode;
 
 import org.eclipse.milo.opcua.sdk.client.AddressSpace;
@@ -27,8 +28,8 @@ import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
 import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
 import org.eclipse.milo.opcua.sdk.client.nodes.UaVariableNode;
 import org.eclipse.milo.opcua.stack.core.Identifiers;
+import org.eclipse.milo.opcua.stack.core.StatusCodes;
 import org.eclipse.milo.opcua.stack.core.UaException;
-import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
 import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
 import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
@@ -48,12 +49,12 @@ import java.util.stream.Collectors;
 public class OpcUaNodeBrowser {
 
   private final OpcUaClient client;
-  private final SpOpcUaConfig spOpcConfig;
+  private final OpcUaConfig spOpcConfig;
 
   private static final Logger LOG = LoggerFactory.getLogger(OpcUaNodeBrowser.class);
 
   public OpcUaNodeBrowser(OpcUaClient client,
-                          SpOpcUaConfig spOpcUaClientConfig) {
+                          OpcUaConfig spOpcUaClientConfig) {
     this.client = client;
     this.spOpcConfig = spOpcUaClientConfig;
   }
@@ -134,8 +135,16 @@ public class OpcUaNodeBrowser {
       metadata.put("Value", String.valueOf(((UaVariableNode) node).getValue().getValue().getValue()));
       try {
         var dataTypeNode = client.getAddressSpace().getNode(dataTypeNodeId);
+        var value = client.readValue(0, TimestampsToReturn.Both, node.getNodeId()).get();
+        metadata.put("SourceTime", value.getSourceTime().getJavaDate().toString());
+        metadata.put("ServerTime", value.getServerTime().getJavaDate().toString());
+        var statusCode = value.getStatusCode().getValue();
+        var statusCodeName = StatusCodes.lookup(statusCode).get();
+        if (statusCodeName.length > 0) {
+          metadata.put("Status", statusCodeName[0]);
+        }
         metadata.put("DataType", dataTypeNode.getDisplayName().getText());
-      } catch (UaException e) {
+      } catch (UaException | ExecutionException | InterruptedException e) {
         throw new RuntimeException(e);
       }
     }
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/configuration/SpOpcUaConfig.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/configuration/SpOpcUaConfig.java
deleted file mode 100644
index 2cfecea090..0000000000
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/configuration/SpOpcUaConfig.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.streampipes.extensions.connectors.opcua.adapter.configuration;
-
-import java.util.List;
-
-public class SpOpcUaConfig {
-
-  private final String opcServerURL;
-
-  private boolean unauthenticated;
-
-  private String username;
-  private String password;
-
-  private final List<String> selectedNodeNames;
-  private final Integer pullIntervalMilliSeconds;
-
-  /**
-   * Constructor for security level {@code None}, OPC server given by url and subscription-based
-   *
-   * @param opcServerURL             complete OPC UA server url
-   * @param pullIntervalMilliSeconds duration of pull interval in milliseconds, {@code null} if in subscription
-   *                                 mode
-   * @param selectedNodeNames        list of node names provided
-   */
-  public SpOpcUaConfig(String opcServerURL,
-                       Integer pullIntervalMilliSeconds,
-                       List<String> selectedNodeNames) {
-
-    this.opcServerURL = opcServerURL;
-    this.unauthenticated = true;
-    this.pullIntervalMilliSeconds = pullIntervalMilliSeconds;
-    this.selectedNodeNames = selectedNodeNames;
-  }
-
-  /**
-   * Constructor for security level {@code None} and OPC server given by hostname and port number
-   *
-   * @param opcServer                OPC UA hostname
-   * @param opcServerPort            OPC UA port number
-   * @param pullIntervalMilliSeconds duration of pull interval in milliseconds, {@code null} if in
-   *                                 subscription mode
-   * @param selectedNodeNames        list of node names provided
-   */
-  public SpOpcUaConfig(String opcServer,
-                       int opcServerPort,
-                       Integer pullIntervalMilliSeconds,
-                       List<String> selectedNodeNames) {
-    this(opcServer + ":" + opcServerPort, pullIntervalMilliSeconds, selectedNodeNames);
-  }
-
-  /**
-   * Constructor for security level {@code Sign} and OPC server given by url
-   *
-   * @param opcServerURL             complete OPC UA server url
-   * @param username                 username to authenticate at the OPC UA server
-   * @param password                 corresponding password to given user name
-   * @param pullIntervalMilliSeconds duration of pull interval in milliseconds,
-   *                                 {@code null} if in subscription mode
-   * @param selectedNodeNames        list of node names provided
-   */
-  public SpOpcUaConfig(String opcServerURL,
-                       String username,
-                       String password,
-                       Integer pullIntervalMilliSeconds,
-                       List<String> selectedNodeNames) {
-    this(opcServerURL, pullIntervalMilliSeconds, selectedNodeNames);
-    this.unauthenticated = false;
-    this.username = username;
-    this.password = password;
-  }
-
-  /**
-   * Constructor for OPC UA security level {@code Sign} and OPC server given by hostname and port number
-   *
-   * @param opcServer                OPC UA hostname
-   * @param opcServerPort            OPC UA port number
-   * @param username                 username to authenticate at the OPC UA server
-   * @param password                 corresponding password to given user name
-   * @param pullIntervalMilliSeconds duration of pull interval in milliseconds,
-   *                                 {@code null} if in subscription mode
-   * @param selectedNodeNames        list of node names provided
-   */
-  public SpOpcUaConfig(String opcServer,
-                       int opcServerPort,
-                       String username,
-                       String password,
-                       int pullIntervalMilliSeconds,
-                       List<String> selectedNodeNames) {
-    this(opcServer, opcServerPort, pullIntervalMilliSeconds, selectedNodeNames);
-    this.unauthenticated = false;
-    this.username = username;
-    this.password = password;
-  }
-
-  public String getOpcServerURL() {
-    return opcServerURL;
-  }
-
-  public boolean isUnauthenticated() {
-    return unauthenticated;
-  }
-
-  public void setUnauthenticated(boolean unauthenticated) {
-    this.unauthenticated = unauthenticated;
-  }
-
-  public String getUsername() {
-    return username;
-  }
-
-  public void setUsername(String username) {
-    this.username = username;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public void setPassword(String password) {
-    this.password = password;
-  }
-
-  public List<String> getSelectedNodeNames() {
-    return selectedNodeNames;
-  }
-
-  public Integer getPullIntervalMilliSeconds() {
-    return pullIntervalMilliSeconds;
-  }
-}
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/SpOpcUaClient.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/client/SpOpcUaClient.java
similarity index 89%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/SpOpcUaClient.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/client/SpOpcUaClient.java
index 755710e2ef..95fda81dbd 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/SpOpcUaClient.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/client/SpOpcUaClient.java
@@ -16,11 +16,13 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter;
+package org.apache.streampipes.extensions.connectors.opcua.client;
 
 
 import org.apache.streampipes.commons.exceptions.SpConfigurationException;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.configuration.SpOpcUaConfig;
+import org.apache.streampipes.extensions.connectors.opcua.adapter.OpcUaAdapter;
+import org.apache.streampipes.extensions.connectors.opcua.config.MiloOpcUaConfigurationProvider;
+import org.apache.streampipes.extensions.connectors.opcua.config.OpcUaConfig;
 
 import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
 import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
@@ -54,16 +56,16 @@ import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.
 /***
  * Wrapper class for all OPC UA specific stuff.
  */
-public class SpOpcUaClient {
+public class SpOpcUaClient<T extends OpcUaConfig> {
 
   private static final Logger LOG = LoggerFactory.getLogger(SpOpcUaClient.class);
 
   private OpcUaClient client;
-  private final SpOpcUaConfig spOpcConfig;
+  private final T spOpcConfig;
 
   private static final AtomicLong clientHandles = new AtomicLong(1L);
 
-  public SpOpcUaClient(SpOpcUaConfig config) {
+  public SpOpcUaClient(T config) {
     this.spOpcConfig = config;
   }
 
@@ -158,12 +160,8 @@ public class SpOpcUaClient {
       requests.add(new MonitoredItemCreateRequest(readValue, MonitoringMode.Reporting, parameters));
     }
 
-    UaSubscription.ItemCreationCallback onItemCreated = new UaSubscription.ItemCreationCallback() {
-      @Override
-      public void onItemCreated(UaMonitoredItem item, int i) {
-        item.setValueConsumer(opcUaAdapter::onSubscriptionValue);
-      }
-    };
+    UaSubscription.ItemCreationCallback onItemCreated =
+        (item, i) -> item.setValueConsumer(opcUaAdapter::onSubscriptionValue);
     List<UaMonitoredItem> items = subscription.createMonitoredItems(
         TimestampsToReturn.Both,
         requests,
@@ -180,15 +178,7 @@ public class SpOpcUaClient {
     }
   }
 
-  public boolean inPullMode() {
-    return !(spOpcConfig.getPullIntervalMilliSeconds() == null);
-  }
-
-  public int getPullIntervalMilliSeconds() {
-    return spOpcConfig.getPullIntervalMilliSeconds();
-  }
-
-  public SpOpcUaConfig getSpOpcConfig() {
+  public T getSpOpcConfig() {
     return spOpcConfig;
   }
 }
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/MiloOpcUaConfigurationProvider.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/MiloOpcUaConfigurationProvider.java
similarity index 92%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/MiloOpcUaConfigurationProvider.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/MiloOpcUaConfigurationProvider.java
index 00287d85a7..9813d52fbb 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/MiloOpcUaConfigurationProvider.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/MiloOpcUaConfigurationProvider.java
@@ -16,10 +16,9 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter;
+package org.apache.streampipes.extensions.connectors.opcua.config;
 
 import org.apache.streampipes.commons.exceptions.SpConfigurationException;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.configuration.SpOpcUaConfig;
 
 import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
 import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder;
@@ -37,7 +36,7 @@ import java.util.concurrent.ExecutionException;
 
 public class MiloOpcUaConfigurationProvider {
 
-  public OpcUaClientConfig makeClientConfig(SpOpcUaConfig spOpcConfig)
+  public OpcUaClientConfig makeClientConfig(OpcUaConfig spOpcConfig)
       throws ExecutionException, InterruptedException, SpConfigurationException, URISyntaxException {
     String opcServerUrl = spOpcConfig.getOpcServerURL();
     List<EndpointDescription> endpoints = DiscoveryClient.getEndpoints(opcServerUrl).get();
@@ -61,7 +60,7 @@ public class MiloOpcUaConfigurationProvider {
   }
 
   private OpcUaClientConfig buildConfig(EndpointDescription endpoint,
-                                        SpOpcUaConfig spOpcConfig) {
+                                        OpcUaConfig spOpcConfig) {
 
     OpcUaClientConfigBuilder builder = defaultBuilder(endpoint);
     if (!spOpcConfig.isUnauthenticated()) {
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/OpcUaAdapterConfig.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/OpcUaAdapterConfig.java
new file mode 100644
index 0000000000..c6736ff8c3
--- /dev/null
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/OpcUaAdapterConfig.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.extensions.connectors.opcua.config;
+
+public class OpcUaAdapterConfig extends OpcUaConfig {
+
+  private Integer pullIntervalMilliSeconds;
+
+  public Integer getPullIntervalMilliSeconds() {
+    return pullIntervalMilliSeconds;
+  }
+
+  public void setPullIntervalMilliSeconds(Integer pullIntervalMilliSeconds) {
+    this.pullIntervalMilliSeconds = pullIntervalMilliSeconds;
+  }
+
+  public boolean inPullMode() {
+    return pullIntervalMilliSeconds != null;
+  }
+}
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/OpcUaConfig.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/OpcUaConfig.java
new file mode 100644
index 0000000000..6db027d861
--- /dev/null
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/OpcUaConfig.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.extensions.connectors.opcua.config;
+
+import java.util.List;
+
+public class OpcUaConfig {
+
+  private String opcServerURL;
+  private boolean unauthenticated;
+  private String username;
+  private String password;
+  private List<String> selectedNodeNames;
+
+  public String getOpcServerURL() {
+    return opcServerURL;
+  }
+
+  public void setOpcServerURL(String opcServerURL) {
+    this.opcServerURL = opcServerURL;
+  }
+
+  public boolean isUnauthenticated() {
+    return unauthenticated;
+  }
+
+  public void setUnauthenticated(boolean unauthenticated) {
+    this.unauthenticated = unauthenticated;
+  }
+
+  public String getUsername() {
+    return username;
+  }
+
+  public void setUsername(String username) {
+    this.username = username;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public void setPassword(String password) {
+    this.password = password;
+  }
+
+  public List<String> getSelectedNodeNames() {
+    return selectedNodeNames;
+  }
+
+  public void setSelectedNodeNames(List<String> selectedNodeNames) {
+    this.selectedNodeNames = selectedNodeNames;
+  }
+}
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/SharedUserConfiguration.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/SharedUserConfiguration.java
new file mode 100644
index 0000000000..647e66fdb7
--- /dev/null
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/SharedUserConfiguration.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.extensions.connectors.opcua.config;
+
+import org.apache.streampipes.sdk.StaticProperties;
+import org.apache.streampipes.sdk.builder.AbstractConfigurablePipelineElementBuilder;
+import org.apache.streampipes.sdk.helpers.Alternatives;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+import java.util.List;
+
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.ACCESS_MODE;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.ADAPTER_TYPE;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.AVAILABLE_NODES;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.HOST_PORT;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_HOST;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_HOST_OR_URL;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_HOST;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_PORT;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_URL;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_URL;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.PASSWORD;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.UNAUTHENTICATED;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.USERNAME;
+import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.USERNAME_GROUP;
+
+public class SharedUserConfiguration {
+
+  public static void appendSharedOpcUaConfig(AbstractConfigurablePipelineElementBuilder<?, ?> builder,
+                                             boolean adapterConfig) {
+
+    var dependsOn = adapterConfig ? List.of(
+        ADAPTER_TYPE.name(),
+        ACCESS_MODE.name(),
+        OPC_HOST_OR_URL.name()
+    ) : List.of(
+        ACCESS_MODE.name(),
+        OPC_HOST_OR_URL.name());
+
+    builder
+        .requiredAlternatives(Labels.withId(ACCESS_MODE),
+            Alternatives.from(Labels.withId(UNAUTHENTICATED)),
+            Alternatives.from(Labels.withId(USERNAME_GROUP),
+                StaticProperties.group(
+                    Labels.withId(USERNAME_GROUP),
+                    StaticProperties.stringFreeTextProperty(
+                        Labels.withId(USERNAME)),
+                    StaticProperties.secretValue(Labels.withId(PASSWORD))
+                ))
+        )
+        .requiredAlternatives(Labels.withId(OPC_HOST_OR_URL),
+            Alternatives.from(
+                Labels.withId(OPC_URL),
+                StaticProperties.stringFreeTextProperty(
+                    Labels.withId(OPC_SERVER_URL), "opc.tcp://localhost:4840"))
+            ,
+            Alternatives.from(Labels.withId(OPC_HOST),
+                StaticProperties.group(
+                    Labels.withId(HOST_PORT),
+                    StaticProperties.stringFreeTextProperty(
+                        Labels.withId(OPC_SERVER_HOST)),
+                    StaticProperties.stringFreeTextProperty(
+                        Labels.withId(OPC_SERVER_PORT))
+                ))
+        )
+        .requiredRuntimeResolvableTreeInput(
+            Labels.withId(AVAILABLE_NODES.name()),
+            dependsOn,
+            true,
+            adapterConfig
+        );
+  }
+}
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/configuration/SpOpcUaConfigBuilder.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/SpOpcUaConfigExtractor.java
similarity index 63%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/configuration/SpOpcUaConfigBuilder.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/SpOpcUaConfigExtractor.java
index 7d8cbd97ed..4f461c9774 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/configuration/SpOpcUaConfigBuilder.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/config/SpOpcUaConfigExtractor.java
@@ -16,10 +16,11 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter.configuration;
+package org.apache.streampipes.extensions.connectors.opcua.config;
 
+import org.apache.streampipes.extensions.api.extractor.IParameterExtractor;
 import org.apache.streampipes.extensions.api.extractor.IStaticPropertyExtractor;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.utils.OpcUaUtil;
+import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaUtil;
 
 import java.util.List;
 
@@ -27,8 +28,6 @@ import static org.apache.kafka.common.config.ConfigDef.Type.PASSWORD;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.ACCESS_MODE;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.ADAPTER_TYPE;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.AVAILABLE_NODES;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.NAMESPACE_INDEX;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.NODE_ID;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_HOST_OR_URL;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_HOST;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_PORT;
@@ -39,84 +38,72 @@ import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabe
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.UNAUTHENTICATED;
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.USERNAME;
 
-public class SpOpcUaConfigBuilder {
+public class SpOpcUaConfigExtractor {
 
   /**
-   * Creates {@link SpOpcUaConfig}  instance in accordance with the given
+   * Creates {@link OpcUaAdapterConfig}  instance in accordance with the given
    * {@link org.apache.streampipes.sdk.extractor.StaticPropertyExtractor}.
    *
    * @param extractor extractor for user inputs
-   * @return {@link SpOpcUaConfig}  instance based on information from {@code extractor}
+   * @return {@link OpcUaAdapterConfig}  instance based on information from {@code extractor}
    */
-  public static SpOpcUaConfig from(IStaticPropertyExtractor extractor) {
-
-    String selectedAlternativeConnection =
-        extractor.selectedAlternativeInternalId(OPC_HOST_OR_URL.name());
-    String selectedAlternativeAuthentication =
-        extractor.selectedAlternativeInternalId(ACCESS_MODE.name());
-
+  public static OpcUaAdapterConfig extractAdapterConfig(IStaticPropertyExtractor extractor) {
+    var config = extractSharedConfig(extractor, new OpcUaAdapterConfig());
     boolean usePullMode = extractor.selectedAlternativeInternalId(ADAPTER_TYPE.name())
         .equals(PULL_MODE.name());
-    boolean useURL = selectedAlternativeConnection.equals(OPC_URL.name());
-    boolean unauthenticated = selectedAlternativeAuthentication.equals(UNAUTHENTICATED.name());
 
-    Integer pullIntervalSeconds = null;
     if (usePullMode) {
-      pullIntervalSeconds =
+      Integer pullIntervalSeconds =
           extractor.singleValueParameter(PULLING_INTERVAL.name(), Integer.class);
+
+      config.setPullIntervalMilliSeconds(pullIntervalSeconds);
     }
 
+    return config;
+  }
+
+  public static OpcUaConfig extractSinkConfig(IParameterExtractor<?> extractor) {
+    return extractSharedConfig(extractor, new OpcUaConfig());
+  }
+
+  public static <T extends OpcUaConfig> T extractSharedConfig(IParameterExtractor<?> extractor,
+                                                               T config) {
+
+    String selectedAlternativeConnection =
+        extractor.selectedAlternativeInternalId(OPC_HOST_OR_URL.name());
+    String selectedAlternativeAuthentication =
+        extractor.selectedAlternativeInternalId(ACCESS_MODE.name());
     List<String> selectedNodeNames =
         extractor.selectedTreeNodesInternalNames(AVAILABLE_NODES.name(), String.class, true);
 
-    if (useURL && unauthenticated) {
-
-      String serverAddress =
-          extractor.singleValueParameter(OPC_SERVER_URL.name(), String.class);
-      serverAddress = OpcUaUtil.formatServerAddress(serverAddress);
+    config.setSelectedNodeNames(selectedNodeNames);
 
-      return new SpOpcUaConfig(serverAddress,
-          pullIntervalSeconds,
-          selectedNodeNames);
+    boolean useURL = selectedAlternativeConnection.equals(OPC_URL.name());
+    boolean unauthenticated = selectedAlternativeAuthentication.equals(UNAUTHENTICATED.name());
 
-    } else if (!useURL && unauthenticated) {
+    if (useURL) {
       String serverAddress =
-          extractor.singleValueParameter(OPC_SERVER_HOST.name(), String.class);
-      serverAddress = OpcUaUtil.formatServerAddress(serverAddress);
+          extractor.singleValueParameter(OPC_SERVER_URL.name(), String.class);
+      config.setOpcServerURL(OpcUaUtil.formatServerAddress(serverAddress));
+    } else {
+      String serverAddress = OpcUaUtil.formatServerAddress(
+          extractor.singleValueParameter(OPC_SERVER_HOST.name(), String.class)
+      );
       int port = extractor.singleValueParameter(OPC_SERVER_PORT.name(), int.class);
+      config.setOpcServerURL(serverAddress + ":" + port);
+    }
 
-      return new SpOpcUaConfig(serverAddress,
-          port,
-          pullIntervalSeconds,
-          selectedNodeNames);
+    if (unauthenticated) {
+      config.setUnauthenticated(true);
     } else {
-
       String username = extractor.singleValueParameter(USERNAME.name(), String.class);
       String password = extractor.secretValue(PASSWORD.name());
 
-      if (useURL) {
-        String serverAddress =
-            extractor.singleValueParameter(OPC_SERVER_URL.name(), String.class);
-        serverAddress = OpcUaUtil.formatServerAddress(serverAddress);
-
-        return new SpOpcUaConfig(serverAddress,
-            username,
-            password,
-            pullIntervalSeconds,
-            selectedNodeNames);
-      } else {
-        String serverAddress =
-            extractor.singleValueParameter(OPC_SERVER_HOST.name(), String.class);
-        serverAddress = OpcUaUtil.formatServerAddress(serverAddress);
-        int port = extractor.singleValueParameter(OPC_SERVER_PORT.name(), int.class);
-
-        return new SpOpcUaConfig(serverAddress,
-            port,
-            username,
-            password,
-            pullIntervalSeconds,
-            selectedNodeNames);
-      }
+      config.setUsername(username);
+      config.setPassword(password);
+      config.setUnauthenticated(false);
     }
+
+    return config;
   }
 }
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcNode.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcNode.java
similarity index 98%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcNode.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcNode.java
index 36b400e513..f27b3321ff 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcNode.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcNode.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter;
+package org.apache.streampipes.extensions.connectors.opcua.model;
 
 import org.apache.streampipes.sdk.utils.Datatypes;
 
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUa.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUa.java
index 870ae02b87..78babe0027 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUa.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUa.java
@@ -19,27 +19,22 @@
 package org.apache.streampipes.extensions.connectors.opcua.sink;
 
 import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.extensions.connectors.opcua.client.SpOpcUaClient;
 import org.apache.streampipes.model.runtime.Event;
 import org.apache.streampipes.model.runtime.field.PrimitiveField;
 import org.apache.streampipes.vocabulary.XSD;
 
 import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
-import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
-import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
 import org.eclipse.milo.opcua.stack.core.UaException;
-import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
 import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
-import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
 import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
 import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
-import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
@@ -49,13 +44,14 @@ public class OpcUa {
 
   private OpcUaClient opcUaClient;
   private OpcUaParameters params;
-  private String serverUrl;
+
   private NodeId node;
-  private Class targetDataType;
-  private Class sourceDataType;
+
+  private Class<?> targetDataType;
+  private Class<?> sourceDataType;
 
   // define a mapping of StreamPipes data types to Java classes
-  private static final HashMap<String, Class> XSDMatchings = new HashMap<>();
+  private static final HashMap<String, Class<?>> XSDMatchings = new HashMap<>();
 
   static {
     XSDMatchings.put(XSD.DOUBLE.toString(), Double.class);
@@ -67,7 +63,7 @@ public class OpcUa {
   }
 
   // define potential mappings, left can be mapped to right
-  private static HashMap<Class, Class[]> compatibleDataTypes = new HashMap<>();
+  private static final HashMap<Class<?>, Class<?>[]> compatibleDataTypes = new HashMap<>();
 
   static {
     compatibleDataTypes.put(Double.class, new Class[]{Float.class, String.class});
@@ -77,55 +73,26 @@ public class OpcUa {
     compatibleDataTypes.put(String.class, new Class[]{String.class});
   }
 
-  public void onInvocation(OpcUaParameters parameters) throws
+  public void onInvocation(OpcUaParameters params) throws
       SpRuntimeException {
 
-    if (!parameters.hostname().startsWith("opc.tcp://")) {
-      serverUrl = "opc.tcp://" + parameters.hostname() + ":" + parameters.port();
-    } else {
-      serverUrl = parameters.hostname() + ":" + parameters.port();
-    }
-    if (isInteger(parameters.nodeId())) {
-      int integerNodeId = Integer.parseInt(parameters.nodeId());
-      node = new NodeId(parameters.nameSpaceIndex(), integerNodeId);
-    } else {
-      node = new NodeId(parameters.nameSpaceIndex(), parameters.nodeId());
-    }
-
-
-    this.params = parameters;
-
-    List<EndpointDescription> endpoints;
-
     try {
-
-      endpoints = DiscoveryClient.getEndpoints(serverUrl).get();
-
-      EndpointDescription endpoint = endpoints
-          .stream()
-          .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
-          .findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
-
-      OpcUaClientConfig config = OpcUaClientConfig.builder()
-          .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
-          .setApplicationUri("urn:eclipse:milo:examples:client")
-          .setEndpoint(endpoint)
-          .build();
-
-      opcUaClient = OpcUaClient.create(config);
+      this.params = params;
+      this.node = NodeId.parse(params.getSelectedNode());
+      opcUaClient = new SpOpcUaClient<>(params.getConfig()).getClient();
       opcUaClient.connect().get();
 
     } catch (Exception e) {
-      throw new SpRuntimeException("Could not connect to OPC-UA server: " + serverUrl);
+      throw new SpRuntimeException("Could not connect to OPC-UA server: " + params.getConfig().getOpcServerURL());
     }
 
     // check whether input data type and target data type are compatible
     try {
       Variant value = opcUaClient.getAddressSpace().getVariableNode(node).readValue().getValue();
       targetDataType = value.getValue().getClass();
-      sourceDataType = XSDMatchings.get(params.mappingPropertyType());
+      sourceDataType = XSDMatchings.get(params.getMappingPropertyType());
       if (!sourceDataType.equals(targetDataType)) {
-        if (!Arrays.stream(compatibleDataTypes.get(sourceDataType)).anyMatch(dt -> dt.equals(targetDataType))) {
+        if (Arrays.stream(compatibleDataTypes.get(sourceDataType)).noneMatch(dt -> dt.equals(targetDataType))) {
           throw new SpRuntimeException("Data Type of event of target node are not compatible");
         }
       }
@@ -140,7 +107,7 @@ public class OpcUa {
     Variant v = getValue(inputEvent);
 
     if (v == null) {
-      LOG.error("Mapping property type: " + this.params.mappingPropertyType() + " is not supported");
+      LOG.error("Mapping property type: " + this.params.getMappingPropertyType() + " is not supported");
     } else {
 
       DataValue value = new DataValue(v);
@@ -150,18 +117,18 @@ public class OpcUa {
         StatusCode status = f.get();
         if (status.isBad()) {
           if (status.getValue() == 0x80740000L) {
-            LOG.error("Type missmatch! Tried to write value of type: " + this.params.mappingPropertyType()
+            LOG.error("Type missmatch! Tried to write value of type: " + this.params.getMappingPropertyType()
                 + " but server did not accept this");
           } else if (status.getValue() == 0x803B0000L) {
             LOG.error("Wrong access level. Not allowed to write to nodes");
           }
           LOG.error(
               "Value: " + value.getValue().toString() + " could not be written to node Id: "
-                  + this.params.nodeId() + " on " + "OPC-UA server: " + this.serverUrl);
+                  + node.getIdentifier() + " on " + "OPC-UA server: " + params.getConfig().getOpcServerURL());
         }
       } catch (InterruptedException | ExecutionException e) {
         LOG.error("Exception: Value: " + value.getValue().toString() + " could not be written to node Id: "
-            + this.params.nodeId() + " on " + "OPC-UA server: " + this.serverUrl);
+            + node.getIdentifier() + " on " + "OPC-UA server: " + params.getConfig().getOpcServerURL());
       }
     }
   }
@@ -173,7 +140,7 @@ public class OpcUa {
   private Variant getValue(Event inputEvent) {
     Variant result = null;
     PrimitiveField propertyPrimitive =
-        inputEvent.getFieldBySelector(this.params.mappingPropertySelector()).getAsPrimitive();
+        inputEvent.getFieldBySelector(this.params.getMappingPropertySelector()).getAsPrimitive();
 
     if (targetDataType.equals(Integer.class)) {
       result = new Variant(propertyPrimitive.getAsInt());
@@ -189,16 +156,4 @@ public class OpcUa {
 
     return result;
   }
-
-  public static boolean isInteger(String s) {
-    try {
-      Integer.parseInt(s);
-    } catch (NumberFormatException e) {
-      return false;
-    } catch (NullPointerException e) {
-      return false;
-    }
-    // only got here if we didn't return false
-    return true;
-  }
 }
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaParameters.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaParameters.java
index 0a0f45ea2f..15906af4aa 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaParameters.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaParameters.java
@@ -18,45 +18,38 @@
 
 package org.apache.streampipes.extensions.connectors.opcua.sink;
 
+import org.apache.streampipes.extensions.connectors.opcua.config.OpcUaConfig;
+
 public final class OpcUaParameters {
-  private final String hostname;
-  private final Integer port;
-  private final String nodeId;
-  private final Integer nameSpaceIndex;
+  private final String selectedNode;
   private final String mappingPropertySelector;
   private final String mappingPropertyType;
 
-  public OpcUaParameters(String hostname, Integer port, String nodeId, Integer nameSpaceIndex,
-                         String mappingPropertySelector, String mappingPropertyType) {
-    this.hostname = hostname;
-    this.port = port;
-    this.nodeId = nodeId;
-    this.nameSpaceIndex = nameSpaceIndex;
+  private final OpcUaConfig config;
+
+  public OpcUaParameters(OpcUaConfig config,
+                         String mappingPropertySelector,
+                         String mappingPropertyType,
+                         String selectedNode) {
+    this.config = config;
     this.mappingPropertySelector = mappingPropertySelector;
     this.mappingPropertyType = mappingPropertyType;
+    this.selectedNode = selectedNode;
   }
 
-  public String hostname() {
-    return hostname;
-  }
-
-  public Integer port() {
-    return port;
-  }
-
-  public String nodeId() {
-    return nodeId;
-  }
-
-  public Integer nameSpaceIndex() {
-    return nameSpaceIndex;
+  public String getSelectedNode() {
+    return selectedNode;
   }
 
-  public String mappingPropertySelector() {
+  public String getMappingPropertySelector() {
     return mappingPropertySelector;
   }
 
-  public String mappingPropertyType() {
+  public String getMappingPropertyType() {
     return mappingPropertyType;
   }
+
+  public OpcUaConfig getConfig() {
+    return config;
+  }
 }
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaSink.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaSink.java
index 8532172b9f..c58c8cab02 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaSink.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/sink/OpcUaSink.java
@@ -18,14 +18,21 @@
 
 package org.apache.streampipes.extensions.connectors.opcua.sink;
 
+import org.apache.streampipes.commons.exceptions.SpConfigurationException;
 import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.extensions.api.extractor.IStaticPropertyExtractor;
 import org.apache.streampipes.extensions.api.pe.IStreamPipesDataSink;
 import org.apache.streampipes.extensions.api.pe.config.IDataSinkConfiguration;
 import org.apache.streampipes.extensions.api.pe.context.EventSinkRuntimeContext;
 import org.apache.streampipes.extensions.api.pe.param.IDataSinkParameters;
+import org.apache.streampipes.extensions.api.runtime.SupportsRuntimeConfig;
+import org.apache.streampipes.extensions.connectors.opcua.config.SharedUserConfiguration;
+import org.apache.streampipes.extensions.connectors.opcua.config.SpOpcUaConfigExtractor;
+import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaUtil;
 import org.apache.streampipes.model.DataSinkType;
 import org.apache.streampipes.model.runtime.Event;
 import org.apache.streampipes.model.schema.PropertyScope;
+import org.apache.streampipes.model.staticproperty.StaticProperty;
 import org.apache.streampipes.sdk.builder.DataSinkBuilder;
 import org.apache.streampipes.sdk.builder.StreamRequirementsBuilder;
 import org.apache.streampipes.sdk.builder.sink.DataSinkConfiguration;
@@ -35,33 +42,28 @@ import org.apache.streampipes.sdk.helpers.Locales;
 import org.apache.streampipes.sdk.utils.Assets;
 
 import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.MAPPING_PROPERY;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.NAMESPACE_INDEX;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.NODE_ID;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_HOST;
-import static org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels.OPC_SERVER_PORT;
 
-public class OpcUaSink implements IStreamPipesDataSink {
+public class OpcUaSink implements IStreamPipesDataSink, SupportsRuntimeConfig {
 
   private OpcUa opcUa;
 
   @Override
   public IDataSinkConfiguration declareConfig() {
+    var builder = DataSinkBuilder.create("org.apache.streampipes.sinks.databases.jvm.opcua")
+        .withLocales(Locales.EN)
+        .withAssets(Assets.DOCUMENTATION, Assets.ICON)
+        .category(DataSinkType.FORWARD)
+        .requiredStream(StreamRequirementsBuilder
+            .create()
+            .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(),
+                Labels.withId(MAPPING_PROPERY),
+                PropertyScope.NONE).build());
+
+    SharedUserConfiguration.appendSharedOpcUaConfig(builder, false);
+
     return DataSinkConfiguration.create(
         OpcUaSink::new,
-        DataSinkBuilder.create("org.apache.streampipes.sinks.databases.jvm.opcua")
-            .withLocales(Locales.EN)
-            .withAssets(Assets.DOCUMENTATION, Assets.ICON)
-            .category(DataSinkType.FORWARD)
-            .requiredStream(StreamRequirementsBuilder
-                .create()
-                .requiredPropertyWithUnaryMapping(EpRequirements.anyProperty(),
-                    Labels.withId(MAPPING_PROPERY),
-                    PropertyScope.NONE).build())
-            .requiredTextParameter(Labels.withId(OPC_SERVER_HOST))
-            .requiredIntegerParameter(Labels.withId(OPC_SERVER_PORT))
-            .requiredIntegerParameter(Labels.withId(NAMESPACE_INDEX))
-            .requiredTextParameter(Labels.withId(NODE_ID))
-            .build()
+        builder.build()
     );
   }
 
@@ -69,13 +71,9 @@ public class OpcUaSink implements IStreamPipesDataSink {
   public void onPipelineStarted(IDataSinkParameters parameters,
                                 EventSinkRuntimeContext runtimeContext) {
     var extractor = parameters.extractor();
-    String hostname = extractor.singleValueParameter(OPC_SERVER_HOST.name(), String.class);
-    Integer port = extractor.singleValueParameter(OPC_SERVER_PORT.name(), Integer.class);
+    var config = SpOpcUaConfigExtractor.extractSinkConfig(extractor);
 
-    String nodeId = extractor.singleValueParameter(NODE_ID.name(), String.class);
-    Integer nameSpaceIndex = extractor.singleValueParameter(NAMESPACE_INDEX.name(), Integer.class);
-
-    String mappingPropertySelector = extractor.mappingPropertyValue(NODE_ID.name());
+    String mappingPropertySelector = extractor.mappingPropertyValue(MAPPING_PROPERY.name());
 
     String mappingPropertyType = "";
     try {
@@ -84,8 +82,12 @@ public class OpcUaSink implements IStreamPipesDataSink {
       e.printStackTrace();
     }
 
-    OpcUaParameters params = new OpcUaParameters(hostname, port, nodeId, nameSpaceIndex,
-        mappingPropertySelector, mappingPropertyType);
+    OpcUaParameters params = new OpcUaParameters(
+        config,
+        mappingPropertySelector,
+        mappingPropertyType,
+        config.getSelectedNodeNames().get(0)
+    );
 
     this.opcUa = new OpcUa();
     this.opcUa.onInvocation(params);
@@ -100,4 +102,10 @@ public class OpcUaSink implements IStreamPipesDataSink {
   public void onPipelineStopped() {
     this.opcUa.onDetach();
   }
+
+  @Override
+  public StaticProperty resolveConfiguration(String staticPropertyInternalName,
+                                             IStaticPropertyExtractor extractor) throws SpConfigurationException {
+    return OpcUaUtil.resolveConfiguration(staticPropertyInternalName, extractor);
+  }
 }
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/ExceptionMessageExtractor.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/ExceptionMessageExtractor.java
similarity index 94%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/ExceptionMessageExtractor.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/ExceptionMessageExtractor.java
index df0dfae8ca..9c37b09017 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/ExceptionMessageExtractor.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/ExceptionMessageExtractor.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter.utils;
+package org.apache.streampipes.extensions.connectors.opcua.utils;
 
 import org.eclipse.milo.opcua.stack.core.UaException;
 
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaTypes.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/OpcUaTypes.java
similarity index 96%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaTypes.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/OpcUaTypes.java
index 956191c674..46692e96ef 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaTypes.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/OpcUaTypes.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter.utils;
+package org.apache.streampipes.extensions.connectors.opcua.utils;
 
 import org.apache.streampipes.sdk.utils.Datatypes;
 
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaUtil.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/OpcUaUtil.java
similarity index 92%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaUtil.java
rename to streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/OpcUaUtil.java
index 32c31ce6a2..9acd311903 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaUtil.java
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/utils/OpcUaUtil.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter.utils;
+package org.apache.streampipes.extensions.connectors.opcua.utils;
 
 import org.apache.streampipes.commons.exceptions.SpConfigurationException;
 import org.apache.streampipes.commons.exceptions.connect.AdapterException;
@@ -24,11 +24,11 @@ import org.apache.streampipes.commons.exceptions.connect.ParseException;
 import org.apache.streampipes.extensions.api.extractor.IAdapterParameterExtractor;
 import org.apache.streampipes.extensions.api.extractor.IStaticPropertyExtractor;
 import org.apache.streampipes.extensions.api.runtime.ResolvesContainerProvidedOptions;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.OpcNode;
 import org.apache.streampipes.extensions.connectors.opcua.adapter.OpcUaNodeBrowser;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.SpOpcUaClient;
-import org.apache.streampipes.extensions.connectors.opcua.adapter.configuration.SpOpcUaConfigBuilder;
-import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaLabels;
+import org.apache.streampipes.extensions.connectors.opcua.client.SpOpcUaClient;
+import org.apache.streampipes.extensions.connectors.opcua.config.OpcUaConfig;
+import org.apache.streampipes.extensions.connectors.opcua.config.SpOpcUaConfigExtractor;
+import org.apache.streampipes.extensions.connectors.opcua.model.OpcNode;
 import org.apache.streampipes.model.connect.guess.FieldStatusInfo;
 import org.apache.streampipes.model.connect.guess.GuessSchema;
 import org.apache.streampipes.model.connect.guess.GuessTypeInfo;
@@ -89,7 +89,9 @@ public class OpcUaUtil {
     Map<String, FieldStatusInfo> fieldStatusInfos = new HashMap<>();
     List<EventProperty> allProperties = new ArrayList<>();
 
-    SpOpcUaClient spOpcUaClient = new SpOpcUaClient(SpOpcUaConfigBuilder.from(extractor.getStaticPropertyExtractor()));
+    SpOpcUaClient<OpcUaConfig> spOpcUaClient = new SpOpcUaClient<>(
+        SpOpcUaConfigExtractor.extractSharedConfig(extractor.getStaticPropertyExtractor(), new OpcUaConfig())
+    );
 
     try {
       spOpcUaClient.connect();
@@ -181,7 +183,9 @@ public class OpcUaUtil {
       return config;
     }
 
-    SpOpcUaClient spOpcUaClient = new SpOpcUaClient(SpOpcUaConfigBuilder.from(parameterExtractor));
+    SpOpcUaClient spOpcUaClient = new SpOpcUaClient(
+        SpOpcUaConfigExtractor.extractSharedConfig(parameterExtractor, new OpcUaConfig())
+    );
 
     try {
       spOpcUaClient.connect();
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/resources/org.apache.streampipes.sinks.databases.jvm.opcua/strings.en b/streampipes-extensions/streampipes-connectors-opcua/src/main/resources/org.apache.streampipes.sinks.databases.jvm.opcua/strings.en
index 4df4e75981..7e78d16a1a 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/resources/org.apache.streampipes.sinks.databases.jvm.opcua/strings.en
+++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/resources/org.apache.streampipes.sinks.databases.jvm.opcua/strings.en
@@ -18,17 +18,41 @@
 org.apache.streampipes.sinks.databases.jvm.opcua.title=OPC-UA
 org.apache.streampipes.sinks.databases.jvm.opcua.description=Writes values in an OPC-UA server
 
-OPC_SERVER_HOST.title=Host Address
-OPC_SERVER_HOST.description=The host address of the OPC-UA server (Example: opc-ua-server.com, opc.tcp://opc-ua-server.com)
+OPC_HOST_OR_URL.title=OPC Server
+OPC_HOST_OR_URL.description=
+
+OPC_URL.title=URL
+OPC_URL.description=
+
+OPC_HOST.title=Host/Port
+OPC_HOST.description=
+
+OPC_SERVER_URL.title=URL
+OPC_SERVER_URL.description=Example: opc.tcp://test-server.com:4840,
+
+OPC_SERVER_HOST.title=Host
+OPC_SERVER_HOST.description=Example: test-server.com, opc.tcp://test-server.com)
 
 OPC_SERVER_PORT.title=Port
-OPC_SERVER_PORT.description=The port of the OPC-UA server (Example: 4840)
+OPC_SERVER_PORT.description=Example: 4840
+
+ACCESS_MODE.title=Security Level
+ACCESS_MODE.description=Select the OPC UA security level for the connection
+
+USERNAME_GROUP.title=Sign (username & password)
+USERNAME_GROUP.description=
+
+UNAUTHENTICATED.title=None
+UNAUTHENTICATED.description=
+
+USERNAME.title=Username
+USERNAME.description=
 
-NAMESPACE_INDEX.title=Namespace Index
-NAMESPACE_INDEX.description=The number of the namespace
+PASSWORD.title=Password
+PASSWORD.description=
 
-NODE_ID.title=Node Id
-NODE_ID.description=Id of the node the result should be written to
+AVAILABLE_NODES.title=Available Nodes
+AVAILABLE_NODES.description=Select the nodes that are relevant for you. Please ensure to select one option each for access mode and OPC UA server and to specify the polling interval
 
-MAPPING_PROPERY.title=Event Property
-MAPPING_PROPERY.description=The event property that should be written to the OPC-UA server
+MAPPING_PROPERY.title=Field to write
+MAPPING_PROPERY.description=The field that should be written to the OPC-UA server
diff --git a/streampipes-extensions/streampipes-extensions-all-iiot/pom.xml b/streampipes-extensions/streampipes-extensions-all-iiot/pom.xml
index da6eef37a3..5d3435e600 100644
--- a/streampipes-extensions/streampipes-extensions-all-iiot/pom.xml
+++ b/streampipes-extensions/streampipes-extensions-all-iiot/pom.xml
@@ -125,6 +125,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
diff --git a/streampipes-extensions/streampipes-extensions-all-jvm/pom.xml b/streampipes-extensions/streampipes-extensions-all-jvm/pom.xml
index f4e9e31b26..3a057237cc 100644
--- a/streampipes-extensions/streampipes-extensions-all-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-extensions-all-jvm/pom.xml
@@ -81,6 +81,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
diff --git a/streampipes-extensions/streampipes-pipeline-elements-all-jvm/pom.xml b/streampipes-extensions/streampipes-pipeline-elements-all-jvm/pom.xml
index be12e3320f..66f0d7d74a 100644
--- a/streampipes-extensions/streampipes-pipeline-elements-all-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-pipeline-elements-all-jvm/pom.xml
@@ -124,6 +124,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConfig.java b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConfig.java
index 16eb4016d8..7e1cfecaf4 100644
--- a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConfig.java
+++ b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConfig.java
@@ -18,6 +18,7 @@
 
 package org.apache.streampipes.pe.shared.config.kafka;
 
+import org.apache.streampipes.messaging.kafka.config.AutoOffsetResetConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecurityConfig;
 
 public class KafkaConfig {
@@ -27,16 +28,18 @@ public class KafkaConfig {
   private String topic;
 
   KafkaSecurityConfig securityConfig;
-
+  AutoOffsetResetConfig autoOffsetResetConfig;
 
   public KafkaConfig(String kafkaHost,
                      Integer kafkaPort,
                      String topic,
-                     KafkaSecurityConfig securityConfig) {
+                     KafkaSecurityConfig securityConfig,
+                     AutoOffsetResetConfig autoOffsetResetConfig) {
     this.kafkaHost = kafkaHost;
     this.kafkaPort = kafkaPort;
     this.topic = topic;
     this.securityConfig = securityConfig;
+    this.autoOffsetResetConfig = autoOffsetResetConfig;
   }
 
   public String getKafkaHost() {
@@ -71,4 +74,12 @@ public class KafkaConfig {
     this.securityConfig = securityConfig;
   }
 
+  public void setAutoOffsetResetConfig(AutoOffsetResetConfig autoOffsetResetConfig) {
+    this.autoOffsetResetConfig = autoOffsetResetConfig;
+  }
+
+  public AutoOffsetResetConfig getAutoOffsetResetConfig() {
+    return autoOffsetResetConfig;
+  }
+
 }
diff --git a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConnectUtils.java b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConnectUtils.java
index 124c1c6e82..7cc3f24306 100644
--- a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConnectUtils.java
+++ b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/KafkaConnectUtils.java
@@ -18,6 +18,9 @@
 
 package org.apache.streampipes.pe.shared.config.kafka;
 
+
+
+import org.apache.streampipes.messaging.kafka.config.AutoOffsetResetConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecurityConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecuritySaslPlainConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecuritySaslSSLConfig;
@@ -30,6 +33,8 @@ import org.apache.streampipes.sdk.helpers.Alternatives;
 import org.apache.streampipes.sdk.helpers.Label;
 import org.apache.streampipes.sdk.helpers.Labels;
 
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+
 public class KafkaConnectUtils {
 
   public static final String TOPIC_KEY = "topic";
@@ -49,6 +54,11 @@ public class KafkaConnectUtils {
 
   private static final String HIDE_INTERNAL_TOPICS = "hide-internal-topics";
 
+  public static final String AUTO_OFFSET_RESET_CONFIG = ConsumerConfig.AUTO_OFFSET_RESET_CONFIG;
+  public static final String EARLIEST = "earliest";
+  public static final String LATEST = "latest";
+  public static final String NONE = "none";
+
   public static Label getTopicLabel() {
     return Labels.withId(TOPIC_KEY);
   }
@@ -73,6 +83,10 @@ public class KafkaConnectUtils {
     return Labels.withId(ACCESS_MODE);
   }
 
+  public static Label getAutoOffsetResetConfigLabel() {
+    return Labels.withId(AUTO_OFFSET_RESET_CONFIG);
+  }
+
   public static KafkaConfig getConfig(StaticPropertyExtractor extractor, boolean containsTopic) {
     String brokerUrl = extractor.singleValueParameter(HOST_KEY, String.class);
     String topic = "";
@@ -102,7 +116,10 @@ public class KafkaConnectUtils {
           new KafkaSecurityUnauthenticatedPlainConfig();
     }
 
-    return new KafkaConfig(brokerUrl, port, topic, securityConfig);
+    String auto = extractor.selectedAlternativeInternalId(AUTO_OFFSET_RESET_CONFIG);
+    AutoOffsetResetConfig autoOffsetResetConfig = new AutoOffsetResetConfig(auto);
+
+    return new KafkaConfig(brokerUrl, port, topic, securityConfig, autoOffsetResetConfig);
   }
 
   private static boolean isUseSSL(String authentication) {
@@ -136,4 +153,17 @@ public class KafkaConnectUtils {
             StaticProperties.stringFreeTextProperty(Labels.withId(KafkaConnectUtils.USERNAME_KEY)),
             StaticProperties.secretValue(Labels.withId(KafkaConnectUtils.PASSWORD_KEY))));
   }
+
+
+  public static StaticPropertyAlternative getAlternativesLatest() {
+    return Alternatives.from(Labels.withId(LATEST));
+  }
+
+  public static StaticPropertyAlternative getAlternativesEarliest() {
+    return Alternatives.from(Labels.withId(EARLIEST));
+  }
+
+  public static StaticPropertyAlternative getAlternativesNone() {
+    return Alternatives.from(Labels.withId(NONE));
+  }
 }
diff --git a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConfig.java b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConfig.java
index 1a66e0fa14..61c83c2a10 100644
--- a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConfig.java
+++ b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConfig.java
@@ -18,6 +18,7 @@
 
 package org.apache.streampipes.pe.shared.config.kafka.kafka;
 
+import org.apache.streampipes.messaging.kafka.config.AutoOffsetResetConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecurityConfig;
 
 public class KafkaConfig {
@@ -27,15 +28,18 @@ public class KafkaConfig {
   private String topic;
 
   KafkaSecurityConfig securityConfig;
+  AutoOffsetResetConfig autoOffsetResetConfig;
 
   public KafkaConfig(String kafkaHost,
                      Integer kafkaPort,
                      String topic,
-                     KafkaSecurityConfig securityConfig) {
+                     KafkaSecurityConfig securityConfig,
+                     AutoOffsetResetConfig autoOffsetResetConfig) {
     this.kafkaHost = kafkaHost;
     this.kafkaPort = kafkaPort;
     this.topic = topic;
     this.securityConfig = securityConfig;
+    this.autoOffsetResetConfig = autoOffsetResetConfig;
   }
 
   public String getKafkaHost() {
@@ -70,4 +74,11 @@ public class KafkaConfig {
     this.securityConfig = securityConfig;
   }
 
+  public AutoOffsetResetConfig getAutoOffsetResetConfig() {
+    return autoOffsetResetConfig;
+  }
+
+  public void setAutoOffsetResetConfig(AutoOffsetResetConfig autoOffsetResetConfig) {
+    this.autoOffsetResetConfig = autoOffsetResetConfig;
+  }
 }
diff --git a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConnectUtils.java b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConnectUtils.java
index cc9bfbff16..6ad3f61db3 100644
--- a/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConnectUtils.java
+++ b/streampipes-extensions/streampipes-pipeline-elements-shared/src/main/java/org/apache/streampipes/pe/shared/config/kafka/kafka/KafkaConnectUtils.java
@@ -19,6 +19,7 @@
 package org.apache.streampipes.pe.shared.config.kafka.kafka;
 
 import org.apache.streampipes.extensions.api.extractor.IStaticPropertyExtractor;
+import org.apache.streampipes.messaging.kafka.config.AutoOffsetResetConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecurityConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecuritySaslPlainConfig;
 import org.apache.streampipes.messaging.kafka.security.KafkaSecuritySaslSSLConfig;
@@ -30,6 +31,8 @@ import org.apache.streampipes.sdk.helpers.Alternatives;
 import org.apache.streampipes.sdk.helpers.Label;
 import org.apache.streampipes.sdk.helpers.Labels;
 
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+
 public class KafkaConnectUtils {
 
   public static final String TOPIC_KEY = "topic";
@@ -55,6 +58,11 @@ public class KafkaConnectUtils {
 
   private static final String HIDE_INTERNAL_TOPICS = "hide-internal-topics";
 
+  public static final String AUTO_OFFSET_RESET_CONFIG = ConsumerConfig.AUTO_OFFSET_RESET_CONFIG;
+  public static final String EARLIEST = "earliest";
+  public static final String LATEST = "latest";
+  public static final String NONE = "none";
+
   public static Label getTopicLabel() {
     return Labels.withId(TOPIC_KEY);
   }
@@ -79,6 +87,11 @@ public class KafkaConnectUtils {
     return Labels.withId(ACCESS_MODE);
   }
 
+  public static Label getAutoOffsetResetConfigLabel() {
+    return Labels.withId(AUTO_OFFSET_RESET_CONFIG);
+  }
+
+
   public static KafkaConfig getConfig(IStaticPropertyExtractor extractor, boolean containsTopic) {
     String brokerUrl = extractor.singleValueParameter(HOST_KEY, String.class);
     String topic = "";
@@ -93,7 +106,7 @@ public class KafkaConnectUtils {
 
     KafkaSecurityConfig securityConfig;
 
-    //KafkaSerializerConfig serializerConfig = new KafkaSerializerByteArrayConfig();
+    //KafkaSerializerConfig serializerConfig = new KafkaSerializerByteArrayConfig()
 
     // check if a user for the authentication is defined
     if (authentication.equals(KafkaConnectUtils.SASL_SSL) || authentication.equals(KafkaConnectUtils.SASL_PLAIN)) {
@@ -110,7 +123,12 @@ public class KafkaConnectUtils {
           new KafkaSecurityUnauthenticatedPlainConfig();
     }
 
-    return new KafkaConfig(brokerUrl, port, topic, securityConfig);
+
+
+    String auto = extractor.selectedAlternativeInternalId(AUTO_OFFSET_RESET_CONFIG);
+    AutoOffsetResetConfig autoOffsetResetConfig = new AutoOffsetResetConfig(auto);
+
+    return new KafkaConfig(brokerUrl, port, topic, securityConfig, autoOffsetResetConfig);
   }
 
   private static boolean isUseSSL(String authentication) {
@@ -144,4 +162,17 @@ public class KafkaConnectUtils {
             StaticProperties.stringFreeTextProperty(Labels.withId(KafkaConnectUtils.USERNAME_KEY)),
             StaticProperties.secretValue(Labels.withId(KafkaConnectUtils.PASSWORD_KEY))));
   }
+
+
+  public static StaticPropertyAlternative getAlternativesLatest() {
+    return Alternatives.from(Labels.withId(LATEST));
+  }
+
+  public static StaticPropertyAlternative getAlternativesEarliest() {
+    return Alternatives.from(Labels.withId(EARLIEST));
+  }
+
+  public static StaticPropertyAlternative getAlternativesNone() {
+    return Alternatives.from(Labels.withId(NONE));
+  }
 }
diff --git a/streampipes-extensions/streampipes-processors-change-detection-jvm/pom.xml b/streampipes-extensions/streampipes-processors-change-detection-jvm/pom.xml
index 78f5c30b64..b68156ba72 100644
--- a/streampipes-extensions/streampipes-processors-change-detection-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-processors-change-detection-jvm/pom.xml
@@ -46,6 +46,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-processors-enricher-jvm/pom.xml b/streampipes-extensions/streampipes-processors-enricher-jvm/pom.xml
index 9cc12b1830..40fc564aae 100644
--- a/streampipes-extensions/streampipes-processors-enricher-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-processors-enricher-jvm/pom.xml
@@ -52,6 +52,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-processors-filters-jvm/pom.xml b/streampipes-extensions/streampipes-processors-filters-jvm/pom.xml
index b5b3fa757e..98bfabefdb 100644
--- a/streampipes-extensions/streampipes-processors-filters-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-processors-filters-jvm/pom.xml
@@ -50,6 +50,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-processors-filters-siddhi/pom.xml b/streampipes-extensions/streampipes-processors-filters-siddhi/pom.xml
index babcc03d54..aa2fce447d 100644
--- a/streampipes-extensions/streampipes-processors-filters-siddhi/pom.xml
+++ b/streampipes-extensions/streampipes-processors-filters-siddhi/pom.xml
@@ -76,6 +76,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-processors-geo-jvm/pom.xml b/streampipes-extensions/streampipes-processors-geo-jvm/pom.xml
index 045b2f6ef7..bf61f86db4 100644
--- a/streampipes-extensions/streampipes-processors-geo-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-processors-geo-jvm/pom.xml
@@ -78,6 +78,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-processors-image-processing-jvm/pom.xml b/streampipes-extensions/streampipes-processors-image-processing-jvm/pom.xml
index 24ff6c3acc..b80cfcf744 100644
--- a/streampipes-extensions/streampipes-processors-image-processing-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-processors-image-processing-jvm/pom.xml
@@ -53,6 +53,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-processors-text-mining-jvm/pom.xml b/streampipes-extensions/streampipes-processors-text-mining-jvm/pom.xml
index 0c78c95485..2d5fbc396f 100644
--- a/streampipes-extensions/streampipes-processors-text-mining-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-processors-text-mining-jvm/pom.xml
@@ -56,6 +56,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-sinks-brokers-jvm/pom.xml b/streampipes-extensions/streampipes-sinks-brokers-jvm/pom.xml
index e0b7afbc7c..4980a3701d 100644
--- a/streampipes-extensions/streampipes-sinks-brokers-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-sinks-brokers-jvm/pom.xml
@@ -120,6 +120,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-sinks-databases-jvm/pom.xml b/streampipes-extensions/streampipes-sinks-databases-jvm/pom.xml
index 714f9e9385..157333404c 100644
--- a/streampipes-extensions/streampipes-sinks-databases-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-sinks-databases-jvm/pom.xml
@@ -136,6 +136,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-sinks-internal-jvm/pom.xml b/streampipes-extensions/streampipes-sinks-internal-jvm/pom.xml
index ade1a6c4b4..d10a3cd7fa 100644
--- a/streampipes-extensions/streampipes-sinks-internal-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-sinks-internal-jvm/pom.xml
@@ -87,6 +87,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-sinks-notifications-jvm/pom.xml b/streampipes-extensions/streampipes-sinks-notifications-jvm/pom.xml
index b06eba5917..b51a074695 100644
--- a/streampipes-extensions/streampipes-sinks-notifications-jvm/pom.xml
+++ b/streampipes-extensions/streampipes-sinks-notifications-jvm/pom.xml
@@ -64,6 +64,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-extensions/streampipes-sources-watertank-simulator/pom.xml b/streampipes-extensions/streampipes-sources-watertank-simulator/pom.xml
index f4777ce922..a38c31c109 100644
--- a/streampipes-extensions/streampipes-sources-watertank-simulator/pom.xml
+++ b/streampipes-extensions/streampipes-sources-watertank-simulator/pom.xml
@@ -111,6 +111,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
         <finalName>streampipes-sources-watertank-simulator</finalName>
diff --git a/streampipes-mail/src/main/java/org/apache/streampipes/mail/utils/MailUtils.java b/streampipes-mail/src/main/java/org/apache/streampipes/mail/utils/MailUtils.java
index d82066f1bb..317f534966 100644
--- a/streampipes-mail/src/main/java/org/apache/streampipes/mail/utils/MailUtils.java
+++ b/streampipes-mail/src/main/java/org/apache/streampipes/mail/utils/MailUtils.java
@@ -17,13 +17,12 @@
  */
 package org.apache.streampipes.mail.utils;
 
+import org.apache.streampipes.commons.resources.Resources;
 import org.apache.streampipes.config.backend.BackendConfig;
 import org.apache.streampipes.config.backend.model.GeneralConfig;
 
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 public class MailUtils {
 
@@ -38,6 +37,6 @@ public class MailUtils {
   }
 
   public static String readResourceFileToString(String filename) throws IOException {
-    return Resources.toString(Resources.getResource(filename), Charsets.UTF_8);
+    return Resources.asString(filename, StandardCharsets.UTF_8);
   }
 }
diff --git a/streampipes-measurement-units/pom.xml b/streampipes-measurement-units/pom.xml
index 839f5d6197..896bf4cabc 100644
--- a/streampipes-measurement-units/pom.xml
+++ b/streampipes-measurement-units/pom.xml
@@ -16,7 +16,8 @@
   ~
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.streampipes</groupId>
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/UnitFactory.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/UnitFactory.java
index 495da29128..d9fdf6b75d 100644
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/UnitFactory.java
+++ b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/UnitFactory.java
@@ -13,7 +13,6 @@ import org.eclipse.rdf4j.model.impl.LinkedHashModel;
 import org.eclipse.rdf4j.model.impl.ValueFactoryImpl;
 import org.eclipse.rdf4j.model.vocabulary.RDF;
 import org.eclipse.rdf4j.model.vocabulary.RDFS;
-import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
 
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -90,8 +89,6 @@ public class UnitFactory {
 							unit.setType(new URI(typeURI.stringValue()));
 						}
 					}
-				} else {
-					// System.out.println("Ignoring: " + statement);
 				}
 			}
 			unit.setMultiplier(multiplier);
@@ -102,27 +99,6 @@ public class UnitFactory {
 		return unit;
 	}
 
-	public List<Unit> findUnits(String symbol) {
-		if (symbol == null) throw new IllegalArgumentException("The symbol cannot be null");
-
-		ValueFactory f = ValueFactoryImpl.getInstance();
-		Model statements = repos.filter(null, QUDT.ABBREVIATION, f.createLiteral(symbol, XMLSchema.STRING));
-		if (statements.isEmpty()) return Collections.emptyList();
-		List<Unit> foundUnits = new ArrayList<>();
-		for (Statement statement : statements) {
-			Object type = statement.getSubject();
-			try {
-				if (type instanceof org.eclipse.rdf4j.model.URI) {
-					org.eclipse.rdf4j.model.URI typeURI = (org.eclipse.rdf4j.model.URI)type;
-					foundUnits.add(getUnit(typeURI.toString()));
-				}
-			} catch (Exception exception) {
-				// ignore
-			}
-		}
-		return foundUnits;
-	}
-
 	public List<String> getURIs(String type) {
 		URI uri;
 		try {
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/AreaUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/AreaUnit.java
deleted file mode 100644
index 118d47117e..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/AreaUnit.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class AreaUnit {
-
-	public static Unit SQUARE_METER = UnitFactory
-					.getInstance()
-					.getUnit("http://qudt.org/vocab/unit#SquareMeter");
-
-	public static Unit SQUARE_ANGSTROM = UnitFactory
-					.getInstance()
-					.getUnit("http://www.openphacts.org/units/SquareAngstrom");
-
-	private AreaUnit() {}
-
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/ConcentrationUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/ConcentrationUnit.java
deleted file mode 100644
index 0c526b0cfe..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/ConcentrationUnit.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class ConcentrationUnit {
-
-	public static Unit MOLE_PER_CUBIC_METER = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#MolePerCubicMeter");
-
-	public static Unit MOLAR = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Molar");
-	public static Unit MILLIMOLAR = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Millimolar");
-	public static Unit NANOMOLAR = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Nanomolar");
-	public static Unit MICROMOLAR = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Micromolar");
-
-	public static Unit GRAM_PER_LITER = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/GramPerLiter");
-	public static Unit MICROGRAM_PER_MILLILITER = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/MicrogramPerMilliliter");
-	public static Unit PICOGRAM_PER_MILLILITER = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/PicogramPerMilliliter");
-
-	private ConcentrationUnit() {}
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/CountingUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/CountingUnit.java
deleted file mode 100644
index c4363431ab..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/CountingUnit.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class CountingUnit {
-
-	public static Unit PERCENT = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#Percent");
-
-	private CountingUnit() {}
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/EnergyUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/EnergyUnit.java
deleted file mode 100644
index 5f6f671d01..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/EnergyUnit.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class EnergyUnit {
-
-	private EnergyUnit() {}
-
-	public static Unit EV = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#ElectronVolt");
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/LengthUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/LengthUnit.java
deleted file mode 100644
index 538bf26a85..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/LengthUnit.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class LengthUnit {
-
-  private LengthUnit() {
-  }
-
-  public static Unit NM = UnitFactory
-          .getInstance()
-          .getUnit("http://www.openphacts.org/units/Nanometer");
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/MassUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/MassUnit.java
deleted file mode 100644
index 7c0cd2d006..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/MassUnit.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class MassUnit {
-
-  public static Unit KILOGRAM = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#Kilogram");
-  public static Unit GRAM = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#Gram");
-  public static Unit MILLIGRAM = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Milligram");
-  public static Unit MICROGRAM = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Microgram");
-  public static Unit NANOGRAM = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Nanogram");
-  public static Unit PICOGRAM = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Picogram");
-  public static Unit FEMTOGRAM = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Femtogram");
-
-  private MassUnit() {
-  }
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/PressureOrStressUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/PressureOrStressUnit.java
deleted file mode 100644
index f6943caf98..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/PressureOrStressUnit.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class PressureOrStressUnit {
-    private PressureOrStressUnit() {}
-
-    public static Unit PASCAL = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#Pascal");
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/TemperatureUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/TemperatureUnit.java
deleted file mode 100644
index 388d4f0190..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/TemperatureUnit.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class TemperatureUnit {
-
-	private TemperatureUnit() {}
-
-	public static Unit KELVIN = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#Kelvin");
-	public static Unit CELSIUS = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#DegreeCelsius");
-	public static Unit FAHRENHEIT = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#DegreeFahrenheit");
-
-}
diff --git a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/VolumeUnit.java b/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/VolumeUnit.java
deleted file mode 100644
index 04156b085e..0000000000
--- a/streampipes-measurement-units/src/main/java/com/github/jqudt/onto/units/VolumeUnit.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (C) 2012  Egon Willighagen <egonw@users.sf.net>
- *
- * License: new BSD
- */
-package com.github.jqudt.onto.units;
-
-import com.github.jqudt.Unit;
-import com.github.jqudt.onto.UnitFactory;
-
-public class VolumeUnit {
-
-	private VolumeUnit() {}
-
-	public static Unit LITER = UnitFactory.getInstance().getUnit("http://qudt.org/vocab/unit#Liter");
-	public static Unit MICROLITER = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Microliter");
-	public static Unit MILLILITER = UnitFactory.getInstance().getUnit("http://www.openphacts.org/units/Milliliter");
-
-}
diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaNodeVariants.java b/streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/AutoOffsetResetConfig.java
similarity index 56%
rename from streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaNodeVariants.java
rename to streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/AutoOffsetResetConfig.java
index 414465cadb..25f8ae29f2 100644
--- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/utils/OpcUaNodeVariants.java
+++ b/streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/AutoOffsetResetConfig.java
@@ -16,39 +16,28 @@
  *
  */
 
-package org.apache.streampipes.extensions.connectors.opcua.adapter.utils;
+package org.apache.streampipes.messaging.kafka.config;
 
+import org.apache.kafka.clients.consumer.ConsumerConfig;
 
-import jakarta.annotation.Nullable;
+import java.util.Properties;
 
-/**
- * Enum that maintains different variants of OPC UA nodes. <br>
- * Not yet completed. <br>
- */
-public enum OpcUaNodeVariants {
-  Property(68),
-  EUInformation(887);
+public class AutoOffsetResetConfig implements KafkaConfigAppender {
 
-  // ID as specified in OPC UA standard
-  private final int id;
+  private final String autoOffsetResetConfig;
 
-  private OpcUaNodeVariants(int id) {
-    this.id = id;
+  @Override
+  public void appendConfig(Properties props) {
+    props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetResetConfig);
   }
 
-  public int getId() {
-    return this.id;
+  public AutoOffsetResetConfig(String autoOffsetResetConfig) {
+    this.autoOffsetResetConfig = autoOffsetResetConfig;
   }
 
-  @Nullable
-  public static OpcUaNodeVariants from(int id) {
-    switch (id) {
-      case 68:
-        return Property;
-      case 887:
-        return EUInformation;
-      default:
-        return null;
-    }
+
+  public String getAutoOffsetResetConfig() {
+    return autoOffsetResetConfig;
   }
+
 }
diff --git a/streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/ConsumerConfigFactory.java b/streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/ConsumerConfigFactory.java
index 461d96e04f..4019cd7bab 100644
--- a/streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/ConsumerConfigFactory.java
+++ b/streampipes-messaging-kafka/src/main/java/org/apache/streampipes/messaging/kafka/config/ConsumerConfigFactory.java
@@ -33,6 +33,7 @@ public class ConsumerConfigFactory extends AbstractConfigFactory {
   private static final Integer FETCH_MAX_BYTES_CONFIG_DEFAULT = 52428800;
   private static final String KEY_DESERIALIZER_CLASS_CONFIG_DEFAULT = ByteArrayDeserializer.class.getName();
   private static final String VALUE_DESERIALIZER_CLASS_CONFIG_DEFAULT = ByteArrayDeserializer.class.getName();
+  private static final String AUTO_OFFSET_RESET_CONFIG_DEFAULT = "earliest";
 
   public ConsumerConfigFactory(KafkaTransportProtocol protocol) {
     super(protocol);
@@ -55,7 +56,7 @@ public class ConsumerConfigFactory extends AbstractConfigFactory {
 
 
     props.put(ConsumerConfig.CLIENT_ID_CONFIG, UUID.randomUUID().toString());
-
+    props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, AUTO_OFFSET_RESET_CONFIG_DEFAULT);
     return props;
   }
 }
diff --git a/streampipes-model/pom.xml b/streampipes-model/pom.xml
index bc4ff9f994..059059f41d 100644
--- a/streampipes-model/pom.xml
+++ b/streampipes-model/pom.xml
@@ -71,24 +71,16 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-        </dependency>
       <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-core</artifactId>
+          <scope>test</scope>
       </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
         </dependency>
-      <dependency>
-        <groupId>com.typesafe.akka</groupId>
-        <artifactId>akka-stream_2.11</artifactId>
-        <version>2.5.21</version>
-        <scope>compile</scope>
-      </dependency>
     </dependencies>
 
     <build>
@@ -136,6 +128,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventProperty.java b/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventProperty.java
index 0cdc8f15e9..9cc33eae6b 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventProperty.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventProperty.java
@@ -19,10 +19,10 @@
 package org.apache.streampipes.model.schema;
 
 import org.apache.streampipes.model.util.ElementIdGenerator;
+import org.apache.streampipes.model.util.ListUtils;
 
 import com.fasterxml.jackson.annotation.JsonSubTypes;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import org.apache.commons.collections.ListUtils;
 
 import java.net.URI;
 import java.util.ArrayList;
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventSchema.java b/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventSchema.java
index d5e21a1046..89c978c1ab 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventSchema.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/schema/EventSchema.java
@@ -19,8 +19,7 @@
 package org.apache.streampipes.model.schema;
 
 import org.apache.streampipes.model.util.Cloner;
-
-import org.apache.commons.collections.ListUtils;
+import org.apache.streampipes.model.util.ListUtils;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/RuntimeResolvableTreeInputStaticProperty.java b/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/RuntimeResolvableTreeInputStaticProperty.java
index 8e3cd90991..f6d48c744a 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/RuntimeResolvableTreeInputStaticProperty.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/RuntimeResolvableTreeInputStaticProperty.java
@@ -28,6 +28,7 @@ public class RuntimeResolvableTreeInputStaticProperty extends StaticProperty {
   private List<TreeInputNode> nodes;
 
   private boolean resolveDynamically;
+  private boolean multiSelection;
   private String nextBaseNodeToResolve;
   private List<TreeInputNode> latestFetchedNodes;
 
@@ -58,6 +59,7 @@ public class RuntimeResolvableTreeInputStaticProperty extends StaticProperty {
     this.latestFetchedNodes = other.getLatestFetchedNodes();
     this.selectedNodesInternalNames = other.getSelectedNodesInternalNames();
     this.nextBaseNodeToResolve = other.getNextBaseNodeToResolve();
+    this.multiSelection = other.isMultiSelection();
   }
 
   @Override
@@ -112,4 +114,12 @@ public class RuntimeResolvableTreeInputStaticProperty extends StaticProperty {
   public void setSelectedNodesInternalNames(List<String> selectedNodesInternalNames) {
     this.selectedNodesInternalNames = selectedNodesInternalNames;
   }
+
+  public boolean isMultiSelection() {
+    return multiSelection;
+  }
+
+  public void setMultiSelection(boolean multiSelection) {
+    this.multiSelection = multiSelection;
+  }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/util/ListUtils.java b/streampipes-model/src/main/java/org/apache/streampipes/model/util/ListUtils.java
new file mode 100644
index 0000000000..7e2a1b4c48
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/util/ListUtils.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.model.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Objects;
+
+public class ListUtils {
+
+  public static boolean isEqualList(final Collection<?> list1, final Collection<?> list2) {
+    if (list1 == list2) {
+      return true;
+    }
+    if (list1 == null || list2 == null || list1.size() != list2.size()) {
+      return false;
+    }
+
+    final Iterator<?> it1 = list1.iterator();
+    final Iterator<?> it2 = list2.iterator();
+
+    while (it1.hasNext() && it2.hasNext()) {
+      final Object obj1 = it1.next();
+      final Object obj2 = it2.next();
+
+      if (!Objects.equals(obj1, obj2)) {
+        return false;
+      }
+    }
+
+    return !(it1.hasNext() || it2.hasNext());
+  }
+}
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/assets/DocumentationParser.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/assets/DocumentationParser.java
index 9ee7c74915..01d1e2a27d 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/assets/DocumentationParser.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/assets/DocumentationParser.java
@@ -17,11 +17,11 @@
  */
 package org.apache.streampipes.manager.assets;
 
-import com.google.common.base.Charsets;
 import org.apache.commons.io.FileUtils;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 public class DocumentationParser {
 
@@ -38,14 +38,14 @@ public class DocumentationParser {
     try {
       String fileContents = getFileContents();
       String newFileContents = new ImagePathReplacer(fileContents, appId).replaceContent();
-      FileUtils.writeStringToFile(file, newFileContents, Charsets.UTF_8);
+      FileUtils.writeStringToFile(file, newFileContents, StandardCharsets.UTF_8);
     } catch (IOException e) {
       e.printStackTrace();
     }
   }
 
   private String getFileContents() throws IOException {
-    return FileUtils.readFileToString(file, Charsets.UTF_8);
+    return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
   }
 
 }
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemFetcher.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemFetcher.java
index 0c103e6990..0cfda6e2b7 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemFetcher.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemFetcher.java
@@ -27,7 +27,6 @@ import org.apache.http.client.fluent.Request;
 import org.apache.http.message.BasicHeader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.http.MediaType;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -51,7 +50,7 @@ public class EndpointItemFetcher {
   private List<ExtensionsServiceEndpointItem> getEndpointItems(ExtensionsServiceEndpoint e) {
     try {
       String result = Request.Get(e.getEndpointUrl())
-          .addHeader(new BasicHeader("Accept", MediaType.APPLICATION_JSON_VALUE))
+          .addHeader(new BasicHeader("Accept", "application/json"))
           .connectTimeout(1000)
           .execute()
           .returnContent()
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemParser.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemParser.java
index 24eab26891..88a3a22c6e 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemParser.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointItemParser.java
@@ -23,7 +23,6 @@ import org.apache.streampipes.model.message.NotificationType;
 import org.apache.streampipes.model.message.Notifications;
 
 import org.apache.http.client.fluent.Request;
-import org.springframework.http.MediaType;
 
 import java.io.IOException;
 import java.net.URLDecoder;
@@ -47,7 +46,7 @@ public class EndpointItemParser {
   private String parseURIContent(String url) throws IOException {
     return Request
         .Get(url)
-        .addHeader("Accept", MediaType.APPLICATION_JSON_VALUE)
+        .addHeader("Accept", "application/json")
         .execute()
         .returnContent()
         .asString();
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java
index 3fcc77e464..c0f1c12a4a 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/pipeline/PipelineManager.java
@@ -29,8 +29,6 @@ import org.apache.streampipes.storage.api.IPermissionStorage;
 import org.apache.streampipes.storage.api.IPipelineStorage;
 import org.apache.streampipes.storage.management.StorageDispatcher;
 
-import com.google.common.collect.Streams;
-
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -129,10 +127,10 @@ public class PipelineManager {
         .collect(Collectors.toList());
   }
 
-  private static Stream<NamedStreamPipesEntity> mergePipelineElement(Pipeline pipeline) {
-    return Streams.concat(pipeline.getStreams().stream(),
-        pipeline.getActions().stream(),
-        pipeline.getSepas().stream());
+  private static Stream<? extends NamedStreamPipesEntity> mergePipelineElement(Pipeline pipeline) {
+    return Stream.concat(
+        Stream.concat(pipeline.getStreams().stream(), pipeline.getSepas().stream()),
+        pipeline.getActions().stream());
   }
 
   private static void preparePipelineBasics(String username,
diff --git a/streampipes-sdk/pom.xml b/streampipes-sdk/pom.xml
index 93cf4fa669..5b4671c79d 100644
--- a/streampipes-sdk/pom.xml
+++ b/streampipes-sdk/pom.xml
@@ -34,6 +34,11 @@
             <artifactId>streampipes-config</artifactId>
             <version>0.93.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.streampipes</groupId>
+            <artifactId>streampipes-commons</artifactId>
+            <version>0.93.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.streampipes</groupId>
             <artifactId>streampipes-extensions-api</artifactId>
@@ -51,10 +56,6 @@
         </dependency>
 
         <!-- External dependencies -->
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
         <dependency>
             <groupId>com.github.drapostolos</groupId>
             <artifactId>type-parser</artifactId>
@@ -81,6 +82,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
index ecce2e722a..6707617e84 100644
--- a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
+++ b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
@@ -137,13 +137,16 @@ public class StaticProperties {
 
   public static RuntimeResolvableTreeInputStaticProperty runtimeResolvableTreeInput(Label label,
                                                                                     List<String> dependsOn,
-                                                                                    boolean resolveDynamically) {
+                                                                                    boolean resolveDynamically,
+                                                                                    boolean multiSelection) {
     RuntimeResolvableTreeInputStaticProperty treeInput = new RuntimeResolvableTreeInputStaticProperty(
         label.getInternalId(),
         label.getLabel(),
         label.getDescription());
 
     treeInput.setDependsOn(dependsOn);
+    treeInput.setResolveDynamically(resolveDynamically);
+    treeInput.setMultiSelection(multiSelection);
 
     return treeInput;
   }
diff --git a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/builder/AbstractConfigurablePipelineElementBuilder.java b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/builder/AbstractConfigurablePipelineElementBuilder.java
index e7d2878c6f..64d7a05ae4 100644
--- a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/builder/AbstractConfigurablePipelineElementBuilder.java
+++ b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/builder/AbstractConfigurablePipelineElementBuilder.java
@@ -1012,14 +1012,18 @@ public abstract class AbstractConfigurablePipelineElementBuilder<K extends
   }
 
   public K requiredRuntimeResolvableTreeInput(Label label,
-                                              List<String> dependsOn) {
-    return requiredRuntimeResolvableTreeInput(label, dependsOn, false);
+                                              List<String> dependsOn,
+                                              boolean multiSelection) {
+    return requiredRuntimeResolvableTreeInput(label, dependsOn, false, multiSelection);
   }
 
   public K requiredRuntimeResolvableTreeInput(Label label,
                                               List<String> dependsOn,
-                                              boolean resolveDynamically) {
-    this.staticProperties.add(StaticProperties.runtimeResolvableTreeInput(label, dependsOn, resolveDynamically));
+                                              boolean resolveDynamically,
+                                              boolean multiSelection) {
+    this.staticProperties.add(
+        StaticProperties.runtimeResolvableTreeInput(label, dependsOn, resolveDynamically, multiSelection)
+    );
     return me();
   }
 
diff --git a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/Labels.java b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/Labels.java
index 1a29aa0e48..378e5372a2 100644
--- a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/Labels.java
+++ b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/Labels.java
@@ -18,13 +18,12 @@
 
 package org.apache.streampipes.sdk.helpers;
 
-import com.google.common.io.ByteSource;
-import com.google.common.io.Resources;
+import org.apache.streampipes.commons.resources.Resources;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.URL;
 import java.util.Properties;
 
@@ -117,14 +116,10 @@ public class Labels {
   }
 
   private static Properties loadProperties(String filename) throws IOException {
-    URL url = Resources.getResource(filename);
+    URL url = Resources.asUrl(filename);
     final Properties props = new Properties();
 
-    final ByteSource byteSource = Resources.asByteSource(url);
-    InputStream inputStream = null;
-
-    inputStream = byteSource.openBufferedStream();
-    props.load(inputStream);
+    props.load(url.openStream());
     return props;
   }
 
diff --git a/streampipes-service-base/pom.xml b/streampipes-service-base/pom.xml
index 496781231b..8da3f3f26e 100644
--- a/streampipes-service-base/pom.xml
+++ b/streampipes-service-base/pom.xml
@@ -121,10 +121,6 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-context-support</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.hibernate.validator</groupId>
-            <artifactId>hibernate-validator</artifactId>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java
index fb46f25465..214b21b9de 100644
--- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java
+++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/WebSecurityConfig.java
@@ -18,8 +18,8 @@
 
 package org.apache.streampipes.service.core;
 
-import org.apache.streampipes.rest.filter.TokenAuthenticationFilter;
 import org.apache.streampipes.service.base.security.UnauthorizedRequestEntryPoint;
+import org.apache.streampipes.service.core.filter.TokenAuthenticationFilter;
 import org.apache.streampipes.user.management.service.SpUserDetailsService;
 
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/filter/TokenAuthenticationFilter.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
similarity index 98%
rename from streampipes-rest/src/main/java/org/apache/streampipes/rest/filter/TokenAuthenticationFilter.java
rename to streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
index fa4e64cac9..e389f4afbf 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/filter/TokenAuthenticationFilter.java
+++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.streampipes.rest.filter;
+package org.apache.streampipes.service.core.filter;
 
 import org.apache.streampipes.commons.constants.HttpConstants;
 import org.apache.streampipes.model.client.user.Principal;
diff --git a/streampipes-service-discovery-consul/pom.xml b/streampipes-service-discovery-consul/pom.xml
index d3a102fa56..f6e34c39c6 100644
--- a/streampipes-service-discovery-consul/pom.xml
+++ b/streampipes-service-discovery-consul/pom.xml
@@ -50,10 +50,6 @@
             <artifactId>consul-api</artifactId>
             <version>1.4.5</version>
         </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>fluent-hc</artifactId>
diff --git a/streampipes-storage-couchdb/pom.xml b/streampipes-storage-couchdb/pom.xml
index 44f478e5d6..963d0a25cc 100644
--- a/streampipes-storage-couchdb/pom.xml
+++ b/streampipes-storage-couchdb/pom.xml
@@ -51,14 +51,14 @@
         </dependency>
 
         <!-- External dependencies -->
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.lightcouch</groupId>
             <artifactId>lightcouch</artifactId>
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ConnectionStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ConnectionStorageImpl.java
index 6402d4b30b..7f98b3746d 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ConnectionStorageImpl.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ConnectionStorageImpl.java
@@ -24,7 +24,6 @@ import org.apache.streampipes.storage.api.IPipelineElementConnectionStorage;
 import org.apache.streampipes.storage.couchdb.dao.AbstractDao;
 import org.apache.streampipes.storage.couchdb.utils.Utils;
 
-import com.google.common.net.UrlEscapers;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -67,8 +66,8 @@ public class ConnectionStorageImpl extends AbstractDao<Connection> implements
   }
 
   private String buildQuery(String from) {
-    String escapedPath = UrlEscapers.urlPathSegmentEscaper()
-        .escape("startkey=[\"" + from + "\"]&endkey=[\"" + from + "\", {}]&group=true");
+    String escapedPath = Utils
+        .escapePathSegment("startkey=[\"" + from + "\"]&endkey=[\"" + from + "\", {}]&group=true");
     return couchDbClientSupplier.get().getDBUri() + "_design/connection/_view/frequent?" + escapedPath;
   }
 
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
index 0817e52299..c0f814b581 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
@@ -26,7 +26,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.net.UrlEscapers;
 import org.apache.http.client.fluent.Content;
 import org.apache.http.client.fluent.Request;
 
@@ -52,8 +51,8 @@ public class GenericStorageImpl implements IGenericStorage {
 
   @Override
   public List<Map<String, Object>> findAll(String type) throws IOException {
-    String query = getDatabaseRoute() + "/_design/appDocType/_view/appDocType?" + UrlEscapers.urlPathSegmentEscaper()
-        .escape("startkey=[\"" + type + "\"]&endkey=[\"" + type + "\",{}]&include_docs=true");
+    String query = getDatabaseRoute() + "/_design/appDocType/_view/appDocType?" + Utils
+        .escapePathSegment("startkey=[\"" + type + "\"]&endkey=[\"" + type + "\",{}]&include_docs=true");
     Map<String, Object> queryResult = this.queryDocuments(query);
 
     List<Map<String, Object>> rows = (List<Map<String, Object>>) queryResult.get("rows");
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
index ba4356f0f0..4ec1b20a2b 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
@@ -22,6 +22,7 @@ import org.apache.streampipes.commons.environment.Environment;
 import org.apache.streampipes.commons.environment.Environments;
 import org.apache.streampipes.storage.couchdb.serializer.GsonSerializer;
 
+import com.google.common.net.UrlEscapers;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.http.HttpHeaders;
 import org.apache.http.client.fluent.Request;
@@ -35,6 +36,10 @@ public class Utils {
     return getCouchDbGsonClient("data-processor");
   }
 
+  public static String escapePathSegment(String urlSegment) {
+    return UrlEscapers.urlPathSegmentEscaper().escape(urlSegment);
+  }
+
   public static CouchDbClient getCouchDbDataStreamDescriptionClient() {
     return getCouchDbGsonClient("data-stream");
   }
diff --git a/streampipes-user-management/pom.xml b/streampipes-user-management/pom.xml
index 632959c08e..8d5592fb73 100644
--- a/streampipes-user-management/pom.xml
+++ b/streampipes-user-management/pom.xml
@@ -52,8 +52,8 @@
 
         <!-- External dependencies -->
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-oauth2-client</artifactId>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
         </dependency>
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
diff --git a/streampipes-wrapper-distributed/pom.xml b/streampipes-wrapper-distributed/pom.xml
index 6ee0136918..1f08d7e34e 100644
--- a/streampipes-wrapper-distributed/pom.xml
+++ b/streampipes-wrapper-distributed/pom.xml
@@ -55,6 +55,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-wrapper-flink/pom.xml b/streampipes-wrapper-flink/pom.xml
index 0d6b63cd4b..e813ead056 100644
--- a/streampipes-wrapper-flink/pom.xml
+++ b/streampipes-wrapper-flink/pom.xml
@@ -121,6 +121,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-wrapper-kafka-streams/pom.xml b/streampipes-wrapper-kafka-streams/pom.xml
index 8ba6767a8d..e6d42cdbff 100644
--- a/streampipes-wrapper-kafka-streams/pom.xml
+++ b/streampipes-wrapper-kafka-streams/pom.xml
@@ -64,6 +64,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-wrapper-python/pom.xml b/streampipes-wrapper-python/pom.xml
index d9a4c294de..64fad8e3ce 100644
--- a/streampipes-wrapper-python/pom.xml
+++ b/streampipes-wrapper-python/pom.xml
@@ -29,6 +29,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-wrapper-siddhi/pom.xml b/streampipes-wrapper-siddhi/pom.xml
index 861a9ed42b..aea9d9fe71 100644
--- a/streampipes-wrapper-siddhi/pom.xml
+++ b/streampipes-wrapper-siddhi/pom.xml
@@ -70,6 +70,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/streampipes-wrapper/pom.xml b/streampipes-wrapper/pom.xml
index 7ab6eeb663..0f95aef5b2 100644
--- a/streampipes-wrapper/pom.xml
+++ b/streampipes-wrapper/pom.xml
@@ -63,6 +63,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>
+                		checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+                	</propertyExpansion>
+                </configuration>
             </plugin>
         </plugins>
     </build>
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 670715fca1..d9c730e528 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -31,7 +31,7 @@
         "@ngx-loading-bar/core": "6.0.2",
         "@ngx-loading-bar/http-client": "6.0.2",
         "@panzoom/panzoom": "^4.5.1",
-        "@swimlane/ngx-charts": "^20.1.2",
+        "@swimlane/ngx-charts": "^20.4.1",
         "angular-datatables": "^14.0.2",
         "angular-gridster2": "^14.1.2",
         "angular-plotly.js": "^4.0.4",
@@ -88,7 +88,7 @@
         "@types/rx": "^4.1.2",
         "@types/showdown": "1.9.4",
         "@typescript-eslint/eslint-plugin": "5.57.1",
-        "@typescript-eslint/parser": "5.56.0",
+        "@typescript-eslint/parser": "5.59.11",
         "ajv-keywords": "^5.1.0",
         "assert": "^2.0.0",
         "compression-webpack-plugin": "^10.0.0",
@@ -6281,21 +6281,22 @@
       }
     },
     "node_modules/@swimlane/ngx-charts": {
-      "version": "20.1.2",
-      "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-20.1.2.tgz",
-      "integrity": "sha512-9uetDtBg++v96R9Nwgf8mvSu+6149FMQEm/jlpbcquUozfC5l+hO9i88tG3REOxnkGS10snGOCVUcPPY03nbxQ==",
+      "version": "20.4.1",
+      "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-20.4.1.tgz",
+      "integrity": "sha512-DyTQe0fcqLDoLEZca45gkdjxP8iLH7kh4pCkr+TCFIkmgEdfQ5DpavNBOOVO0qd5J5uV/tbtSnkYWSx8JkbFpg==",
       "dependencies": {
-        "d3-array": "^2.9.1",
-        "d3-brush": "^2.1.0",
+        "d3-array": "^3.1.1",
+        "d3-brush": "^3.0.0",
         "d3-color": "^3.1.0",
-        "d3-format": "^2.0.0",
-        "d3-hierarchy": "^2.0.0",
-        "d3-interpolate": "^2.0.1",
-        "d3-scale": "^3.2.3",
-        "d3-selection": "^2.0.0",
-        "d3-shape": "^2.0.0",
+        "d3-ease": "^3.0.1",
+        "d3-format": "^3.1.0",
+        "d3-hierarchy": "^3.1.0",
+        "d3-interpolate": "^3.0.1",
+        "d3-scale": "^4.0.2",
+        "d3-selection": "^3.0.0",
+        "d3-shape": "^3.2.0",
         "d3-time-format": "^3.0.0",
-        "d3-transition": "^2.0.0",
+        "d3-transition": "^3.0.1",
         "rfdc": "^1.3.0",
         "tslib": "^2.0.0"
       },
@@ -6829,8 +6830,7 @@
     "node_modules/@types/showdown": {
       "version": "1.9.4",
       "resolved": "https://registry.npmjs.org/@types/showdown/-/showdown-1.9.4.tgz",
-      "integrity": "sha512-50ehC3IAijfkvoNqmQ+VL73S7orOxmAK8ljQAFBv8o7G66lAZyxQj1L3BAv2dD86myLXI+sgKP1kcxAaxW356w==",
-      "dev": true
+      "integrity": "sha512-50ehC3IAijfkvoNqmQ+VL73S7orOxmAK8ljQAFBv8o7G66lAZyxQj1L3BAv2dD86myLXI+sgKP1kcxAaxW356w=="
     },
     "node_modules/@types/sinonjs__fake-timers": {
       "version": "8.1.1",
@@ -7086,14 +7086,14 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.56.0.tgz",
-      "integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz",
+      "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.56.0",
-        "@typescript-eslint/types": "5.56.0",
-        "@typescript-eslint/typescript-estree": "5.56.0",
+        "@typescript-eslint/scope-manager": "5.59.11",
+        "@typescript-eslint/types": "5.59.11",
+        "@typescript-eslint/typescript-estree": "5.59.11",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -7113,13 +7113,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz",
-      "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz",
+      "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.56.0",
-        "@typescript-eslint/visitor-keys": "5.56.0"
+        "@typescript-eslint/types": "5.59.11",
+        "@typescript-eslint/visitor-keys": "5.59.11"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -7279,9 +7279,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz",
-      "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz",
+      "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -7292,13 +7292,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz",
-      "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz",
+      "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.56.0",
-        "@typescript-eslint/visitor-keys": "5.56.0",
+        "@typescript-eslint/types": "5.59.11",
+        "@typescript-eslint/visitor-keys": "5.59.11",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -7441,12 +7441,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz",
-      "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz",
+      "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/types": "5.59.11",
         "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
@@ -10939,23 +10939,29 @@
       }
     },
     "node_modules/d3-array": {
-      "version": "2.12.1",
-      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
-      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
       "dependencies": {
-        "internmap": "^1.0.0"
+        "internmap": "1 - 2"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/d3-brush": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz",
-      "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+      "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
       "dependencies": {
-        "d3-dispatch": "1 - 2",
-        "d3-drag": "2",
-        "d3-interpolate": "1 - 2",
-        "d3-selection": "2",
-        "d3-transition": "2"
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "3",
+        "d3-transition": "3"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/d3-collection": {
@@ -10972,23 +10978,32 @@
       }
     },
     "node_modules/d3-dispatch": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
-      "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+      "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-drag": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
-      "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
+      "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
       "dependencies": {
-        "d3-dispatch": "1 - 2",
-        "d3-selection": "2"
+        "d3-dispatch": "1 - 3",
+        "d3-selection": "3"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/d3-ease": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
-      "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-force": {
       "version": "1.2.1",
@@ -11012,9 +11027,12 @@
       "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
     },
     "node_modules/d3-format": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
-      "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-geo": {
       "version": "1.12.1",
@@ -11058,27 +11076,31 @@
       "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
     },
     "node_modules/d3-hierarchy": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz",
-      "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw=="
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+      "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-interpolate": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
-      "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
       "dependencies": {
-        "d3-color": "1 - 2"
+        "d3-color": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/d3-interpolate/node_modules/d3-color": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
-      "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
-    },
     "node_modules/d3-path": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
-      "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-quadtree": {
       "version": "1.0.7",
@@ -11086,36 +11108,48 @@
       "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
     },
     "node_modules/d3-scale": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
-      "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
       "dependencies": {
-        "d3-array": "^2.3.0",
-        "d3-format": "1 - 2",
-        "d3-interpolate": "1.2.0 - 2",
-        "d3-time": "^2.1.1",
-        "d3-time-format": "2 - 3"
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/d3-selection": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
-      "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA=="
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+      "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-shape": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
-      "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
       "dependencies": {
-        "d3-path": "1 - 2"
+        "d3-path": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/d3-time": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
-      "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
       "dependencies": {
-        "d3-array": "2"
+        "d3-array": "2 - 3"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/d3-time-format": {
@@ -11126,31 +11160,53 @@
         "d3-time": "1 - 2"
       }
     },
+    "node_modules/d3-time-format/node_modules/d3-array": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+      "dependencies": {
+        "internmap": "^1.0.0"
+      }
+    },
+    "node_modules/d3-time-format/node_modules/d3-time": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+      "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+      "dependencies": {
+        "d3-array": "2"
+      }
+    },
+    "node_modules/d3-time-format/node_modules/internmap": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+      "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+    },
     "node_modules/d3-timer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
-      "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/d3-transition": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
-      "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
+      "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
       "dependencies": {
-        "d3-color": "1 - 2",
-        "d3-dispatch": "1 - 2",
-        "d3-ease": "1 - 2",
-        "d3-interpolate": "1 - 2",
-        "d3-timer": "1 - 2"
+        "d3-color": "1 - 3",
+        "d3-dispatch": "1 - 3",
+        "d3-ease": "1 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-timer": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
       },
       "peerDependencies": {
-        "d3-selection": "2"
+        "d3-selection": "2 - 3"
       }
     },
-    "node_modules/d3-transition/node_modules/d3-color": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
-      "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
-    },
     "node_modules/dagre": {
       "version": "0.8.5",
       "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
@@ -11864,7 +11920,6 @@
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
       "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
-      "dev": true,
       "optional": true,
       "dependencies": {
         "iconv-lite": "^0.6.2"
@@ -11874,7 +11929,6 @@
       "version": "0.6.3",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
       "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-      "dev": true,
       "optional": true,
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -15329,8 +15383,7 @@
     "node_modules/immutable": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
-      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
-      "dev": true
+      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ=="
     },
     "node_modules/import-fresh": {
       "version": "3.3.0",
@@ -15529,9 +15582,12 @@
       }
     },
     "node_modules/internmap": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
-      "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/interpret": {
       "version": "3.1.1",
@@ -20674,17 +20730,6 @@
       "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
       "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
     },
-    "node_modules/plotly.js/node_modules/d3-interpolate": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
-      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
-      "dependencies": {
-        "d3-color": "1 - 3"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/plotly.js/node_modules/d3-time": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
@@ -28055,7 +28100,8 @@
           "version": "14.2.11",
           "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.11.tgz",
           "integrity": "sha512-4enbLFAp98uTgWYF6OFceQqLcfv2/0brIrNN4iWT9xe/Mh3zdCt+eH42zvNRsqo9WXNWRSLvnx8I924p83LNlw==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "ajv": {
           "version": "8.11.0",
@@ -28509,7 +28555,8 @@
               "version": "3.5.2",
               "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
               "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-              "dev": true
+              "dev": true,
+              "requires": {}
             },
             "schema-utils": {
               "version": "3.1.1",
@@ -28629,7 +28676,8 @@
       "version": "15.2.1",
       "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-15.2.1.tgz",
       "integrity": "sha512-7x2DANebLRl997Mj4DhZrnz5+vnSjavGGveJ0mBuU7CEsL0ZYLftdRqL0e0HtU3ksseS7xpchD6OM08nkNgySw==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@angular-eslint/bundled-angular-compiler": {
       "version": "14.4.0",
@@ -30611,13 +30659,15 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz",
       "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@csstools/selector-specificity": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
       "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@ctrl/ngx-codemirror": {
       "version": "5.1.1",
@@ -30831,7 +30881,8 @@
           "version": "3.5.2",
           "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
           "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "brace-expansion": {
           "version": "1.1.11",
@@ -31694,7 +31745,8 @@
     "@mapbox/mapbox-gl-supported": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz",
-      "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg=="
+      "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==",
+      "requires": {}
     },
     "@mapbox/point-geometry": {
       "version": "0.1.0",
@@ -31728,7 +31780,8 @@
       "version": "14.2.10",
       "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.10.tgz",
       "integrity": "sha512-sLHapZLVub6mEz5b19tf1VfIV1w3tYfg7FNPLeni79aldxu1FbP1v2WmiFAnMzrswqyK0bhTtxrl+Z/CLKqyoQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@ngx-loading-bar/core": {
       "version": "6.0.2",
@@ -32332,21 +32385,22 @@
       }
     },
     "@swimlane/ngx-charts": {
-      "version": "20.1.2",
-      "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-20.1.2.tgz",
-      "integrity": "sha512-9uetDtBg++v96R9Nwgf8mvSu+6149FMQEm/jlpbcquUozfC5l+hO9i88tG3REOxnkGS10snGOCVUcPPY03nbxQ==",
+      "version": "20.4.1",
+      "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-20.4.1.tgz",
+      "integrity": "sha512-DyTQe0fcqLDoLEZca45gkdjxP8iLH7kh4pCkr+TCFIkmgEdfQ5DpavNBOOVO0qd5J5uV/tbtSnkYWSx8JkbFpg==",
       "requires": {
-        "d3-array": "^2.9.1",
-        "d3-brush": "^2.1.0",
+        "d3-array": "^3.1.1",
+        "d3-brush": "^3.0.0",
         "d3-color": "^3.1.0",
-        "d3-format": "^2.0.0",
-        "d3-hierarchy": "^2.0.0",
-        "d3-interpolate": "^2.0.1",
-        "d3-scale": "^3.2.3",
-        "d3-selection": "^2.0.0",
-        "d3-shape": "^2.0.0",
+        "d3-ease": "^3.0.1",
+        "d3-format": "^3.1.0",
+        "d3-hierarchy": "^3.1.0",
+        "d3-interpolate": "^3.0.1",
+        "d3-scale": "^4.0.2",
+        "d3-selection": "^3.0.0",
+        "d3-shape": "^3.2.0",
         "d3-time-format": "^3.0.0",
-        "d3-transition": "^2.0.0",
+        "d3-transition": "^3.0.1",
         "rfdc": "^1.3.0",
         "tslib": "^2.0.0"
       }
@@ -32852,8 +32906,7 @@
     "@types/showdown": {
       "version": "1.9.4",
       "resolved": "https://registry.npmjs.org/@types/showdown/-/showdown-1.9.4.tgz",
-      "integrity": "sha512-50ehC3IAijfkvoNqmQ+VL73S7orOxmAK8ljQAFBv8o7G66lAZyxQj1L3BAv2dD86myLXI+sgKP1kcxAaxW356w==",
-      "dev": true
+      "integrity": "sha512-50ehC3IAijfkvoNqmQ+VL73S7orOxmAK8ljQAFBv8o7G66lAZyxQj1L3BAv2dD86myLXI+sgKP1kcxAaxW356w=="
     },
     "@types/sinonjs__fake-timers": {
       "version": "8.1.1",
@@ -33031,25 +33084,25 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.56.0.tgz",
-      "integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz",
+      "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.56.0",
-        "@typescript-eslint/types": "5.56.0",
-        "@typescript-eslint/typescript-estree": "5.56.0",
+        "@typescript-eslint/scope-manager": "5.59.11",
+        "@typescript-eslint/types": "5.59.11",
+        "@typescript-eslint/typescript-estree": "5.59.11",
         "debug": "^4.3.4"
       }
     },
     "@typescript-eslint/scope-manager": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz",
-      "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz",
+      "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.56.0",
-        "@typescript-eslint/visitor-keys": "5.56.0"
+        "@typescript-eslint/types": "5.59.11",
+        "@typescript-eslint/visitor-keys": "5.59.11"
       }
     },
     "@typescript-eslint/type-utils": {
@@ -33140,19 +33193,19 @@
       }
     },
     "@typescript-eslint/types": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz",
-      "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz",
+      "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==",
       "dev": true
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz",
-      "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz",
+      "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.56.0",
-        "@typescript-eslint/visitor-keys": "5.56.0",
+        "@typescript-eslint/types": "5.59.11",
+        "@typescript-eslint/visitor-keys": "5.59.11",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -33236,12 +33289,12 @@
       }
     },
     "@typescript-eslint/visitor-keys": {
-      "version": "5.56.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz",
-      "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==",
+      "version": "5.59.11",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz",
+      "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/types": "5.59.11",
         "eslint-visitor-keys": "^3.3.0"
       }
     },
@@ -33513,19 +33566,22 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
       "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@webpack-cli/info": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz",
       "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@webpack-cli/serve": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz",
       "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "@xtuc/ieee754": {
       "version": "1.2.0",
@@ -33581,13 +33637,15 @@
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
       "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "acorn-jsx": {
       "version": "5.3.2",
       "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
       "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "acorn-walk": {
       "version": "8.2.0",
@@ -33672,7 +33730,8 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
       "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "ajv-formats": {
       "version": "2.1.1",
@@ -35814,7 +35873,8 @@
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
       "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "css-select": {
       "version": "4.3.0",
@@ -36031,7 +36091,8 @@
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz",
       "integrity": "sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "d": {
       "version": "1.0.1",
@@ -36043,23 +36104,23 @@
       }
     },
     "d3-array": {
-      "version": "2.12.1",
-      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
-      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
       "requires": {
-        "internmap": "^1.0.0"
+        "internmap": "1 - 2"
       }
     },
     "d3-brush": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz",
-      "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+      "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
       "requires": {
-        "d3-dispatch": "1 - 2",
-        "d3-drag": "2",
-        "d3-interpolate": "1 - 2",
-        "d3-selection": "2",
-        "d3-transition": "2"
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "3",
+        "d3-transition": "3"
       }
     },
     "d3-collection": {
@@ -36073,23 +36134,23 @@
       "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
     },
     "d3-dispatch": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
-      "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+      "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
     },
     "d3-drag": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
-      "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
+      "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
       "requires": {
-        "d3-dispatch": "1 - 2",
-        "d3-selection": "2"
+        "d3-dispatch": "1 - 3",
+        "d3-selection": "3"
       }
     },
     "d3-ease": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
-      "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
     },
     "d3-force": {
       "version": "1.2.1",
@@ -36115,9 +36176,9 @@
       }
     },
     "d3-format": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
-      "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="
     },
     "d3-geo": {
       "version": "1.12.1",
@@ -36158,29 +36219,22 @@
       }
     },
     "d3-hierarchy": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz",
-      "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw=="
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+      "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="
     },
     "d3-interpolate": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
-      "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
       "requires": {
-        "d3-color": "1 - 2"
-      },
-      "dependencies": {
-        "d3-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
-          "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
-        }
+        "d3-color": "1 - 3"
       }
     },
     "d3-path": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
-      "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="
     },
     "d3-quadtree": {
       "version": "1.0.7",
@@ -36188,36 +36242,36 @@
       "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
     },
     "d3-scale": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
-      "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
       "requires": {
-        "d3-array": "^2.3.0",
-        "d3-format": "1 - 2",
-        "d3-interpolate": "1.2.0 - 2",
-        "d3-time": "^2.1.1",
-        "d3-time-format": "2 - 3"
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
       }
     },
     "d3-selection": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
-      "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA=="
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+      "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="
     },
     "d3-shape": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz",
-      "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
       "requires": {
-        "d3-path": "1 - 2"
+        "d3-path": "^3.1.0"
       }
     },
     "d3-time": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
-      "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
       "requires": {
-        "d3-array": "2"
+        "d3-array": "2 - 3"
       }
     },
     "d3-time-format": {
@@ -36226,30 +36280,46 @@
       "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
       "requires": {
         "d3-time": "1 - 2"
+      },
+      "dependencies": {
+        "d3-array": {
+          "version": "2.12.1",
+          "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+          "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+          "requires": {
+            "internmap": "^1.0.0"
+          }
+        },
+        "d3-time": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
+          "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
+          "requires": {
+            "d3-array": "2"
+          }
+        },
+        "internmap": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+          "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+        }
       }
     },
     "d3-timer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
-      "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
     },
     "d3-transition": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
-      "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
+      "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
       "requires": {
-        "d3-color": "1 - 2",
-        "d3-dispatch": "1 - 2",
-        "d3-ease": "1 - 2",
-        "d3-interpolate": "1 - 2",
-        "d3-timer": "1 - 2"
-      },
-      "dependencies": {
-        "d3-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
-          "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
-        }
+        "d3-color": "1 - 3",
+        "d3-dispatch": "1 - 3",
+        "d3-ease": "1 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-timer": "1 - 3"
       }
     },
     "dagre": {
@@ -36766,7 +36836,8 @@
     "echarts-wordcloud": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/echarts-wordcloud/-/echarts-wordcloud-2.1.0.tgz",
-      "integrity": "sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ=="
+      "integrity": "sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ==",
+      "requires": {}
     },
     "ee-first": {
       "version": "1.1.1",
@@ -36838,7 +36909,6 @@
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
       "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
-      "dev": true,
       "optional": true,
       "requires": {
         "iconv-lite": "^0.6.2"
@@ -36848,7 +36918,6 @@
           "version": "0.6.3",
           "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
           "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-          "dev": true,
           "optional": true,
           "requires": {
             "safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -37493,7 +37562,8 @@
       "version": "8.8.0",
       "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz",
       "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "eslint-scope": {
       "version": "7.1.1",
@@ -39470,7 +39540,8 @@
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
       "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "ieee754": {
       "version": "1.2.1",
@@ -39518,8 +39589,7 @@
     "immutable": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
-      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
-      "dev": true
+      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ=="
     },
     "import-fresh": {
       "version": "3.3.0",
@@ -39671,9 +39741,9 @@
       }
     },
     "internmap": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
-      "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="
     },
     "interpret": {
       "version": "3.1.1",
@@ -40703,7 +40773,8 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.0.0.tgz",
       "integrity": "sha512-SB8HNNiazAHXM1vGEzf8/tSyEhkfxuDdhYdPBX2Mwgzt0OuF2gicApQ+uvXLID/gXyJQgvrM9+1/2SxZFUUDIA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "karma-source-map-support": {
       "version": "1.4.0",
@@ -43612,14 +43683,6 @@
           "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
           "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
         },
-        "d3-interpolate": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
-          "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
-          "requires": {
-            "d3-color": "1 - 3"
-          }
-        },
         "d3-time": {
           "version": "1.1.0",
           "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
@@ -43793,13 +43856,15 @@
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
       "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-gap-properties": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz",
       "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-image-set-function": {
       "version": "4.0.7",
@@ -43825,7 +43890,8 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz",
       "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-lab-function": {
       "version": "4.2.1",
@@ -43852,19 +43918,22 @@
       "version": "5.0.4",
       "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
       "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-media-minmax": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
       "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-modules-extract-imports": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
       "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-modules-local-by-default": {
       "version": "4.0.0",
@@ -43909,7 +43978,8 @@
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz",
       "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-overflow-shorthand": {
       "version": "3.0.4",
@@ -43924,7 +43994,8 @@
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz",
       "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-place": {
       "version": "7.0.5",
@@ -44005,7 +44076,8 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz",
       "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-selector-not": {
       "version": "6.0.1",
@@ -44567,7 +44639,8 @@
     "ramda-adjunct": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-3.4.0.tgz",
-      "integrity": "sha512-qKRgqwZzJUZmPJfGK8/uLVxQXkiftKhW6FW9NUCUlQrzsBUZBvFAZUxwH7nTRwDMg+ChRU69rVVuS/4EUgtuIg=="
+      "integrity": "sha512-qKRgqwZzJUZmPJfGK8/uLVxQXkiftKhW6FW9NUCUlQrzsBUZBvFAZUxwH7nTRwDMg+ChRU69rVVuS/4EUgtuIg==",
+      "requires": {}
     },
     "randexp": {
       "version": "0.5.3",
@@ -44640,7 +44713,8 @@
           "version": "3.5.2",
           "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
           "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "json-schema-traverse": {
           "version": "0.4.1",
@@ -44746,12 +44820,14 @@
     "react-immutable-pure-component": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz",
-      "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A=="
+      "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==",
+      "requires": {}
     },
     "react-inspector": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.1.tgz",
-      "integrity": "sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg=="
+      "integrity": "sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg==",
+      "requires": {}
     },
     "react-is": {
       "version": "16.13.1",
@@ -44876,7 +44952,8 @@
     "redux-immutable": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz",
-      "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg=="
+      "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==",
+      "requires": {}
     },
     "reflect-metadata": {
       "version": "0.1.13",
@@ -45495,7 +45572,8 @@
           "version": "3.5.2",
           "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
           "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "json-schema-traverse": {
           "version": "0.4.1",
@@ -47143,7 +47221,8 @@
           "version": "3.5.2",
           "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
           "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "json-schema-traverse": {
           "version": "0.4.1",
@@ -48046,7 +48125,8 @@
     "use-sync-external-store": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
-      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="
+      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+      "requires": {}
     },
     "util": {
       "version": "0.12.5",
@@ -48663,7 +48743,8 @@
           "version": "3.5.2",
           "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
           "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "enhanced-resolve": {
           "version": "5.12.0",
@@ -49004,7 +49085,8 @@
       "version": "8.11.0",
       "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
       "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "xml": {
       "version": "1.0.1",
diff --git a/ui/package.json b/ui/package.json
index d4a70c9a54..66d18c604a 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -53,7 +53,7 @@
     "@ngx-loading-bar/core": "6.0.2",
     "@ngx-loading-bar/http-client": "6.0.2",
     "@panzoom/panzoom": "^4.5.1",
-    "@swimlane/ngx-charts": "^20.1.2",
+    "@swimlane/ngx-charts": "^20.4.1",
     "angular-datatables": "^14.0.2",
     "angular-gridster2": "^14.1.2",
     "angular-plotly.js": "^4.0.4",
@@ -110,7 +110,7 @@
     "@types/rx": "^4.1.2",
     "@types/showdown": "1.9.4",
     "@typescript-eslint/eslint-plugin": "5.57.1",
-    "@typescript-eslint/parser": "5.56.0",
+    "@typescript-eslint/parser": "5.59.11",
     "ajv-keywords": "^5.1.0",
     "assert": "^2.0.0",
     "compression-webpack-plugin": "^10.0.0",
diff --git a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
index ae13fdf966..c8029745c8 100644
--- a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
@@ -19,7 +19,7 @@
 /* tslint:disable */
 /* eslint-disable */
 // @ts-nocheck
-// Generated using typescript-generator version 3.1.1185 on 2023-06-12 22:17:35.
+// Generated using typescript-generator version 3.1.1185 on 2023-06-17 23:53:33.
 
 export class NamedStreamPipesEntity {
     '@class':
@@ -3140,6 +3140,7 @@ export class RuntimeResolvableTreeInputStaticProperty extends StaticProperty {
     '@class': 'org.apache.streampipes.model.staticproperty.RuntimeResolvableTreeInputStaticProperty';
     'dependsOn': string[];
     'latestFetchedNodes': TreeInputNode[];
+    'multiSelection': boolean;
     'nextBaseNodeToResolve': string;
     'nodes': TreeInputNode[];
     'resolveDynamically': boolean;
@@ -3161,6 +3162,7 @@ export class RuntimeResolvableTreeInputStaticProperty extends StaticProperty {
         instance.latestFetchedNodes = __getCopyArrayFn(TreeInputNode.fromData)(
             data.latestFetchedNodes,
         );
+        instance.multiSelection = data.multiSelection;
         instance.nextBaseNodeToResolve = data.nextBaseNodeToResolve;
         instance.nodes = __getCopyArrayFn(TreeInputNode.fromData)(data.nodes);
         instance.resolveDynamically = data.resolveDynamically;


Test patch:
diff --git a/streampipes-commons/src/test/java/TestResources.java b/streampipes-commons/src/test/java/TestResources.java
new file mode 100644
index 0000000000..ec7174e336
--- /dev/null
+++ b/streampipes-commons/src/test/java/TestResources.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+import org.apache.streampipes.commons.resources.Resources;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class TestResources {
+
+  @Test
+  public void testResourceLoader() throws IOException {
+    String filename = "test.txt";
+    String content = Resources.asString(filename, StandardCharsets.UTF_8);
+    assertEquals("HelloWorld", content.replaceAll("\\s+",""));
+  }
+}
diff --git a/streampipes-commons/src/test/resources/test.txt b/streampipes-commons/src/test/resources/test.txt
new file mode 100644
index 0000000000..3da1ec26e9
--- /dev/null
+++ b/streampipes-commons/src/test/resources/test.txt
@@ -0,0 +1,1 @@
+HelloWorld
diff --git a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredCsvOutputWriter.java b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredCsvOutputWriter.java
index 5b64b44218..f929f71655 100644
--- a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredCsvOutputWriter.java
+++ b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredCsvOutputWriter.java
@@ -20,11 +20,11 @@ package org.apache.streampipes.dataexplorer.query.writer;
 
 import org.apache.streampipes.dataexplorer.param.ProvidedRestQueryParams;
 
-import com.google.common.base.Charsets;
 import org.junit.Test;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 
 import static org.junit.Assert.assertEquals;
@@ -46,7 +46,7 @@ public class TestConfiguredCsvOutputWriter extends TestConfiguredOutputWriter {
       }
 
       writer.afterLastItem(outputStream);
-      assertEquals(Expected, outputStream.toString(Charsets.UTF_8));
+      assertEquals(Expected, outputStream.toString(StandardCharsets.UTF_8));
     }
   }
 }
diff --git a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredJsonOutputWriter.java b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredJsonOutputWriter.java
index 2e0431cf7e..1acecffdac 100644
--- a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredJsonOutputWriter.java
+++ b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredJsonOutputWriter.java
@@ -20,11 +20,11 @@ package org.apache.streampipes.dataexplorer.query.writer;
 
 import org.apache.streampipes.dataexplorer.param.ProvidedRestQueryParams;
 
-import com.google.common.base.Charsets;
 import org.junit.Test;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 
 import static org.junit.Assert.assertEquals;
@@ -47,7 +47,7 @@ public class TestConfiguredJsonOutputWriter extends TestConfiguredOutputWriter {
       }
 
       writer.afterLastItem(outputStream);
-      assertEquals(Expected, outputStream.toString(Charsets.UTF_8));
+      assertEquals(Expected, outputStream.toString(StandardCharsets.UTF_8));
     }
   }
 }
diff --git a/streampipes-integration-tests/pom.xml b/streampipes-integration-tests/pom.xml
index a4b05efbbb..f77c4e5b37 100644
--- a/streampipes-integration-tests/pom.xml
+++ b/streampipes-integration-tests/pom.xml
@@ -102,6 +102,11 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+        	<propertyExpansion>
+				checkstyle.config.base.path=${project.parent.basedir}/tools/maven
+            </propertyExpansion>
+        </configuration>
       </plugin>
     </plugins>
   </build>
diff --git a/streampipes-storage-couchdb/src/test/java/org/apache/streampipes/storage/couchdb/utils/TestUrlEscapers.java b/streampipes-storage-couchdb/src/test/java/org/apache/streampipes/storage/couchdb/utils/TestUrlEscapers.java
new file mode 100644
index 0000000000..50926ed4f6
--- /dev/null
+++ b/streampipes-storage-couchdb/src/test/java/org/apache/streampipes/storage/couchdb/utils/TestUrlEscapers.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.storage.couchdb.utils;
+
+import org.junit.Test;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class TestUrlEscapers {
+
+  @Test
+  public void testUrlPathEscaper() {
+    String type = "typeDummy";
+    String test = "startkey=[\"" + type + "\"]&endkey=[\"" + type + "\",{}]&include_docs=true";
+    String escaped = Utils.escapePathSegment(test);
+    String expected = "startkey=%5B%22typeDummy%22%5D&endkey=%5B%22typeDummy%22,%7B%7D%5D&include_docs=true";
+    assertEquals(expected, escaped);
+  }
+
+  @Test
+  public void testUrlPathEscaper2() {
+    String from = "fromDummy";
+    String test = "startkey=[\"" + from + "\"]&endkey=[\"" + from + "\", {}]&group=true";
+    String escaped = Utils.escapePathSegment(test);
+    String expected2 = "startkey=%5B%22fromDummy%22%5D&endkey=%5B%22fromDummy%22,%20%7B%7D%5D&group=true";
+    assertEquals(expected2, escaped);
+  }
+}