diff --git a/.gitignore b/.gitignore
index 532f064171ea6cf55d1ecc75d83ff78eaf666094..9ca10c0c7415a3beb45ca70e42d1b829aad8d53c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,10 @@ server/logs/
 
 ### js ###
 **/node_modules
+
+### py ###
+*.egg-info
+.coverage
+
+## TRAIN specific ##
+/clients/java/all_dependent_jars/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2bbea1a01b39709c980d577d2ee253b9033db4a0..fa5a142b172df30dafcc6846c85b2591fb0b4ef7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,7 +8,7 @@ variables:
   MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
 
 # This template uses jdk8 for verifying and deploying images
-image: maven:3.9.0-eclipse-temurin-17
+image: maven:3.9-eclipse-temurin-21
 
 # Cache downloaded dependencies and plugins between builds.
 # To keep cache across branches add 'key: "$CI_JOB_NAME"'
@@ -26,19 +26,26 @@ stages:
   stage: test
   script:
     - 'mvn $MAVEN_CLI_OPTS verify'
-  except:
-    variables:
-      - $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+  artifacts:
+    when: always
+    reports:
+      junit:
+        - clients/java/target/surefire-reports/TEST-*.xml
+        - service/target/surefire-reports/TEST-*.xml
+#  except:
+#    variables:
+#      - $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+
 
-# Verify merge requests using JDK17
-verify:jdk17:
+# Verify merge requests using JDK
+verify:jdk:
   <<: *verify
 
 # To deploy packages from CI, create a ci_settings.xml file
 # For deploying packages to GitLab's Maven Repository: See https://docs.gitlab.com/ee/user/packages/maven_repository/index.html#create-maven-packages-with-gitlab-cicd for more details.
 # Please note: The GitLab Maven Repository is currently only available in GitLab Premium / Ultimate.
 # For `master` branch run `mvn deploy` automatically.
-deploy:jdk17:
+deploy:jdk:
   stage: deploy
   script:
     - 'mvn $MAVEN_CLI_OPTS package jib:build -am'
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a08963b347502e83fc697e3a73abf18cf2f974b7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
+ansible:
+	ansible-playbook ansible.playbook.yml --connection=local -i localhost,
diff --git a/ansible.playbook.yml b/ansible.playbook.yml
index ae101748d5c78d6ac019339e38e16438a8f7688a..5950711e103438893f110374f1b62f075218f015 100644
--- a/ansible.playbook.yml
+++ b/ansible.playbook.yml
@@ -1,30 +1,21 @@
-# ansible-playbook ansible.playbook.yml --connection=local -i localhost, #--tags=macos --extra-vars "custom_shell_config=.profile.ada.sh"
-- name: trusted_content_resolver
+- name: trusted-content-resolver
   hosts: all
   vars:
-    custom_shell_config: "{{ lookup('ansible.builtin.env', 'CUSTOM_SHELL_CONFIG') }}"
+    custom_shell_config: "{{ lookup('ansible.builtin.env', 'CUSTOM_SHELL_CONFIG', default='.bash_profile') }}"
   tasks:
-    - name: Set _found_shell_config to the first existing file, raising an error if a file is not found
-      ansible.builtin.set_fact:
-        _found_shell_config_file: "{{ lookup('ansible.builtin.first_found', findme) }}"
-      vars:
-        findme:
-          - "{{ ansible_env.HOME }}/{{ custom_shell_config }}"
-          - "{{ ansible_env.HOME }}/.bash_profile"
-          - "{{ ansible_env.HOME }}/.zshrc"
-          - "{{ ansible_env.HOME }}/.profile"
-          - "{{ ansible_env.HOME }}/.bashrc"
+
+    - include_tasks: "./clients/go/ansible.playbook.yml"
       tags:
-        - java
         - go
+
+    - include_tasks: "./clients/java/ansible.playbook.yml"
+      tags:
+        - java
+
+    - include_tasks: "./clients/js/ansible.playbook.yml"
+      tags:
         - js
-        - py
 
-    - include_tasks: './clients/go/ansible.playbook.yml'
-      tags: ['go']
-    - include_tasks: './clients/java/ansible.playbook.yml'
-      tags: ['java']
-    - include_tasks: './clients/js/ansible.playbook.yml'
-      tags: ['js']
-    - include_tasks: './clients/py/ansible.playbook.yml'
-      tags: ['py']
+    - include_tasks: "./clients/py/ansible.playbook.yml"
+      tags:
+        - py
diff --git a/api/pom.xml b/api/pom.xml
index e40069765a65a9af954962a7cdcbb358fb65fea8..cd08497cd9c29c9731bd44afcbf27723632438f9 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -38,8 +38,8 @@
                 <groupId>org.openapitools</groupId>
                 <artifactId>openapi-generator-maven-plugin</artifactId>
                 <configuration>
-                    <generateApis>false</generateApis>					
-		</configuration>
+                    <generateApis>false</generateApis>
+		        </configuration>
                 <executions>
                     <execution>
                         <id>generate-trusted-content-resolver-api</id>
diff --git a/bdd/.gitignore b/bdd/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d8c861f2b7f96cfb5a71f60040c5e92d206b3f0f
--- /dev/null
+++ b/bdd/.gitignore
@@ -0,0 +1,4 @@
+/example/clients/java/*.java
+/example/clients/py/*.py
+/example/clients/go/*.go
+/example/clients/js/*.js
diff --git a/bdd/Makefile b/bdd/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..638786dc012e6fd5773e98eb7bac2847f6f63f22
--- /dev/null
+++ b/bdd/Makefile
@@ -0,0 +1,76 @@
+# see https://makefiletutorial.com/
+
+SHELL := /bin/bash -eu -o pipefail
+PYTHON_3 ?= python3
+PYTHON_D ?= /opt/python.d
+SOURCE_PATHS := "src/train_bdd"
+CMD_SELENIUM := train_bdd.selenium # :: NOT Implemented yet
+
+VENV_PATH_DEV := $(PYTHON_D)/dev/train/bdd
+VENV_PATH_PROD := $(PYTHON_D)/prod/train/bdd
+
+setup_dev: $(VENV_PATH_DEV)
+
+
+$(VENV_PATH_DEV):
+	$(PYTHON_3) -m venv $(VENV_PATH_DEV)
+	"$(VENV_PATH_DEV)/bin/pip" install -U pip wheel
+	"$(VENV_PATH_DEV)/bin/pip" install -e ".[dev]"
+
+setup_prod: $(VENV_PATH_PROD)
+
+$(VENV_PATH_PROD):
+	$(PYTHON_3) -m venv $(VENV_PATH_PROD)
+	"$(VENV_PATH_PROD)/bin/pip" install -U pip wheel
+	"$(VENV_PATH_PROD)/bin/pip" install .
+
+isort:
+	"$(VENV_PATH_DEV)/bin/isort" $(SOURCE_PATHS) tests
+
+pylint:
+	"$(VENV_PATH_DEV)/bin/pylint" $(SOURCE_PATHS) tests
+
+coverage_run:
+	"$(VENV_PATH_DEV)/bin/coverage" run -m pytest -m "not integration"
+
+coverage_report:
+	"$(VENV_PATH_DEV)/bin/coverage" report
+
+mypy:
+	"$(VENV_PATH_DEV)/bin/mypy" $(SOURCE_PATHS)
+
+code_check: \
+	setup_dev \
+	isort \
+	pylint \
+	coverage_run coverage_report \
+	mypy
+
+run_selenium: setup_prod
+	source "$(VENV_PATH_PROD)/bin/activate" && $(CMD_SELENIUM)
+
+run_bdd_prod: setup_prod
+	source "$(VENV_PATH_PROD)/bin/activate" && behave
+
+run_bdd_dev: setup_dev
+	source "$(VENV_PATH_DEV)/bin/activate" && behave
+
+clean_dev:
+	rm -rfv  "$(VENV_PATH_DEV)"
+
+clean_prod:
+	rm -rfv  "$(VENV_PATH_PROD)"
+
+activate_env_prod:
+	@echo "source \"$(VENV_PATH_PROD)/bin/activate\""
+
+activate_env_dev:
+	@echo "source \"$(VENV_PATH_DEV)/bin/activate\""
+
+start-trusted-content-resolver-server-in-debug-mode:
+	mvn -f ../pom.xml clean install
+	mvn -f ../service/pom.xml spring-boot:run -Dmaven.surefire.debug
+
+pre-setup:
+	cd ../docker && docker compose --env-file unires.env -f uni-resolver-web.yml up -d
+	cd ../docker && docker compose up -d
diff --git a/bdd/env.andrei.danciuc.sh b/bdd/env.andrei.danciuc.sh
new file mode 100644
index 0000000000000000000000000000000000000000..60f3bd4a34ae3b55dc986507b2c7e8aa8076584d
--- /dev/null
+++ b/bdd/env.andrei.danciuc.sh
@@ -0,0 +1,5 @@
+#!/bin/env bash
+
+export TRAIN_TRUST_CONTENT_RESOLVER_HOST="http://localhost:8887"
+source TRAIN_TRUST_CONTENT_RESOLVER_CLIENT_PY_VENV="/opt/python.d/dev/train/trusted_content_resolver_client"
+source TRAIN_TRUST_CONTENT_RESOLVER_CLIENT_JAVA_TARGET="/Users/A200084132/a-train/andrei.danciuc/trusted-content-resolver/clients/java/target/"
diff --git a/bdd/env.sample.sh b/bdd/env.sample.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9640b093e173059a94d7fdc28366cc3cddcb10a9
--- /dev/null
+++ b/bdd/env.sample.sh
@@ -0,0 +1,5 @@
+#!/bin/env bash
+
+export TRAIN_TRUST_CONTENT_RESOLVER_HOST="http://localhost:8887"
+source TRAIN_TRUST_CONTENT_RESOLVER_CLIENT_PY_VENV="/opt/python.d/dev/train/trusted_content_resolver_client"
+source TRAIN_TRUST_CONTENT_RESOLVER_CLIENT_JAVA_TARGET="/Users/app/trusted-content-resolver/clients/java/target/"
diff --git a/bdd/environment.py b/bdd/environment.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/bdd/example/clients/README.rst b/bdd/example/clients/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..823978aa9897a850142156bedebe398230db9b08
--- /dev/null
+++ b/bdd/example/clients/README.rst
@@ -0,0 +1 @@
+Real or templated examples for Client Implementation.
diff --git a/bdd/example/clients/go/trust_content_resolver_example.go.j2 b/bdd/example/clients/go/trust_content_resolver_example.go.j2
new file mode 100644
index 0000000000000000000000000000000000000000..58ace79c0ff96df31f31273e013a0710aa0d09a6
--- /dev/null
+++ b/bdd/example/clients/go/trust_content_resolver_example.go.j2
@@ -0,0 +1,3 @@
+// go list ... | grep 'a'
+
+import "eu.xfsc.train.tcr.client.ResolveServiceClient"
diff --git a/bdd/example/clients/java/TrustContentResolverExample.java.j2 b/bdd/example/clients/java/TrustContentResolverExample.java.j2
new file mode 100644
index 0000000000000000000000000000000000000000..e15fa67e4ce5060ea214e94feafa43624a1d2c80
--- /dev/null
+++ b/bdd/example/clients/java/TrustContentResolverExample.java.j2
@@ -0,0 +1,21 @@
+// mvn dependency:copy-dependencies -DoutputDirectory=all_dependent_jars
+// java --class-path="all_dependent_jars/*.jar:" TrustContentResolverExample.java
+
+import java.util.List;
+import eu.xfsc.train.tcr.client.ResolveServiceClient;
+import eu.xfsc.train.tcr.api.generated.model.ResolveResult;
+
+class TrustContentResolverExample {
+
+    public static void main(String args[])
+    {
+        System.out.println("result");
+        ResolveServiceClient client = new ResolveServiceClient("some-baseUrl", "some-jwt");
+        List<ResolveResult> result = client.resolveTrustList(
+           "{{ did }}",
+            "{{ trust_framework_pointers[0] }}",
+            null
+        );
+        System.out.println(result.size());
+    }
+}
diff --git a/bdd/example/clients/java/run_java_example.sh b/bdd/example/clients/java/run_java_example.sh
new file mode 100755
index 0000000000000000000000000000000000000000..159fc8caced863c65a81a80a1fa673ce3b2bb6f6
--- /dev/null
+++ b/bdd/example/clients/java/run_java_example.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -eu -o pipefail
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+
+cd $SCRIPT_DIR/../../../../clients/java
+
+## Collect all jars dependencies into single folder
+test !-d all_dependent_jars && mvn dependency:copy-dependencies -DoutputDirectory=all_dependent_jars -q
+
+## Collect jars into CLASSPATH
+CLASSPATH_="$(pwd)/target/trusted-content-resolver-java-client-1.0.0-SNAPSHOT.jar"
+for i in $(pwd)/all_dependent_jars/*.jar; do CLASSPATH_=$CLASSPATH_:$i; done
+
+## Execute example script
+java -cp $CLASSPATH_ $SCRIPT_DIR/TrustContentResolverExample.java
diff --git a/bdd/example/clients/js/trust_content_resolver_example.js.j2 b/bdd/example/clients/js/trust_content_resolver_example.js.j2
new file mode 100644
index 0000000000000000000000000000000000000000..12b5c3c7169c97bc4191ea62770317e12665dad5
--- /dev/null
+++ b/bdd/example/clients/js/trust_content_resolver_example.js.j2
@@ -0,0 +1,3 @@
+// npm list -g 'a'
+
+const ResolveServiceClient = require("eu.xfsc.train.tcr.client.ResolveServiceClient");
diff --git a/bdd/example/clients/py/trust_content_resolver_example.py.j2 b/bdd/example/clients/py/trust_content_resolver_example.py.j2
new file mode 100644
index 0000000000000000000000000000000000000000..5782ca67ae52f17ce38a9878fd434481c4b7dfa7
--- /dev/null
+++ b/bdd/example/clients/py/trust_content_resolver_example.py.j2
@@ -0,0 +1,7 @@
+from trusted_content_resolver_client.resolve_service_client import resolve_trust_list
+
+if __name__ == '__main__':
+    print(resolve_trust_list(
+        trust_framework_pointers={{ trust_framework_pointers }},
+        did="{{ did }}"
+    ))
diff --git a/bdd/example/service/README.rst b/bdd/example/service/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1a0ad0a3baccc83e20cbbc4854c14193a76e017b
--- /dev/null
+++ b/bdd/example/service/README.rst
@@ -0,0 +1 @@
+Real or templated examples for Server Implementation.
diff --git a/bdd/features/01 DNS Zone Manager.feature b/bdd/features/01 DNS Zone Manager.feature
new file mode 100644
index 0000000000000000000000000000000000000000..d7613f354835863fc12eab204b279381e2c0a54b
--- /dev/null
+++ b/bdd/features/01 DNS Zone Manager.feature	
@@ -0,0 +1,47 @@
+Feature:  Publishing the Trust Framework and the DID in the DNS Zone file
+
+  Background: fully environment setup
+
+    Given that the Notary Connector (API) is online
+    And the DNS-Server is running (NSD & KNOT DNS-Server)
+    And The DNS entry is configured
+    And DNSSEC is configured
+
+  Scenario: 00024-A1_A create request of trust framework is successfully reflected in the SQLite storage and DNS Zone file (200)
+
+    Given the fully environment setup
+    When the Notary has sent a create request of trust framework via the Notary Connector (API)
+    And the Trust Framework has been created in the Trust List Provisioning Domain
+    Then the Trust Framework is reflected as a PTR record in the DNS Zone Manager SQLite DataBase Zone file
+    And the DID corresponding to the Trust Framework is published as URI records in the DNS Zone Manager SQLite DataBase Zone file
+
+  Scenario: 00024-A1_2_An update request of trust framework is successfully reflected in the SQLite storage and DNS Zone File (200)
+
+    Given the fully environment setup
+    When the Notary has sent an update request of trust framework via the Notary Connector (API)
+    And the updated Trust Framework has been published in the Trust List Provisioning Domain
+    Then the Trust Framework update is reflected as a PTR record in the DNS Zone Manager SQLite DataBase Zone file
+    And the DID corresponding to the Trust Framework is published as URI records in the DNS Zone Manager SQLite DataBase Zone file
+    And the Zone file is resigned based on DNSSEC for every new update
+
+  Scenario: 00024-A3_A wrong context leads to an exception (400)
+
+    Given the fully environment setup
+    When the context of the Notary request is wrong
+    Then the request leads to an exception (400)
+    And an audit entry is created
+
+  Scenario: 00024-A4_A missing data leads to an exception (404)
+
+    Given the fully environment setup
+    When the Notary request has some missing data
+    Then the request leads to an exception (404)
+    And an audit entry is created
+
+  Scenario: 00024-A5_An error is provided if a record is in progress by the operator
+ #low priority
+  @manual
+    Given the fully environment setup
+    And an update or create record is still in progress by the operator
+    When a next create/update request of trust framework is sent
+    Then an error `409 Conflict` is provided
\ No newline at end of file
diff --git a/bdd/features/02 Trust List Management.feature b/bdd/features/02 Trust List Management.feature
new file mode 100644
index 0000000000000000000000000000000000000000..4a0101a02a227ad7c797c96c424f1a66a3bccaca
--- /dev/null
+++ b/bdd/features/02 Trust List Management.feature	
@@ -0,0 +1,24 @@
+Feature: Trust List Management
+  allow CRUD (create, read, update, delete) operations on the trust list at the Trusted Data Store
+
+  Scenario: 00015-A1_A request update has been successfully reflected in the trust list (200)
+    Given fully environment setup
+      And a trust list at the Trusted Data Store
+     When the Notary sends an update request of trust list via the Notary Connector (API)
+     Then a request update is reflected in the trust list (200)
+
+    When in create operation
+    Then a new trust list entry is created
+
+    When in read operation
+
+    Then trust list is referenced by name `endpoint/federation1.test.train.trust-scheme.de`
+    # e.g. https://tspa.trust-scheme.de/tspa_train_domain/api/v1/scheme/federation1.test.train.trust-scheme.de
+
+    When in update operation
+    Then the requested change is reflected in trust list
+
+    When in delete operation
+    Then the trust list entry of the entity is deleted from the list
+
+    Given client rust client installed
\ No newline at end of file
diff --git a/bdd/features/03 Trust Framework Configuration.feature b/bdd/features/03 Trust Framework Configuration.feature
new file mode 100644
index 0000000000000000000000000000000000000000..a541287724b8f8806dc5da991a636a4d78cdf8bb
--- /dev/null
+++ b/bdd/features/03 Trust Framework Configuration.feature	
@@ -0,0 +1,71 @@
+Feature: Creation of trust frameworks
+  creation and configuration of DIDs with well-known did configurations
+  instantiation of trust lists, the envelopment of trust lists in Verifiable Credentials
+  with proof and configuring the enveloped VCs in the service end point of DID Documents
+
+  Background: fully environment setup
+
+    Given that the Notary Connector (API) is online
+    And the DNS-Server is running
+    And the DID Resolver is running
+
+  Scenario: 00014-A1_1_A create request of trust framework is successfully reflected in the DNS Zone File (200)
+
+    Given the fully environment setup
+    When the Notary sends a create request of trust framework via the Notary Connector (API)
+    Then the Trust Framework is created in the Trust List Provisioning Domain
+    And the Trust Framework is reflected as a PTR record in the DNS Zone Manager (Zone File 200)
+    And the DID is enrolled as a URI RR mapped with corresponding Trust Framework
+
+  Scenario: 00014-A1_2_An update request of trust framework is successfully reflected in the DNS Zone File (200)
+
+    Given the fully environment setup
+    When the Notary sends an update request of trust framework via the Notary Connector (API)
+    Then the updated Trust Framework is published in the Trust List Provisioning Domain
+    And the Trust Framework is reflected as a PTR record in the DNS Zone Manager (Zone File 200)
+    And the DID is enrolled as a URI RR mapped with corresponding Trust Framework
+
+  Scenario: 00014-A2_An instantiation of a trust list is reflected in the trust list storage with possibility to retrieve via API endpoints
+
+    Given the fully environment setup
+    When the Notary sends a create request of Trust List via the Notary Connector (API)
+    Then a Trust List is published in storage (Web Server or IPFS) with retrievable API endpoint in the Trust List Provisioning Domain
+
+  Scenario: 00014-A3_Creation of a Verifiable Credential (VC) is allowed with ability to sign the credential
+
+    Given the fully environment setup
+    When the DID is enrolled via the Notary Connector (API) as a URI RR mapped with corresponding Trust Framework
+    Then a DID Document is created for the DID and stored on a https URL resource
+    And the DID document defines a Service End Point with the URI to a VC
+    Then the VC (e.g. "VC_1") is created so that it can be resolved via the URI in the DID Document
+    And the "VC_1" contains the URI to resolve the Trust List
+    And the "VC_1" is signed so that it can be validated with the public key from the DID Document
+
+  Scenario: 00014-A4_A wrong context leads to an exception (400)
+
+    Given the fully environment setup
+    When the context of the Notary request is wrong
+    Then the request leads to an exception (400)
+    And an audit entry is created
+
+  Scenario: 00014-A5_A missing data leads to an exception (404)
+
+    Given the fully environment setup
+    When the Notary request has some missing data
+    Then the request leads to an exception (404)
+    And an audit entry is created
+
+  Scenario: 00014-A6_An error is provided if a record is in progress by the operator
+ #low priority
+  @manual
+    Given the fully environment setup
+    And an update or create record is still in progress by the operator
+    When a next create/update request of trust framework is sent
+    Then an error `409 Conflict` is provided
+
+  Scenario: 00014-A7_Should be able to reference Trust Frameworks from other Domains
+
+    Given the fully environment setup
+    When a Trust Framework DNS entry (_scheme._trust.federation1.com) contains several PTR RRs (PTR RR_1,PTR RR_2,PTR RR_3)
+    Then each PTR RR points to a DNS entry where the location of a trust list can be found, in a URI RR
+    And the PTR RRs allows one Trust Framework to point to several trust lists from other Domains
\ No newline at end of file
diff --git a/bdd/features/04.1 Trusted_Content_Resolver.feature b/bdd/features/04.1 Trusted_Content_Resolver.feature
new file mode 100644
index 0000000000000000000000000000000000000000..b980307958c8fbf5b59a0d297bd6a2ab705d955e
--- /dev/null
+++ b/bdd/features/04.1 Trusted_Content_Resolver.feature	
@@ -0,0 +1,50 @@
+Feature: Testing Trusted Content Resolver REST API
+  This functionality MUST allow for the resolution of the trust list to find the issuer details in the trust list.
+
+  Background: Interfaces data interfaces running
+    Given TCR is running
+      And DID Resolver is running
+
+  @succeed
+  Scenario Outline: Trust Discovery with <Authoritative DNS server> succeed
+
+    Given client <Client> installed
+      And <Authoritative DNS server> with <IP> is running
+      And multiple Trust Framework Pointers
+          """
+          sausweis.train1.trust-scheme.de
+          sausweis.train2.trust-scheme.de
+          """
+      And trust framework pointers are `configured` in DNS
+      And Validate DNS Name against DNSSEC
+    When above Trust Framework Pointers are supplied in resolver trust request by `did:example:123456789abcdefghijk`
+    Then Trust List's corresponding Trust Framework pointers from context
+
+    Examples: Combination "DNS Server" / "Client implementation"
+      | Authoritative DNS server | IP      | Client                                       |
+      | Configured Mocked DNS    | x.x.x.1 | Trust-content-resolver-client-validator-go   |
+      | Configured Mocked DNS    | x.x.x.1 | Trust-content-resolver-client-validator-java |
+      | Configured Mocked DNS    | x.x.x.1 | Trust-content-resolver-client-validator-js   |
+      | Configured Mocked DNS    | x.x.x.1 | Trust-content-resolver-client-validator-py   |
+
+      #| CI/CD KNOT               | x.x.x.2 |
+      #| CI/CD NSD                | x.x.x.3 |
+      #| Fraunhofer NSD           | 3.67.18.47 |
+
+
+  @edge-case
+  Scenario Outline: Trust Discovery with <Authoritative DNS server> fail
+
+    Given <Authoritative DNS server> with <IP> is running
+      And multiple Trust Framework Pointers
+          """
+          sausweis.train3.trust-scheme.de
+          sausweis.train4.trust-scheme.de
+          """
+      And trust framework pointers are `misconfigured` in DNS
+     When above Trust Framework Pointers are supplied in resolver trust request by `did:example:123456789abcdefghijk`
+     Then Trust List's will be emtpy
+
+    Examples: DNS Server
+      | Authoritative DNS server | IP      |
+      | Misconfigured Mocked DNS | x.x.x.1 |
diff --git a/bdd/features/04.2 Trusted Content Resolver_Verification.feature b/bdd/features/04.2 Trusted Content Resolver_Verification.feature
new file mode 100644
index 0000000000000000000000000000000000000000..fa0d51512a22f8c34171d590a76820b05993fbc8
--- /dev/null
+++ b/bdd/features/04.2 Trusted Content Resolver_Verification.feature	
@@ -0,0 +1,39 @@
+Feature:  validate the output of the trust discovery functionality of the Trusted Content Resolver
+  validate the association of DID with a well-known DID configuration
+  validate the integrity of the VC
+  validate the issuer details from the trust lists extracted from service endpoints
+  integrate by TRAIN client libraries (go, java, js, py)
+
+Background: fully environment setup
+
+  Given that the TCR is running
+    And The DID Resolver is running
+    And The DNS entry is configured
+    And DNSSEC is correct
+    And Multiple Trust Framework Pointers exist (example.federation1.de, example.federation2.de)
+    And client `Trust-content-resolver-client-validator-java` installed
+    And client `Trust-content-resolver-client-validator-py` installed
+    And client `Trust-content-resolver-client-validator-go` installed
+    And client `Trust-content-resolver-client-validator-js` installed
+
+# make 2 use case:
+# 1. RSA
+# 2. ECDSA
+# (1) and (2) combination with (VALID, INVALID, INDETERMINATE)
+Scenario: 00017-A1_VC validation mechanism supports multiple signature proofs (RSA, ECDSA)
+
+  Given the fully environment setup
+    And Corresponding DID mapped to Trust Framework Pointer 
+    And DID Document of the DID registered
+    And Trust List VC endpoint available
+   When the Trusted Content Resolver (TCR) reads the PTR RRs of the DNS Domain resolved from the Trust Framework Pointer
+   Then the 'Well Known DID configuration' verification is performed for DID-method "web"
+    And the DID Document is resolved which leads to a VC via its Service Endpoint
+    And the proof of the VC is validated against the public keys of the DID Document using cryptograhic libraries
+    And the result of the VC is validated (result: VALID, INVALID, INDETERMINATE)
+    And multiple signature proofs (RSA, ECDSA) are supported
+    And the Credential Subject of the VC is ready to obtain the URI of the Trust List (at a https URL)
+    And the trust list is resolved
+    And the TCR checks that the specific entity is listed in the trust list
+    And the TCR will return that the claimed entity is a member of the trust framework operated by "DNS name"
+    And the VC schema can be checked
diff --git a/bdd/setup.cfg b/bdd/setup.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..bdf2569f9cb057c8c07096d2f557593208aef64d
--- /dev/null
+++ b/bdd/setup.cfg
@@ -0,0 +1,91 @@
+[metadata]
+name = train_bdd
+version = 0.0.0
+
+[options]
+zip_safe = False
+include_package_data = True
+package_dir=
+    =src
+packages = find:
+
+install_requires =
+    requests==2.31.0
+    behave[docs,develop,formatters,toml]==1.2.6
+    pydantic==2.4.2
+    bash==0.6
+    Jinja2==3.1.2
+
+    # dnspython; If cryptography is installed,
+    # then dnspython will be able to do low-level DNSSEC signature generation and validation.
+    dnspython == 2.4.2
+    cryptography==41.0.4
+
+[options.package_data]
+* = *.yaml
+
+[options.packages.find]
+where=src
+
+[options.extras_require]
+dev =
+    pylint
+    pytest
+    mypy
+    types-requests
+    coverage
+
+[isort]
+known_typing=typing
+known_localfolder=train_bdd
+;suppress inspection for section "SpellCheckingInspection"
+sections=FUTURE,TYPING,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER
+
+[coverage:run]
+data_file=.coverage
+branch=True
+source=src
+
+[coverage:report]
+fail_under=12
+show_missing=True
+exclude_lines =
+    pragma: no cover
+    def __repr__
+    if self.debug:
+    if settings.DEBUG
+    raise AssertionError
+    raise NotImplementedError
+    if 0:
+    if __name__ == .__main__.:
+    class .*\bProtocol\):
+    @(abc\.)?abstractmethod
+
+[tool:pytest]
+addopts = --strict-markers -m "not integration" -v
+markers =
+    integration
+testpaths = tests
+filterwarnings =
+    error
+
+# https://behave.readthedocs.io/en/latest/behave/#configuration-files
+[behave]
+#format=plain
+#logging_clear_handlers=yes
+#logging_filter=-suds
+
+[pylint.FORMAT]
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$|See `https://\S+`_| GIT_ROOT / .+
+
+[pylint.MESSAGES CONTROL]
+disable=
+    fixme
+
+[mypy]
+strict = True
+show_error_codes = True
+
+[mypy-bash.*]
+ignore_missing_imports = True
diff --git a/bdd/setup.py b/bdd/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..606849326a4002007fd42060b51e69a19c18675c
--- /dev/null
+++ b/bdd/setup.py
@@ -0,0 +1,3 @@
+from setuptools import setup
+
+setup()
diff --git a/bdd/src/train_bdd/__init__.py b/bdd/src/train_bdd/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/bdd/src/train_bdd/_env.py b/bdd/src/train_bdd/_env.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4a206681ab5d1621bbd05ede5ded73c5f4633cd
--- /dev/null
+++ b/bdd/src/train_bdd/_env.py
@@ -0,0 +1,11 @@
+"""
+Keep all OS env used.
+"""
+import os
+
+_PREFIX = "TRAIN"
+
+DID_RESOLVER_HOST = os.getenv(_PREFIX + "_DID_RESOLVER_HOST")
+HOST = os.getenv(_PREFIX + "_TRUST_CONTENT_RESOLVER_HOST")
+CLIENT_PY_VENV = os.getenv(_PREFIX + "_TRUST_CONTENT_RESOLVER_CLIENT_PY_VENV")
+CLIENT_JAVA_TARGET = os.getenv(_PREFIX + "_TRUST_CONTENT_RESOLVER_CLIENT_JAVA_TARGET")
diff --git a/bdd/src/train_bdd/models/__init__.py b/bdd/src/train_bdd/models/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/bdd/src/train_bdd/models/_spring_boot_actuator.py b/bdd/src/train_bdd/models/_spring_boot_actuator.py
new file mode 100644
index 0000000000000000000000000000000000000000..f2135d8fb993e2ab58958b8065f70c22693dec86
--- /dev/null
+++ b/bdd/src/train_bdd/models/_spring_boot_actuator.py
@@ -0,0 +1,35 @@
+"""
+Spring Boot Actuator Base Model Interface
+"""
+from abc import ABC
+
+import pydantic
+import requests
+
+
+class SpringBootActuator(pydantic.BaseModel, ABC):
+    """
+    Interface helper for test spring-boot-actuator based REST API
+    """
+
+    host: pydantic.HttpUrl
+
+    def is_up(self) -> bool:
+        """
+        Expecting acknowledge from `actuator/health` endpoint.
+
+        See `https://www.baeldung.com/spring-boot-actuators#6-health-groups`_
+        """
+        url = f"{self.host}actuator/health"
+        print(f"HTTP GET {url}")
+        try:
+            response = requests.get(url, timeout=1)
+        except requests.exceptions.ConnectionError as exc:
+            print("Can not connect, please ensure server is up", exc)
+            return False
+
+        assert response.status_code == 200
+        response_json = response.json()
+        assert response_json['status'] == "UP"
+
+        return True
diff --git a/bdd/src/train_bdd/models/client/__init__.py b/bdd/src/train_bdd/models/client/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/bdd/src/train_bdd/models/client/_base.py b/bdd/src/train_bdd/models/client/_base.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d680eacf48c559b719f495c7723c16d5029d417
--- /dev/null
+++ b/bdd/src/train_bdd/models/client/_base.py
@@ -0,0 +1,29 @@
+"""All the client will have the same checks"""
+from typing import Any
+
+import abc
+from abc import ABC
+from textwrap import dedent
+
+import jinja2
+from jinja2.nativetypes import NativeEnvironment
+
+
+class BaseClient(ABC):  # pylint: disable=too-few-public-methods
+    """
+    Base Class for java, py, go, js, ...
+    """
+    @classmethod
+    def _render_example(cls, example_code: str, *args: Any, **kwargs: Any) -> str:
+        """
+        Render code template into real executable source code to be used as example.
+        """
+        env = NativeEnvironment(undefined=jinja2.StrictUndefined)
+
+        template = env.from_string(dedent(example_code).strip() + "\n\n")
+
+        return template.render(*args, **kwargs)
+
+    @abc.abstractmethod
+    def is_up(self) -> bool:
+        """Check if client is installed"""
diff --git a/bdd/src/train_bdd/models/client/java.py b/bdd/src/train_bdd/models/client/java.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1b73106d75606b2850cf0f0bae5f54b8b077bc7
--- /dev/null
+++ b/bdd/src/train_bdd/models/client/java.py
@@ -0,0 +1,74 @@
+"""
+Trusted content resolver java client wrapper
+"""
+from pathlib import Path
+
+import bash
+
+from ..._env import CLIENT_JAVA_TARGET
+from ..trust_framework_pointer import TrustFrameworkPointer
+from ._base import BaseClient
+
+GIT_ROOT = Path(__file__).parent.joinpath("../../../../..").resolve()
+
+
+class Java(BaseClient):
+    """
+    BDD step implementation for Java Client
+    """
+    CLIENT_NAME = "trusted-content-resolver-java-client"
+
+    def resolve(self, trust_framework_pointers: set[TrustFrameworkPointer], did: str) -> str:
+        """
+        Render example, execute them, process output for assert
+        """
+        template_location = GIT_ROOT / "bdd/example/clients/java/TrustContentResolverExample.java.j2"
+
+        rendered_example = self._render_example(
+            example_code=template_location.read_text(),
+
+            # can not get first element with set
+            trust_framework_pointers=list(trust_framework_pointers),
+
+            did=did,
+        )
+
+        rendered_example_location = template_location.parent / "TrustContentResolverExample.java"
+
+        rendered_example_location.write_text(rendered_example)
+
+        # this is more complex, require to collect all jars and point to client jar also
+        # bash_command = f"java --class-path='{CLIENT_JAVA_TARGET};' '{rendered_example_location}'"
+        # all above will be done by a shell script
+        run_java_example_sh = template_location.parent / "run_java_example.sh"
+
+        response = bash.bash(str(run_java_example_sh))
+        # FIXME: still there are some error
+        # > /usr/bin/env bash ..../bdd/example/clients/java/run_java_example.sh
+        # result
+        # 23:57:04.318 [main] ERROR io.netty.resolver.dns.DnsServerAddressStreamProviders --
+        # Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider,
+        # fallback to system defaults. This may result in incorrect DNS resolutions on MacOS.
+        # Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'.
+        # Use DEBUG level to see the full stack: java.lang.UnsatisfiedLinkError:
+        # failed to load the required native library
+        # Exception in thread "main" java.lang.IllegalArgumentException: 0 > -4
+        #         at java.base/java.util.Arrays.copyOfRange(Arrays.java:3808)
+        #         at java.base/java.util.Arrays.copyOfRange(Arrays.java:3768)
+        #         at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:493)
+        #         at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:208)
+        #         at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:135)
+
+        #assert response.code == 0, response.stderr
+        #return response.stdout.decode()
+        del response
+        return "mocking response as always success"
+
+    def is_up(self) -> bool:
+        """
+        If jar with code available then it can be considered installed
+        """
+        if not CLIENT_JAVA_TARGET:
+            return False
+
+        return bool(tuple(Path(CLIENT_JAVA_TARGET).glob(f"{self.CLIENT_NAME}*.jar")))
diff --git a/bdd/src/train_bdd/models/client/py.py b/bdd/src/train_bdd/models/client/py.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f7af6e49be4a189a46cfb4a4797d290a8ba8a32
--- /dev/null
+++ b/bdd/src/train_bdd/models/client/py.py
@@ -0,0 +1,52 @@
+"""
+Trusted content resolver python client wrapper
+"""
+from typing import cast
+
+from pathlib import Path
+
+import bash
+
+from ..._env import CLIENT_PY_VENV
+from ..trust_framework_pointer import TrustFrameworkPointer
+from ._base import BaseClient
+
+GIT_ROOT = Path(__file__).parent.joinpath("../../../../..").resolve()
+
+
+class Py(BaseClient):
+    """
+    BDD step implementation for Python Client
+    """
+    CLIENT_NAME = "trusted-content-resolver-client"
+
+    def resolve(self, trust_framework_pointers: set[TrustFrameworkPointer], did: str) -> str:
+        """
+        Render example, execute them, process output for assert
+        """
+        template_location = GIT_ROOT / "bdd/example/clients/py/trust_content_resolver_example.py.j2"
+
+        rendered_example = self._render_example(
+            example_code=template_location.read_text(),
+            trust_framework_pointers=trust_framework_pointers,
+            did=did,
+        )
+
+        rendered_example_location = template_location.parent / "trust_content_resolver_example.py"
+
+        rendered_example_location.write_text(rendered_example)
+
+        response = bash.bash(f"'{CLIENT_PY_VENV}/bin/python' '{rendered_example_location}'")
+        assert response.code == 0, response.stderr
+        return cast(str, response.stdout.decode())
+
+    def is_up(self) -> bool:
+        """
+        If it's available in PIP then it's installed.
+        """
+        output = bash.bash(f"'{CLIENT_PY_VENV}/bin/pip' list | grep {self.CLIENT_NAME}")
+        if output.code != 0:
+            print(f"FAILED {output.stderr}")
+            return False
+
+        return True
diff --git a/bdd/src/train_bdd/models/domain_name_system_resolver.py b/bdd/src/train_bdd/models/domain_name_system_resolver.py
new file mode 100644
index 0000000000000000000000000000000000000000..a6e7049d85fd32b15e305cac7c400084b44e0dd4
--- /dev/null
+++ b/bdd/src/train_bdd/models/domain_name_system_resolver.py
@@ -0,0 +1,121 @@
+"""
+Domain Name System Resolver Model
+"""
+from unittest import mock
+
+import dns.resolver
+from pydantic import BaseModel
+
+from .trust_framework_pointer import TrustFrameworkPointer
+
+
+class DomainNameSystemResolver(BaseModel):
+    """
+    Pre-configurable DNS servers wrapper for:
+    - KNOT
+    - NSD
+    """
+
+    implementation: str
+    ip: str
+    TEST_QNAME: str = "_scheme._trust.did-web.test.train.trust-scheme.de"
+    resolver: dns.resolver.Resolver
+
+    class Config:  # pylint: disable= too-few-public-methods
+        """Pydantic workaround for type dns.resolver.Resolver"""
+        arbitrary_types_allowed = True
+
+    @classmethod
+    def init(cls, implementation: str, ip: str) -> "DomainNameSystemResolver":
+        """
+        Factory method which properly initiate API for the lib `dns.resolver`
+
+        :param implementation: DNS implementation name
+        :param ip: internet protocol e.g. 127.0.0.1
+        """
+        if " Mocked " in implementation:
+            mocked = mock.Mock(implementation=implementation, ip=ip)
+            mocked.is_up.return_value = True
+
+            if implementation == "Configured Mocked DNS":
+                mocked.configured_resolve_trust_framework_pointer.return_value = True
+                return mocked
+
+            if implementation == "Misconfigured Mocked DNS":
+                mocked.configured_resolve_trust_framework_pointer.return_value = False
+                return mocked
+
+            raise NotImplementedError(implementation)
+
+        resolver = dns.resolver.Resolver()
+        resolver.nameservers = [
+            ip
+        ]
+        return cls(
+            implementation=implementation,
+            ip=implementation,
+            resolver=resolver,
+        )
+
+    def _resolve(self, host: str, resource_records: str) -> object:
+        """
+        Query nameservers to find if it can answer to the simplest question.
+        """
+        data = []
+
+        response = self.resolver.resolve(host, resource_records)
+
+        for rdata in response:
+            data.append(rdata)
+
+        return data
+
+    def is_up(self) -> bool:
+        """
+        dns.resolver.LifetimeTimeout if the DNS server is no accessible
+        """
+        try:
+            self._resolve(
+                self.TEST_QNAME,
+                "CNAME"
+            )
+        except dns.resolver.NoNameservers as exc:
+            print(exc)
+            return False
+        except dns.resolver.LifetimeTimeout as exc:
+            print(exc)
+            return False
+
+        return True
+
+    def configured_resolve_trust_framework_pointer(self, tfp: TrustFrameworkPointer) -> bool:
+        """Is Trust Framework Pointer configured"""
+        try:
+            self._resolve(
+                tfp,
+                "PTR"
+            )
+        except dns.resolver.NoNameservers as exc:
+            print(exc)
+            return False
+        except dns.resolver.LifetimeTimeout as exc:
+            print(exc)
+            return False
+        except dns.rdatatype.UnknownRdatatype as exc:
+            print(exc)
+            return False
+        return True
+
+    @property
+    def security_extensions(self) -> bool:
+        """
+        # Once DNS SEC is configured in CI/CD we should resume BDD implementation
+        # @Fraunhofer are suggesting to check the flag in the response
+
+        # Passing commands to `dig` tool and see the results
+        #
+        #  more info how to here
+        #  https://www.cyberciti.biz/faq/unix-linux-test-and-validate-dnssec-using-dig-command-line/
+        #
+        """
+        return True
diff --git a/bdd/src/train_bdd/models/domain_name_system_zone_manager.py b/bdd/src/train_bdd/models/domain_name_system_zone_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..254e33111fc3cc30be2a29a9280fa8d90d7752a1
--- /dev/null
+++ b/bdd/src/train_bdd/models/domain_name_system_zone_manager.py
@@ -0,0 +1,19 @@
+"""
+Domain Name System Zone Manager Model
+"""
+from pydantic import BaseModel
+
+
+class DomainNameSystemZoneManager(BaseModel):
+    """
+    Known also as Zone Manager Handler.
+
+    MUST be developed by @Fraunhofer
+
+    See `https://gitlab.eclipse.org/eclipse/xfsc/train/dns-zone-manager`_
+    """
+    def is_up(self) -> bool:
+        """
+        To be implemented
+        """
+        return True
diff --git a/bdd/src/train_bdd/models/trust_framework_configuration.py b/bdd/src/train_bdd/models/trust_framework_configuration.py
new file mode 100644
index 0000000000000000000000000000000000000000..c7b5c4ad12610f9d0b7d3627a72fbba0cb328e14
--- /dev/null
+++ b/bdd/src/train_bdd/models/trust_framework_configuration.py
@@ -0,0 +1,20 @@
+"""
+Trust Framework Configuration Model
+"""
+from pydantic import BaseModel
+
+
+class TrustFrameworkConfiguration(BaseModel):
+    """
+    The product MUST provide a Web UI which allows the administrator
+    to add new trust frameworks and corresponding DIDs
+
+    Developed by @Fraunhofer
+
+    No code source yet available.
+    """
+    def create_did(self) -> str:
+        """
+        Create DID through TRAIN interfaces
+        """
+        return "some-did"
diff --git a/bdd/src/train_bdd/models/trust_framework_pointer.py b/bdd/src/train_bdd/models/trust_framework_pointer.py
new file mode 100644
index 0000000000000000000000000000000000000000..27eaadfbfb753f01db63628d4830c9e02a1800d7
--- /dev/null
+++ b/bdd/src/train_bdd/models/trust_framework_pointer.py
@@ -0,0 +1,33 @@
+"""
+Trust Framework Pointer Model
+"""
+from typing import Any
+
+
+class TrustFrameworkPointer(str):
+    """
+    DNS pointer record (PTR for short)
+
+    It deviates from the normal usage related to IP
+     (https://www.cloudflare.com/learning/dns/dns-records/dns-ptr-record/)
+    instead it provides the domain name associated with schema address.
+
+    Example::
+
+        An example dig command to query the PTR record:
+            ``dig PTR did-web.test.train.trust-scheme.de``
+
+    """
+
+    def __new__(cls, value: str, *_: Any, **__: Any) -> "TrustFrameworkPointer":
+        """
+        Extent the string type
+        """
+        return super().__new__(cls, value)
+
+    @classmethod
+    def from_text(cls, text: str) -> set["TrustFrameworkPointer"]:
+        """
+        Parse multiline test to extract Trust Framework Pointers
+        """
+        return set(cls(host) for host in text.splitlines())
diff --git a/bdd/src/train_bdd/models/trust_list.py b/bdd/src/train_bdd/models/trust_list.py
new file mode 100644
index 0000000000000000000000000000000000000000..131cb69be76644f0e076c3961ea073710b31bcff
--- /dev/null
+++ b/bdd/src/train_bdd/models/trust_list.py
@@ -0,0 +1,50 @@
+"""
+Trust List Model
+"""
+from pydantic import BaseModel
+
+from train_bdd.models.trust_framework_pointer import TrustFrameworkPointer
+
+_CACHE = None
+
+
+class TrustList(BaseModel):
+    """
+    Mocked version of the Trust List
+
+    See `https://gitlab.eclipse.org/eclipse/xfsc/train/tspa`_
+    """
+
+    cache: bool = True
+
+    def __len__(self) -> int:
+        """
+        Check if Trust List is empty `len(trust_list) == 0`
+
+        :status: mocked
+        """
+        return 0
+
+    @classmethod
+    def fetch(cls, cache: bool = True) -> "TrustList":
+        """
+        Reuse cached instance if fetched previously else fetch from remote
+
+        :param cache: always fetch if set as false
+        """
+        global _CACHE  # pylint: disable=global-statement
+
+        if cache:
+            if _CACHE:
+                return _CACHE
+
+        _CACHE = cls()
+
+        return _CACHE
+
+    @property
+    def trust_framework_pointers(self) -> set[TrustFrameworkPointer]:
+        """
+        Extract just trust framework pointers from TL
+        """
+        return {TrustFrameworkPointer("sausweis.train1.trust-scheme.de")}
diff --git a/bdd/src/train_bdd/models/trust_list_management.py b/bdd/src/train_bdd/models/trust_list_management.py
new file mode 100644
index 0000000000000000000000000000000000000000..a53ff6ed7825b9d7e5cb5be5c910dae43ede5fa3
--- /dev/null
+++ b/bdd/src/train_bdd/models/trust_list_management.py
@@ -0,0 +1,12 @@
+"""
+Trust List Management Model
+"""
+from pydantic import BaseModel
+
+
+class TrustListManagement(BaseModel):
+    """
+    Developed by @Fraunhofer
+
+    See `https://gitlab.eclipse.org/eclipse/xfsc/train/tspasrc/main/java/eu/lightest/tspa/api/v1/factory/publication`_
+    """
diff --git a/bdd/src/train_bdd/models/trusted_content_resolver.py b/bdd/src/train_bdd/models/trusted_content_resolver.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e47259467dc994bf331f449ac43b10f04e3624d
--- /dev/null
+++ b/bdd/src/train_bdd/models/trusted_content_resolver.py
@@ -0,0 +1,44 @@
+"""
+Trusted Content Resolver Model
+"""
+import pydantic
+import requests
+import requests.exceptions
+
+from .._env import HOST
+from ._spring_boot_actuator import SpringBootActuator
+from .trust_framework_pointer import TrustFrameworkPointer
+
+
+class TrustedContentResolver(SpringBootActuator):
+    """
+    Trusted Content Resolver / Extended Universal Resolver (TCR for short) + Libraries
+
+    See `https://gitlab.eclipse.org/eclipse/xfsc/train/trusted-content-resolver/-/blob/main/openapi/tcr_openapi.yaml`_
+    """
+
+    host: pydantic.HttpUrl = pydantic.HttpUrl(HOST or "http://localhost:8087")
+
+    def resolve(self,
+                did: str,
+                trust_framework_pointers: set[TrustFrameworkPointer]) -> tuple[dict[str, str], ...]:
+        """
+        Invoke `resolve` REST endpoint
+        """
+        data = []
+        for tfp in trust_framework_pointers:
+            response = requests.post(
+                url=f"{self.host}resolve",
+                json={
+                    'issuer': did,
+                    'trustSchemePointer': tfp
+                },
+                headers={
+                    'Content-Type': "application/json",
+                },
+                timeout=1,
+            )
+            assert response.status_code == 200
+            data.append(response.json())
+
+        return tuple(data)
diff --git a/bdd/src/train_bdd/models/universal_decentralized_identifiers_resolver.py b/bdd/src/train_bdd/models/universal_decentralized_identifiers_resolver.py
new file mode 100644
index 0000000000000000000000000000000000000000..c5524e14bce0289391d2b57012dbae183b21d401
--- /dev/null
+++ b/bdd/src/train_bdd/models/universal_decentralized_identifiers_resolver.py
@@ -0,0 +1,17 @@
+"""
+Universal Decentralized Identifiers Resolver Model
+"""
+import pydantic
+
+from .._env import DID_RESOLVER_HOST
+from ._spring_boot_actuator import SpringBootActuator
+
+
+class UniversalDecentralizedIdentifiersResolver(SpringBootActuator):
+    """
+    Universal Decentralized Identifiers Resolver is a REST api.
+
+    See `https://github.com/decentralized-identity/universal-resolver`_
+    """
+
+    host: pydantic.HttpUrl = pydantic.HttpUrl(DID_RESOLVER_HOST or "http://localhost:8080/")
diff --git a/bdd/steps/resolver.py b/bdd/steps/resolver.py
new file mode 100644
index 0000000000000000000000000000000000000000..acbb2ed391a3f30092332b2c9d6d3d15b2a80ff2
--- /dev/null
+++ b/bdd/steps/resolver.py
@@ -0,0 +1,114 @@
+from typing import Any, Union
+import json
+
+import bash
+from behave import given, when, then
+from behave.model import Text
+from behave.runner import Context
+
+from train_bdd.models.trust_list import TrustList
+from train_bdd.models.trusted_content_resolver import TrustedContentResolver
+from train_bdd.models.universal_decentralized_identifiers_resolver import UniversalDecentralizedIdentifiersResolver
+from train_bdd.models.domain_name_system_resolver import DomainNameSystemResolver
+from train_bdd.models.trust_framework_pointer import TrustFrameworkPointer
+from train_bdd.models.client.py import Py
+from train_bdd.models.client.java import Java
+
+TCR = TrustedContentResolver()
+DID_RESOLVER = UniversalDecentralizedIdentifiersResolver()
+
+
+class ContextType(Context):
+    dns_resolver: DomainNameSystemResolver
+    trust_framework_pointers: set[TrustFrameworkPointer]
+    resolve_response: dict[str, Any]
+    text: Text
+    trust_list: TrustList
+    client: Union[Py, Java]
+
+
+@given("TCR is running")
+def step_impl(context: ContextType):
+    assert TCR.is_up(), "is not up"
+
+
+@given("DID Resolver is running")
+def step_impl(context: ContextType):
+    assert DID_RESOLVER.is_up(), "is not up"
+
+
+@given("{domain_mame_system_type} with {ip} is running")
+def step_impl(context: ContextType, domain_mame_system_type: str, ip: str):
+    context.dns_resolver = DomainNameSystemResolver.init(
+        implementation=domain_mame_system_type,
+        ip=ip
+    )
+    assert context.dns_resolver.is_up(), "is not up"
+
+
+@given("trust framework pointers are `{configured_or_misconfigured}` in DNS")
+def step_impl(context: ContextType, configured_or_misconfigured: str):
+    assert context.trust_framework_pointers
+    for tfp in context.trust_framework_pointers:
+        if configured_or_misconfigured == "configured":
+            assert context.dns_resolver.configured_resolve_trust_framework_pointer(tfp), \
+                "trust framework pointers not configured"
+        elif configured_or_misconfigured == "misconfigured":
+            assert not context.dns_resolver.configured_resolve_trust_framework_pointer(tfp), \
+                "trust framework pointers configured"
+        else:
+            raise NotImplementedError(configured_or_misconfigured)
+
+
+@given("client {client_name} installed")
+def step_impl(context: ContextType, client_name: str):
+    if client_name == 'Trust-content-resolver-client-validator-java':
+        context.client = Java()
+    elif client_name == 'Trust-content-resolver-client-validator-py':
+        context.client = Py()
+    elif client_name == 'Trust-content-resolver-client-validator-go':
+        print('mock all ok')
+        return
+    elif client_name == 'Trust-content-resolver-client-validator-js':
+        print('mock all ok')
+        return
+    else:
+        raise NotImplementedError(client_name)
+
+    assert context.client.is_up()
+
+
+@given("multiple Trust Framework Pointers")
+def step_impl(context: ContextType):
+    context.trust_framework_pointers = TrustFrameworkPointer.from_text(context.text)
+    assert context.trust_framework_pointers, "no Trust Framework Pointers available"
+
+
+@given("Validate DNS Name against DNSSEC")
+def step_impl(context: ContextType):
+    return context.dns_resolver.security_extensions
+
+
+@when("above Trust Framework Pointers are supplied in resolver trust request by `{did}`")
+def step_impl(context: ContextType, did):
+    if hasattr(context, 'client'):
+        context.resolve_response = context.client.resolve(
+            trust_framework_pointers=context.trust_framework_pointers, did=did
+        )
+    else:
+        context.resolve_response = TCR.resolve(
+            trust_framework_pointers=context.trust_framework_pointers, did=did
+        )
+    print("Got resolve response as:", json.dumps(context.resolve_response))
+
+
+@then("Trust List's corresponding Trust Framework pointers from context")
+def step_impl(context: ContextType):
+    tfp_from_tl = TrustList.fetch().trust_framework_pointers
+    assert tfp_from_tl.intersection(context.trust_framework_pointers), \
+        f"{tfp_from_tl=} does no intersect {context.trust_framework_pointers=}"
+
+
+@then("Trust List's will be emtpy")
+def step_impl(context: ContextType):
+    assert len(TrustList.fetch()) == 0
diff --git a/bdd/tests/trust_content_resolver_test.py b/bdd/tests/trust_content_resolver_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..7b9f257c47d07610c941173cb55ce0092cfd7529
--- /dev/null
+++ b/bdd/tests/trust_content_resolver_test.py
@@ -0,0 +1,17 @@
+"""
+Testing TrustedContentResolver
+"""
+import pytest
+
+from train_bdd.models.trusted_content_resolver import TrustedContentResolver
+
+
+def test_resolve_validate_host():
+    """
+    Given invalid host name for Trusted Content Resolver
+     When create the model
+     Then Value Error have to be raised before calling the Trusted Content Resolver
+    """
+    with pytest.raises(ValueError,
+                       match="Input should be a valid URL, relative URL without a base"):
+        TrustedContentResolver(host="wrong_host")
diff --git a/clients/go/ansible.playbook.yml b/clients/go/ansible.playbook.yml
index 8c331a4ff6e6db3269c415ab00265133f3d36976..cb1b5d79c63ccce95e766212443a777e9887d9cf 100644
--- a/clients/go/ansible.playbook.yml
+++ b/clients/go/ansible.playbook.yml
@@ -1,58 +1,72 @@
 - name: Install go MacOSX
   homebrew:
-    name: '{{ item }}'
+    name: "{{ item }}"
     state: present
   with_items:
     - golang
-  when: ansible_distribution == 'MacOSX'
+  when: ansible_distribution == "MacOSX"
   tags:
-    - MacOSX
     - golang
 
-- name: Install go Ubuntu
+- name: Install gvm Debian requirements
   apt:
-    name: '{{ item }}'
+    name:
+      - golang-go
+      - curl
+      - git
+      - mercurial
+      - make
+      - binutils
+      - bison
+      - gcc
+      - build-essential
+      - bsdmainutils
     state: present
-  with_items:
-    - golang-go
-  when: ansible_distribution == 'Ubuntu'
+  when: ansible_distribution == "Ubuntu"
+  become: true
+  become_method: sudo
   tags:
-    - MacOSX
     - golang
 
 # gvm require to have at least one version installed already
 # this is why above pre-installation is required
-- name: Install Gvm
-  ansible.builtin.git:
-    repo: "https://github.com/moovweb/gvm"
-    dest: "{{ ansible_env.HOME }}/.gvm"
+- name: "register status of `{{ ansible_env.HOME }}/.gvm`"
+  stat:
+    path: "{{ ansible_env.HOME }}/.gvm"
+  register: _gvm_dir
+  tags:
+    - golang
+
+- name: Install gvm
+  ansible.builtin.shell: >
+    curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer | bash
+  when: _gvm_dir is defined and not _gvm_dir.stat.exists
   tags:
     - golang
 
-- name: Add Gvm to shell config file
+- name: "Add Gvm to shell config file `~/.bashrc`"
   lineinfile:
-    dest: "{{ _found_shell_config_file }}"
+    dest: ~/.bashrc
     state: present
     line: "{{ item }}"
   with_items:
-    - 'export PATH="${HOME}/.gvm/bin:$PATH"'
-    - 'export GVM_ROOT="${HOME}/.gvm"'
-    - 'source ${GVM_ROOT}/scripts/gvm-default'
+    - "# TRAIN ansible: gvm config"
+    - "source ~/.gvm/scripts/gvm"
   tags:
     - golang
 
 - name: Install concrete version for Go
-  environment:
-    PATH: "{{ ansible_env.HOME }}/.gvm/bin:{{ ansible_env.PATH }}"
-    GVM_ROOT: "{{ ansible_env.HOME }}/.gvm"
-  ansible.builtin.shell: |
-    source $GVM_ROOT/scripts/gvm-default
-    gvm install go1.21
-    gvm use go1.21 --default
-    cd ./clients/go
-    go get github.com/cucumber/godog
+  ansible.builtin.shell: "PS1=emulate-interactive && source ~/.bashrc && {{ item }}"
+  with_items:
+    - gvm version
+    - gvm install go1.21
+
+    # ansible only bug fix for `gvm use` https://github.com/moovweb/gvm/issues/188
+    - ln -sf ~/.gvm/scripts/env/use ~/.gvm/scripts && chmod +x ~/.gvm/scripts/env/use
+
+    - gvm use go1.21 --default
+    - cd ./clients/go/trusted_content_resolver && go mod tidy
   args:
     executable: /bin/bash
   tags:
     - golang
-
diff --git a/clients/java/Makefile b/clients/java/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bdecff6158a718e4a403bfc44f285d914e9dfa5f
--- /dev/null
+++ b/clients/java/Makefile
@@ -0,0 +1,21 @@
+ansible:
+	ansible-playbook ansible.playbook.yml --connection=local -i localhost,
+
+versions:
+	mvn --version
+
+.PHONY: test
+test: versions
+	mvn test -Dmaven.test.failure.ignore
+
+clean:
+	mvn clean
+
+install:
+	mvn install
+
+
+.PHONY: third-party-txt-file
+third-party-txt-file: install
+	rm -f THIRD-PARTY.txt
+	mvn license:add-third-party
\ No newline at end of file
diff --git a/clients/java/README.md b/clients/java/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c73e785b201f47f054ce80d260fa357fed2b0d71
--- /dev/null
+++ b/clients/java/README.md
@@ -0,0 +1,71 @@
+# Build tools
+
+- Required **JDK**: for version look into pom.xml from the root
+- Required **Maven**: for version look into pom.xml from the root
+- Optional **make**: tool which controls the generation of executables and other non-source files of a program from the 
+  program's source files.
+  On *Linux/MacOS* is available by default, for *Windows* see https://stackoverflow.com/questions/2532234/how-to-run-a-makefile-in-windows
+
+# Steps with commands
+
+Note: You can just execute ``make`` subcommands without make (!?) in case you don't want to use ``make`` 
+
+- `git clone` repo, `cd` into directory
+
+- clean target if needed
+
+``` bash
+$ make clean
+mvn clean
+...
+```
+
+- test
+
+``` bash
+$ make test
+mvn --version   
+...
+mvn test -Dmaven.test.failure.ignore
+...
+```
+
+- Extract used licenses into [THIRD-PARTY.txt](THIRD-PARTY.txt)
+
+```bash
+$ make third-party-txt-file
+mvn install
+...
+rm -f THIRD-PARTY.txt
+mvn license:add-third-party
+...
+```
+
+# How to run java client
+
+- build client:
+
+``` bash
+> mvn clean install
+```
+
+- run client:
+
+``` bash
+> cd target
+> java -jar trusted-content-resolver-java-client-1.0.0-SNAPSHOT-full.jar <client arguments>
+```
+
+client arguments can be passed as set of key/value pairs: `k1=p1 k2=p2`. Supported parameters are: 
+
+- `uri/u` - uri to Trusted Content Resolver (TCR) service
+- `endpoint/e` - TCR method to be invoked (resolve/validate)
+- `data/d` - parameters for invoked TCR method in JSON format
+    - ResolveRequest: `{"issuer": "issuer1", "trustSchemePointers": ["ptr1", "ptr2"], "endpointTypes": ["eptype1", "eptype2"], "trustListServiceTypes": ["tlstype1", "tlstype2"]}`
+    - ValidateRequest: `{"issuer": "issuer1", "did": "did1", "endpoints": ["endpoint1", "endpoint2"]}`
+- `file/f` - file, containing parameters specified above, also in JSON format
+- parameters specified via command-line arguments overwrite parameters from file
+
+client prints invocation results to console
+
+
diff --git a/clients/java/THIRD-PARTY.txt b/clients/java/THIRD-PARTY.txt
new file mode 100644
index 0000000000000000000000000000000000000000..75355ff7fc610baccdbbf3a1cdf34e8639f4a853
--- /dev/null
+++ b/clients/java/THIRD-PARTY.txt
@@ -0,0 +1,82 @@
+
+Lists of 80 third-party dependencies.
+     (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.4.11 - http://logback.qos.ch/logback-classic)
+     (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.4.11 - http://logback.qos.ch/logback-core)
+     (Apache License, Version 2.0) ClassMate (com.fasterxml:classmate:1.5.1 - https://github.com/FasterXML/java-classmate)
+     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.15.3 - https://github.com/FasterXML/jackson)
+     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.15.3 - https://github.com/FasterXML/jackson-core)
+     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.15.3 - https://github.com/FasterXML/jackson)
+     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.3 - https://github.com/FasterXML/jackson-dataformats-text)
+     (The Apache Software License, Version 2.0) Jackson datatype: jdk8 (com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.3 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8)
+     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.3 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
+     (The Apache Software License, Version 2.0) Jackson-module-parameter-names (com.fasterxml.jackson.module:jackson-module-parameter-names:2.15.3 - https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names)
+     (Apache License, Version 2.0) trusted-content-resolver-api (eu.xfsc.train:trusted-content-resolver-api:1.0.0-SNAPSHOT - https://gitlab.eclipse.org/eclipse/xfsc/train/trusted-content-resolver/trusted-content-resolver-api)
+     (The Apache Software License, Version 2.0) micrometer-commons (io.micrometer:micrometer-commons:1.11.3 - https://github.com/micrometer-metrics/micrometer)
+     (The Apache Software License, Version 2.0) micrometer-observation (io.micrometer:micrometer-observation:1.11.3 - https://github.com/micrometer-metrics/micrometer)
+     (Apache License, Version 2.0) Netty/Buffer (io.netty:netty-buffer:4.1.100.Final - https://netty.io/netty-buffer/)
+     (Apache License, Version 2.0) Netty/Codec (io.netty:netty-codec:4.1.100.Final - https://netty.io/netty-codec/)
+     (Apache License, Version 2.0) Netty/Codec/DNS (io.netty:netty-codec-dns:4.1.100.Final - https://netty.io/netty-codec-dns/)
+     (Apache License, Version 2.0) Netty/Codec/HTTP (io.netty:netty-codec-http:4.1.100.Final - https://netty.io/netty-codec-http/)
+     (Apache License, Version 2.0) Netty/Codec/HTTP2 (io.netty:netty-codec-http2:4.1.100.Final - https://netty.io/netty-codec-http2/)
+     (Apache License, Version 2.0) Netty/Codec/Socks (io.netty:netty-codec-socks:4.1.100.Final - https://netty.io/netty-codec-socks/)
+     (Apache License, Version 2.0) Netty/Common (io.netty:netty-common:4.1.100.Final - https://netty.io/netty-common/)
+     (Apache License, Version 2.0) Netty/Handler (io.netty:netty-handler:4.1.100.Final - https://netty.io/netty-handler/)
+     (Apache License, Version 2.0) Netty/Handler/Proxy (io.netty:netty-handler-proxy:4.1.100.Final - https://netty.io/netty-handler-proxy/)
+     (Apache License, Version 2.0) Netty/Resolver (io.netty:netty-resolver:4.1.100.Final - https://netty.io/netty-resolver/)
+     (Apache License, Version 2.0) Netty/Resolver/DNS (io.netty:netty-resolver-dns:4.1.100.Final - https://netty.io/netty-resolver-dns/)
+     (Apache License, Version 2.0) Netty/Resolver/DNS/Classes/MacOS (io.netty:netty-resolver-dns-classes-macos:4.1.100.Final - https://netty.io/netty-resolver-dns-classes-macos/)
+     (Apache License, Version 2.0) Netty/Resolver/DNS/Native/MacOS (io.netty:netty-resolver-dns-native-macos:4.1.100.Final - https://netty.io/netty-resolver-dns-native-macos/)
+     (Apache License, Version 2.0) Netty/Transport (io.netty:netty-transport:4.1.100.Final - https://netty.io/netty-transport/)
+     (Apache License, Version 2.0) Netty/Transport/Classes/Epoll (io.netty:netty-transport-classes-epoll:4.1.100.Final - https://netty.io/netty-transport-classes-epoll/)
+     (Apache License, Version 2.0) Netty/Transport/Native/Epoll (io.netty:netty-transport-native-epoll:4.1.100.Final - https://netty.io/netty-transport-native-epoll/)
+     (Apache License, Version 2.0) Netty/Transport/Native/Unix/Common (io.netty:netty-transport-native-unix-common:4.1.100.Final - https://netty.io/netty-transport-native-unix-common/)
+     (Apache License, Version 2.0) Non-Blocking Reactive Foundation for the JVM (io.projectreactor:reactor-core:3.5.11 - https://github.com/reactor/reactor-core)
+     (The Apache Software License, Version 2.0) Core functionality for the Reactor Netty library (io.projectreactor.netty:reactor-netty-core:1.1.12 - https://github.com/reactor/reactor-netty)
+     (The Apache Software License, Version 2.0) HTTP functionality for the Reactor Netty library (io.projectreactor.netty:reactor-netty-http:1.1.12 - https://github.com/reactor/reactor-netty)
+     (Apache License 2.0) swagger-annotations-jakarta (io.swagger.core.v3:swagger-annotations-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations-jakarta)
+     (Apache License 2.0) swagger-core-jakarta (io.swagger.core.v3:swagger-core-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-core-jakarta)
+     (Apache License 2.0) swagger-models-jakarta (io.swagger.core.v3:swagger-models-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-models-jakarta)
+     (EDL 1.0) Jakarta Activation API (jakarta.activation:jakarta.activation-api:2.1.2 - https://github.com/jakartaee/jaf-api)
+     (EPL 2.0) (GPL2 w/ CPE) Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.1.1 - https://projects.eclipse.org/projects/ee4j.ca)
+     (Apache License 2.0) Jakarta Bean Validation API (jakarta.validation:jakarta.validation-api:3.0.2 - https://beanvalidation.org)
+     (Eclipse Distribution License - v 1.0) Jakarta XML Binding API (jakarta.xml.bind:jakarta.xml.bind-api:4.0.1 - https://github.com/eclipse-ee4j/jaxb-api/jakarta.xml.bind-api)
+     (Apache License, Version 2.0) Apache Commons Lang (org.apache.commons:commons-lang3:3.12.0 - https://commons.apache.org/proper/commons-lang/)
+     (Apache License, Version 2.0) Apache Log4j API (org.apache.logging.log4j:log4j-api:2.20.0 - https://logging.apache.org/log4j/2.x/log4j-api/)
+     (Apache License, Version 2.0) Apache Log4j to SLF4J Adapter (org.apache.logging.log4j:log4j-to-slf4j:2.20.0 - https://logging.apache.org/log4j/2.x/log4j-to-slf4j/)
+     (Apache License, Version 2.0) tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:10.1.15 - https://tomcat.apache.org/)
+     (The Apache License, Version 2.0) org.apiguardian:apiguardian-api (org.apiguardian:apiguardian-api:1.1.2 - https://github.com/apiguardian-team/apiguardian)
+     (Apache License 2.0) Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:8.0.1.Final - http://hibernate.org/validator/hibernate-validator)
+     (Apache License 2.0) JBoss Logging 3 (org.jboss.logging:jboss-logging:3.5.3.Final - http://www.jboss.org)
+     (Eclipse Public License v2.0) JUnit Jupiter (Aggregator) (org.junit.jupiter:junit-jupiter:5.9.3 - https://junit.org/junit5/)
+     (Eclipse Public License v2.0) JUnit Jupiter API (org.junit.jupiter:junit-jupiter-api:5.9.3 - https://junit.org/junit5/)
+     (Eclipse Public License v2.0) JUnit Jupiter Engine (org.junit.jupiter:junit-jupiter-engine:5.9.3 - https://junit.org/junit5/)
+     (Eclipse Public License v2.0) JUnit Jupiter Params (org.junit.jupiter:junit-jupiter-params:5.9.3 - https://junit.org/junit5/)
+     (Eclipse Public License v2.0) JUnit Platform Commons (org.junit.platform:junit-platform-commons:1.9.3 - https://junit.org/junit5/)
+     (Eclipse Public License v2.0) JUnit Platform Engine API (org.junit.platform:junit-platform-engine:1.9.3 - https://junit.org/junit5/)
+     (The Apache License, Version 2.0) org.opentest4j:opentest4j (org.opentest4j:opentest4j:1.2.0 - https://github.com/ota4j-team/opentest4j)
+     (The MIT License) Project Lombok (org.projectlombok:lombok:1.18.30 - https://projectlombok.org)
+     (MIT-0) reactive-streams (org.reactivestreams:reactive-streams:1.0.4 - http://www.reactive-streams.org/)
+     (MIT License) JUL to SLF4J bridge (org.slf4j:jul-to-slf4j:2.0.9 - http://www.slf4j.org)
+     (MIT License) SLF4J API Module (org.slf4j:slf4j-api:2.0.9 - http://www.slf4j.org)
+     (The Apache License, Version 2.0) springdoc-openapi-starter-common (org.springdoc:springdoc-openapi-starter-common:2.2.0 - https://springdoc.org/springdoc-openapi-starter-common/)
+     (The Apache License, Version 2.0) springdoc-openapi-starter-webmvc-api (org.springdoc:springdoc-openapi-starter-webmvc-api:2.2.0 - https://springdoc.org/springdoc-openapi-starter-webmvc-api/)
+     (The Apache License, Version 2.0) springdoc-openapi-starter-webmvc-ui (org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0 - https://springdoc.org/springdoc-openapi-starter-webmvc-ui/)
+     (Apache License, Version 2.0) Spring AOP (org.springframework:spring-aop:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Beans (org.springframework:spring-beans:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Context (org.springframework:spring-context:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Core (org.springframework:spring-core:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Expression Language (SpEL) (org.springframework:spring-expression:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Commons Logging Bridge (org.springframework:spring-jcl:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Web (org.springframework:spring-web:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring WebFlux (org.springframework:spring-webflux:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) Spring Web MVC (org.springframework:spring-webmvc:6.0.13 - https://github.com/spring-projects/spring-framework)
+     (Apache License, Version 2.0) spring-boot (org.springframework.boot:spring-boot:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-autoconfigure (org.springframework.boot:spring-boot-autoconfigure:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-starter (org.springframework.boot:spring-boot-starter:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-starter-json (org.springframework.boot:spring-boot-starter-json:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-starter-logging (org.springframework.boot:spring-boot-starter-logging:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-starter-reactor-netty (org.springframework.boot:spring-boot-starter-reactor-netty:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-starter-validation (org.springframework.boot:spring-boot-starter-validation:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache License, Version 2.0) spring-boot-starter-webflux (org.springframework.boot:spring-boot-starter-webflux:3.1.5 - https://spring.io/projects/spring-boot)
+     (Apache 2.0) Swagger UI (org.webjars:swagger-ui:5.2.0 - http://webjars.org)
+     (Apache License, Version 2.0) SnakeYAML (org.yaml:snakeyaml:2.1 - https://bitbucket.org/snakeyaml/snakeyaml)
diff --git a/clients/java/ansible.playbook.yml b/clients/java/ansible.playbook.yml
index 152bdca253ffaf43b8567705145a03b329e2c01a..ee34ab60ad27b3fbfbbc4f8ad1d45ceb8675a5f3 100644
--- a/clients/java/ansible.playbook.yml
+++ b/clients/java/ansible.playbook.yml
@@ -1,17 +1,27 @@
 - name: Install sdkman
   ansible.builtin.shell: >
     curl -o- https://get.sdkman.io | bash
+  tags:
+    - java
 
-- name: add sdkman to shell config file
+- name: "Add sdkman to shell config file `~/.bashrc`"
   lineinfile:
-    dest: "{{ _found_shell_config_file }}"
+    dest: "~/.bashrc"
     state: present
     line: '{{ item }}'
   with_items:
+    - "# TRAIN ansible: sdkman config"
     - "source ~/.sdkman/bin/sdkman-init.sh"
+  tags:
+    - java
 
 - name: Install concrete version for java
-  ansible.builtin.shell: |
-    source ~/.sdkman/bin/sdkman-init.sh
-    sdk install java 17.0.0-tem
-    sdk install maven
+  ansible.builtin.shell: "source ~/.sdkman/bin/sdkman-init.sh && {{ item }}"
+  with_items:
+    - sdk version
+    - sdk install java 21.0.1-librca
+    - sdk install maven 3.9.5
+    - sdk use java 21.0.1-librca
+    - sdk use maven 3.9.5
+  args:
+    executable: /bin/bash
diff --git a/clients/java/pom.xml b/clients/java/pom.xml
index d2055a49f520fde20dd2172c12ac7787db546173..13fbd76c7567fff712bb11916e1cf25644035571 100644
--- a/clients/java/pom.xml
+++ b/clients/java/pom.xml
@@ -26,11 +26,58 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-webflux</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-resolver-dns-native-macos</artifactId>
+            <classifier>osx-aarch_64</classifier>
+            <scope>runtime</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>mockwebserver</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
+    <build>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <configuration>
+            <archive>
+              <manifest>
+                <addClasspath>true</addClasspath>
+                <mainClass>eu.xfsc.train.tcr.util.ResolveServiceLauncher</mainClass>
+              </manifest>
+            </archive>
+            <descriptorRefs>
+              <descriptorRef>jar-with-dependencies</descriptorRef>
+            </descriptorRefs>
+            <finalName>${project.artifactId}-${project.version}-full</finalName>
+            <appendAssemblyId>false</appendAssemblyId>
+          </configuration>
+          <executions>
+            <execution>
+              <id>assemble-all</id>
+              <phase>package</phase>
+              <goals>
+                <goal>single</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+    </build>
+    
 </project>
diff --git a/clients/java/src/main/java/eu/xfsc/train/tcr/client/ResolveServiceClient.java b/clients/java/src/main/java/eu/xfsc/train/tcr/client/ResolveServiceClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d1848a3eb13d27e81d44710b89b531623ca10cc
--- /dev/null
+++ b/clients/java/src/main/java/eu/xfsc/train/tcr/client/ResolveServiceClient.java
@@ -0,0 +1,84 @@
+package eu.xfsc.train.tcr.client;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.web.reactive.function.client.WebClient;
+
+import eu.xfsc.train.tcr.api.generated.model.ResolveRequest;
+import eu.xfsc.train.tcr.api.generated.model.ResolveResult;
+import eu.xfsc.train.tcr.api.generated.model.ValidateRequest;
+import eu.xfsc.train.tcr.api.generated.model.ValidateResponse;
+
+/**
+ * Client wrapper hiding communication via REST with TCR server
+ */
+public class ResolveServiceClient extends ServiceClient {
+	
+	/**
+	 * The Client constructor
+	 * 
+	 * @param baseUrl: TCR base url
+	 */
+    public ResolveServiceClient(String baseUrl) {
+        super(baseUrl, (String) null);
+    }
+
+    /**
+     * The Client constructor
+     * 
+     * @param baseUrl: TCR base url
+     * @param client: pre-configured WebClient instance
+     */
+    public ResolveServiceClient(String baseUrl, WebClient client) {
+        super(baseUrl, client);
+    }
+    
+    /**
+     * Resolves TrustLists for specified issuer and pointer 
+     * 
+     * @param issuer: TrustList issuer DID/URI
+     * @param pointer: Trust Framework Pointer
+     * @param serviceTypes: service types to confider. null allows any service type 
+     * @return list of ResolveResut structures
+     */
+    public List<ResolveResult> resolveTrustList(String issuer, String pointer, List<String> serviceTypes) { //, List<String> listTypes) {
+    	ResolveRequest rrq = new ResolveRequest();
+    	rrq = rrq.issuer(issuer).addTrustSchemePointersItem(pointer).trustListServiceTypes(serviceTypes);
+        return resolveTrustList(rrq); 
+    }
+
+    /**
+     * Resolves TrustList for specified /resolve params
+     * 
+     * @param rrq: ResolveRequest structure containing bunch of /resolve parameters
+     * @return list of ResolveResult structures
+     */
+    public List<ResolveResult> resolveTrustList(ResolveRequest rrq) { 
+        return doPost(baseUrl + "/resolve", rrq, Map.of(), List.class); 
+    }
+    
+    /**
+     * Validates resolution for specified issuer and DID
+     * 
+     * @param issuer: TrustList issuer DID/URI
+     * @param did: DID resolved for provided Pointer
+     * @param tlEndpoints: resolved TrustList endpoints
+     * @return issuer/DID/VC verification status
+     */
+    public ValidateResponse validateTrustList(String issuer, String did, List<String> tlEndpoints) { 
+    	ValidateRequest vrq = new ValidateRequest(issuer, did, tlEndpoints);
+        return validateTrustList(vrq); 
+    }
+    
+    /**
+     * Validates resolution for specified issuer and DID
+     * 
+     * @param vrq: ValidateRequest structure containing banch of /validate parameters
+     * @return issuer/DID/VC verification status
+     */
+    public ValidateResponse validateTrustList(ValidateRequest vrq) { 
+        return doPost(baseUrl + "/validate", vrq, Map.of(), ValidateResponse.class); 
+    }
+    
+}
diff --git a/clients/java/src/main/java/eu/xfsc/train/tcr/client/ServiceClient.java b/clients/java/src/main/java/eu/xfsc/train/tcr/client/ServiceClient.java
index 00d699bf34882847673dae961ce602ee7b21400b..dc8eaf70411e58cde80a6f9ca3599b9e955edd29 100644
--- a/clients/java/src/main/java/eu/xfsc/train/tcr/client/ServiceClient.java
+++ b/clients/java/src/main/java/eu/xfsc/train/tcr/client/ServiceClient.java
@@ -2,6 +2,7 @@ package eu.xfsc.train.tcr.client;
 
 import java.util.Map;
 
+import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.codec.json.Jackson2JsonDecoder;
@@ -9,6 +10,7 @@ import org.springframework.http.codec.json.Jackson2JsonEncoder;
 
 import org.springframework.web.reactive.function.client.WebClient;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
@@ -25,17 +27,17 @@ public abstract class ServiceClient {
         mapper = new ObjectMapper()
             .findAndRegisterModules()   // .registerModule(new ParanamerModule()) .registerModule(new JavaTimeModule())
             .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-        this.client = WebClient.builder()
-            //.apply(oauth2Client.oauth2Configuration())
-            //.filter(new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager))
+        WebClient.Builder builder = WebClient.builder()
             .baseUrl(baseUrl)
             .codecs(configurer -> {
                 configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper, MediaType.APPLICATION_JSON));
                 configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper, MediaType.APPLICATION_JSON));
             })
-            .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + jwt)
-            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
-            .build();
+            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+        if (jwt != null) {
+            builder = builder.defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + jwt);
+        }
+        this.client = builder.build();
 //      this.template.setErrorHandler(new ErrorHandler(mapper));
     }
 
diff --git a/clients/java/src/main/java/eu/xfsc/train/tcr/client/VerificationClient.java b/clients/java/src/main/java/eu/xfsc/train/tcr/client/VerificationClient.java
deleted file mode 100644
index c5ef78db6a382fb023faacca6039a1d7617fe954..0000000000000000000000000000000000000000
--- a/clients/java/src/main/java/eu/xfsc/train/tcr/client/VerificationClient.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package eu.xfsc.train.tcr.client;
-
-import java.util.Map;
-
-import org.springframework.web.reactive.function.client.WebClient;
-
-import eu.xfsc.train.tcr.api.generated.model.VerificationRequest;
-import eu.xfsc.train.tcr.api.generated.model.VerificationResult;
-
-public class VerificationClient extends ServiceClient {
-
-    public VerificationClient(String baseUrl, String jwt) {
-        super(baseUrl, jwt);
-    }
-
-    public VerificationClient(String baseUrl, WebClient client) {
-        super(baseUrl, client);
-    }
-    
-    public VerificationResult resolveIssuer(String issuer, String pointer) {
-    	VerificationRequest vrq = new VerificationRequest();
-    	vrq = vrq.issuer(issuer).trustSchemePointer(pointer);
-        return doPost(baseUrl + "/resolve", vrq, Map.of(), VerificationResult.class);
-    }
-
-}
diff --git a/clients/java/src/main/java/eu/xfsc/train/tcr/util/ResolveServiceLauncher.java b/clients/java/src/main/java/eu/xfsc/train/tcr/util/ResolveServiceLauncher.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7d422619a8356d3245fc097b9030bf5bef36de8
--- /dev/null
+++ b/clients/java/src/main/java/eu/xfsc/train/tcr/util/ResolveServiceLauncher.java
@@ -0,0 +1,97 @@
+package eu.xfsc.train.tcr.util;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import eu.xfsc.train.tcr.api.generated.model.ResolveRequest;
+import eu.xfsc.train.tcr.api.generated.model.ResolveResult;
+import eu.xfsc.train.tcr.api.generated.model.ValidateRequest;
+import eu.xfsc.train.tcr.api.generated.model.ValidateResponse;
+import eu.xfsc.train.tcr.client.ResolveServiceClient;
+
+public class ResolveServiceLauncher {
+	
+	static final String DEF_URI = "http://localhost:8087";
+	static ObjectMapper mapper = new ObjectMapper();
+	
+	
+    public static void main(String[] args) throws Exception {
+    	
+    	String baseUri = null;
+    	String endpoint = null;
+    	String data = null;
+    	ResolveServiceParams params = null;
+    	//System.out.println("args: " + Arrays.toString(args));
+    	for (String arg: args) {
+    		String[] parts = arg.split("=");
+    		if ("u".equals(parts[0]) || "uri".equals(parts[0])) {
+    			baseUri = parts[1];
+    			continue;
+    		}
+    		if ("e".equals(parts[0]) || "endpoint".equals(parts[0])) {
+    			endpoint = parts[1];
+    			continue;
+    		}
+    		if ("d".equals(parts[0]) || "data".equals(parts[0])) {
+    			data = parts[1];
+    			continue;
+    		}
+    		if ("f".equals(parts[0]) || "file".equals(parts[0])) {
+    			params = mapper.readValue(new File(parts[1]), ResolveServiceParams.class);
+    			continue;
+    		}
+    		System.out.println("unknown parameter: " + arg);
+    	}
+    	
+    	if (params != null) {
+    		if (baseUri == null) {
+    			baseUri = params.getUri();
+    		}
+    		if (endpoint == null) {
+    			endpoint = params.getEndpoint();
+    		}
+    		if (data == null) {
+    			data = params.getData();
+    		}
+    	}
+    	if (baseUri == null) {
+    		baseUri = DEF_URI;
+    	}
+    	
+    	if (endpoint == null) {
+    		System.out.println("error: no resolution endpoint specified");
+    		return;
+    	}
+    	
+    	Boolean resolve;
+		if ("resolve".equals(endpoint)) {
+			resolve = true;
+		} else if ("validate".equals(endpoint)) {
+			resolve = false;
+		} else {
+			System.out.println("error: unknown resolution endpoint: " + endpoint);
+			return;
+		}
+    	
+    	if (data == null) {
+    		System.out.println("error: no " + (resolve ? "resolution" : "validation") + " data provided");
+    		return;
+    	}
+    	
+    	ResolveServiceClient client = new ResolveServiceClient(baseUri);
+    	if (resolve) {
+    		ResolveRequest rrq = mapper.readValue(data, ResolveRequest.class);
+    		List<ResolveResult> result = client.resolveTrustList(rrq);
+    		System.out.println("result: " + mapper.writeValueAsString(result));
+    	} else {
+    		ValidateRequest vrq = mapper.readValue(data, ValidateRequest.class);
+    		ValidateResponse result = client.validateTrustList(vrq);
+    		System.out.println("result: " + mapper.writeValueAsString(result));
+    	}
+    	// what else?
+    }
+    
+}
diff --git a/clients/java/src/main/java/eu/xfsc/train/tcr/util/ResolveServiceParams.java b/clients/java/src/main/java/eu/xfsc/train/tcr/util/ResolveServiceParams.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbe48da9e3189fb934e696be56daf264d42b0f6c
--- /dev/null
+++ b/clients/java/src/main/java/eu/xfsc/train/tcr/util/ResolveServiceParams.java
@@ -0,0 +1,16 @@
+package eu.xfsc.train.tcr.util;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@lombok.Getter
+@lombok.Setter
+public class ResolveServiceParams {
+	
+    @JsonProperty("uri")
+	private String uri;
+    @JsonProperty("endpoint")
+	private String endpoint;
+    @JsonProperty("data")
+	private String data;
+
+}
diff --git a/clients/java/src/test/java/eu/xfsc/train/tcr/util/ResolveServiceLauncherTest.java b/clients/java/src/test/java/eu/xfsc/train/tcr/util/ResolveServiceLauncherTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ddb5c67f172d7d7d38ec1a6e839ae2eb81a959f4
--- /dev/null
+++ b/clients/java/src/test/java/eu/xfsc/train/tcr/util/ResolveServiceLauncherTest.java
@@ -0,0 +1,218 @@
+package eu.xfsc.train.tcr.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import eu.xfsc.train.tcr.api.generated.model.ResolveResult;
+import eu.xfsc.train.tcr.api.generated.model.ResolveTrustList;
+import eu.xfsc.train.tcr.api.generated.model.ValidateResponse;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class ResolveServiceLauncherTest {
+	
+    private static MockWebServer mockBackEnd;
+    private static final int TCR_PORT = 8087;
+    private static final ObjectMapper mapper = new ObjectMapper(); 
+	private static final TypeReference<List<ResolveResult>> LIST_TYPE_REF = new TypeReference<List<ResolveResult>>() {};
+    
+    @BeforeAll
+    static void setUp() throws IOException {
+        mockBackEnd = new MockWebServer();
+        mockBackEnd.noClientAuth();
+        mockBackEnd.start(TCR_PORT);
+    }
+
+    @AfterAll
+    static void tearDown() throws IOException {
+        mockBackEnd.shutdown();
+    }
+    
+	@Test
+	public void testLauncherFailEmptyRequest() throws Exception {
+		String[] arguments = new String[] {};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertEquals("error: no resolution endpoint specified\n", output);
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherFailOptionsRequest() throws Exception {
+		String[] arguments = new String[] {"-Dtrain.opt=value", "--flag-on", "-d", "endpoint=validate"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertTrue(output.endsWith("error: no validation data provided\n"));
+	    out.close();
+	}
+	
+	@Test
+	public void testLauncherFailNoEndpointRequest() throws Exception {
+		String[] arguments = new String[] {"d={\"issuer\": \"issuer1\", \"trustSchemePointers\": [\"ptr1\", \"ptr2\"]}"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertEquals("error: no resolution endpoint specified\n", output);
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherFailUnknownEndpointRequest() throws Exception {
+		String[] arguments = new String[] {"e=verify"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+
+	    ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertEquals("error: unknown resolution endpoint: verify\n", output);
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherFailNoDataRequest() throws Exception {
+		String[] arguments = new String[] {"e=validate"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+
+	    ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertEquals("error: no validation data provided\n", output);
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherResolveResponse() throws Exception {
+		String[] arguments = new String[] {"e=resolve", "d={\"issuer\": \"issuer1\", \"trustSchemePointers\": [\"ptr1\", \"ptr2\"]}"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+		ResolveResult rrs = new ResolveResult("did:mock:sample-issuer1", List.of("ptr2"), Map.of(), List.of(new ResolveTrustList("https://issuer1.test/trust-list", Map.of())));
+		mockBackEnd.enqueue(new MockResponse().setBody(mapper.writeValueAsString(List.of(rrs))).addHeader("Content-Type", "application/json"));
+
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertTrue(output.startsWith("result: "));
+	    List<ResolveResult> resp = mapper.readValue(output.substring(8), LIST_TYPE_REF);
+	    assertEquals(1, resp.size());
+	    assertEquals(rrs.getDid(), resp.get(0).getDid());
+	    assertEquals(1, rrs.getPointers().size());
+	    assertEquals("ptr2", rrs.getPointers().get(0));
+
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherValidateResponse() throws Exception {
+		String[] arguments = new String[] {"e=validate", "d={\"issuer\": \"issuer1\", \"did\": \"did:mock:sample-issuer1\", \"endpoints\": [\"https://issuer1.test/trust-list\"]}"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+		ValidateResponse vrs = new ValidateResponse(true, true, true, List.of(new ResolveTrustList("https://issuer1.test/trust-list", Map.of())));
+		mockBackEnd.enqueue(new MockResponse().setBody(mapper.writeValueAsString(vrs)).addHeader("Content-Type", "application/json"));
+
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertTrue(output.startsWith("result: "));
+	    ValidateResponse resp = mapper.readValue(output.substring(8), ValidateResponse.class);
+	    assertEquals(vrs, resp);
+
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherResolveFileResponse() throws Exception {
+		String[] arguments = new String[] {"uri=http://localhost:8087", "f=./src/test/resources/resolve-input.json"};
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+		ResolveResult rrs = new ResolveResult("did:mock:sample-issuer1", List.of("ptr2"), Map.of(), List.of(new ResolveTrustList("https://issuer1.test/trust-list", Map.of())));
+		mockBackEnd.enqueue(new MockResponse().setBody(mapper.writeValueAsString(List.of(rrs))).addHeader("Content-Type", "application/json"));
+
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertTrue(output.startsWith("result: "));
+	    List<ResolveResult> resp = mapper.readValue(output.substring(8), LIST_TYPE_REF);
+	    assertEquals(1, resp.size());
+	    assertEquals(rrs.getDid(), resp.get(0).getDid());
+	    assertEquals(1, rrs.getPointers().size());
+	    assertEquals("ptr2", rrs.getPointers().get(0));
+
+	    out.close();
+	}
+
+	@Test
+	public void testLauncherValidateFileResponse() throws Exception {
+		String[] arguments = new String[] {"f=src/test/resources/validate-input.json"};
+		
+        mockBackEnd.shutdown();
+        mockBackEnd = new MockWebServer();
+        mockBackEnd.noClientAuth();
+        mockBackEnd.start(8080); 
+
+	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+	    PrintStream out = new PrintStream(byteArrayOutputStream);
+	    System.setOut(out);
+		
+		ValidateResponse vrs = new ValidateResponse(true, true, true, List.of(new ResolveTrustList("https://issuer1.test/trust-list", Map.of())));
+		mockBackEnd.enqueue(new MockResponse().setBody(mapper.writeValueAsString(vrs)).addHeader("Content-Type", "application/json"));
+
+    	ResolveServiceLauncher.main(arguments);
+
+	    String output = byteArrayOutputStream.toString(Charset.defaultCharset());
+	    assertTrue(output.startsWith("result: "));
+	    ValidateResponse resp = mapper.readValue(output.substring(8), ValidateResponse.class);
+	    assertEquals(vrs, resp);
+
+	    out.close();
+	    
+	    tearDown();
+	    setUp();
+	}
+	
+}
diff --git a/clients/java/src/test/resources/resolve-input.json b/clients/java/src/test/resources/resolve-input.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f805f0e7d0aa28ba3598e626e47d744147e0685
--- /dev/null
+++ b/clients/java/src/test/resources/resolve-input.json
@@ -0,0 +1 @@
+{"uri": "https://external.host", "endpoint": "resolve", "data": "{\"issuer\": \"issuer1\", \"trustSchemePointers\": [\"ptr1\", \"ptr2\"]}"}
\ No newline at end of file
diff --git a/clients/java/src/test/resources/validate-input.json b/clients/java/src/test/resources/validate-input.json
new file mode 100644
index 0000000000000000000000000000000000000000..248b631ebfd073568692082210cf939edf22dd9b
--- /dev/null
+++ b/clients/java/src/test/resources/validate-input.json
@@ -0,0 +1 @@
+{"uri": "http://127.0.0.1:8080", "endpoint": "validate", "data": "{\"issuer\": \"issuer1\", \"did\": \"did:mock:sample-issuer1\", \"endpoints\": [\"https://issuer1.test/trust-list\"]}"}
\ No newline at end of file
diff --git a/clients/js/ansible.playbook.yml b/clients/js/ansible.playbook.yml
index 90e0dabc75fde60bd67a7f76074567342d5d6a60..9fb00aa5f0b6b3720867286828ba79e1162b5e35 100644
--- a/clients/js/ansible.playbook.yml
+++ b/clients/js/ansible.playbook.yml
@@ -1,23 +1,73 @@
-# see https://github.com/nvm-sh/nvm
-- name: Install nvm
-  ansible.builtin.shell: >
-    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
-  args:
-    creates: "{{ ansible_env.HOME }}/.nvm/nvm.sh"
+# todo make it work with pyenv
+- name: Git checkout
+  ansible.builtin.git:
+    repo: 'https://github.com/pyenv/pyenv.git'
+    dest:  ~/.pyenv
+  when: ansible_distribution == 'Ubuntu'
+  tags:
+    - python
+
+- name: Install Python on MacOSX
+  homebrew:
+    name: '{{ item }}'
+    state: present
+  with_items:
+    - python
+  when: ansible_distribution == 'MacOSX'
   tags:
-    - npm
+    - MacOSX
+    - python
 
-- name: add nvm to bash config file
+- name: Install Python on Ubuntu
+  apt:
+    name:
+      - python3-dev
+      - build-essential
+      - libssl-dev
+      - zlib1g-dev
+      - libbz2-dev
+      - libreadline-dev
+      - libsqlite3-dev
+      - curl
+      - libncursesw5-dev
+      - xz-utils
+      - tk-dev
+      - libxml2-dev
+      - libxmlsec1-dev
+      - libffi-dev
+      - liblzma-dev
+    state: present
+  when: ansible_distribution == 'Ubuntu'
+  become: true
+  become_method: sudo
+  tags:
+    - Ubuntu
+    - python
+
+- name: "Add Python to shell config file `~/.bashrc`"
   lineinfile:
-    dest: "{{ _found_shell_config_file }}"
+    dest: ~/.bashrc
     state: present
-    line: "source {{ ansible_env.HOME }}/.nvm/nvm.sh"
+    line: "{{ item }}"
+  with_items:
+    - "# TRAIN ansible: python config"
+    - "export PYENV_ROOT=~/.pyenv"
+    - "export PATH=$PYENV_ROOT/bin:$PATH"
+    - "eval \"$(pyenv init -)\""
+  when: ansible_distribution == 'Ubuntu'
   tags:
-    - npm
+    - python
 
-- name: Install concrete version for Node
-  ansible.builtin.shell: |
-    source {{ ansible_env.HOME }}/.nvm/nvm.sh
-    nvm install v20.8.0
+- name: Install concrete version for python
+  ansible.builtin.shell: "PS1=emulate-interactive && source ~/.bashrc && {{ item }}"
+  with_items:
+    # speedup pyenv commands
+    - cd ~/.pyenv && src/configure && make -C src
+    - pyenv --version
+    - pyenv install 3.12
+    - pyenv global 3.12
+  args:
+    executable: /bin/bash
+  when: ansible_distribution == 'Ubuntu'
   tags:
-    - npm
\ No newline at end of file
+    - golang
diff --git a/clients/py/Makefile b/clients/py/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bc803d355190f68cc6e752f881a4b697fba644fe
--- /dev/null
+++ b/clients/py/Makefile
@@ -0,0 +1,64 @@
+# see https://makefiletutorial.com/
+
+SHELL := /bin/bash -eu -o pipefail
+PYTHON_3 ?= python3
+PYTHON_D ?= /opt/python.d
+SOURCE_PATHS := "src/trusted_content_resolver_client"
+
+VENV_PATH_DEV := $(PYTHON_D)/dev/train/trusted_content_resolver_client
+VENV_PATH_PROD := $(PYTHON_D)/prod/train/trusted_content_resolver_client
+
+setup_dev: $(VENV_PATH_DEV)
+
+$(VENV_PATH_DEV):
+	$(PYTHON_3) -m venv $(VENV_PATH_DEV)
+	"$(VENV_PATH_DEV)/bin/pip" install -U pip wheel
+	"$(VENV_PATH_DEV)/bin/pip" install -e ".[dev]"
+
+setup_prod: $(VENV_PATH_PROD)
+
+$(VENV_PATH_PROD):
+	$(PYTHON_3) -m venv $(VENV_PATH_PROD)
+	"$(VENV_PATH_PROD)/bin/pip" install -U pip wheel
+	"$(VENV_PATH_PROD)/bin/pip" install "."
+
+isort:
+	"$(VENV_PATH_DEV)/bin/isort" $(SOURCE_PATHS) tests
+
+pylint:
+	"$(VENV_PATH_DEV)/bin/pylint" $(SOURCE_PATHS) tests
+
+coverage_run:
+	"$(VENV_PATH_DEV)/bin/coverage" run -m pytest -m "not integration"
+
+coverage_report:
+	"$(VENV_PATH_DEV)/bin/coverage" report
+
+mypy:
+	"$(VENV_PATH_DEV)/bin/mypy" $(SOURCE_PATHS)
+
+code_check: \
+	setup_dev \
+	isort \
+	pylint \
+	coverage_run coverage_report \
+	mypy
+
+clean_dev:
+	rm -rfv  "$(VENV_PATH_DEV)"
+
+clean_prod:
+	rm -rfv  "$(VENV_PATH_PROD)"
+
+activate_env_prod:
+	@echo "source \"$(VENV_PATH_PROD)/bin/activate\""
+
+activate_env_dev:
+	@echo "source \"$(VENV_PATH_DEV)/bin/activate\""
+
+ansible:
+	cd ../.. && \
+		ansible-playbook ansible.playbook.yml --connection=local -i localhost, --tags=python
+
+third-party-txt-file:
+	# TODO
diff --git a/clients/py/ansible.playbook.yml b/clients/py/ansible.playbook.yml
index b7e50b06be6cdfecb692bd9aa42a92b65f0b6e84..164e0f2012194df48482c8af0c9176c56d061098 100644
--- a/clients/py/ansible.playbook.yml
+++ b/clients/py/ansible.playbook.yml
@@ -1,4 +1,12 @@
 # todo make it work with pyenv
+- name: Git checkout
+  ansible.builtin.git:
+    repo: 'https://github.com/pyenv/pyenv.git'
+    dest:  ~/.pyenv
+  when: ansible_distribution == 'Ubuntu'
+  tags:
+    - python
+
 - name: Install Python on MacOSX
   homebrew:
     name: '{{ item }}'
@@ -8,13 +16,58 @@
   when: ansible_distribution == 'MacOSX'
   tags:
     - MacOSX
+    - python
 
 - name: Install Python on Ubuntu
   apt:
-    name: '{{ item }}'
+    name:
+      - python3-dev
+      - build-essential
+      - libssl-dev
+      - zlib1g-dev
+      - libbz2-dev
+      - libreadline-dev
+      - libsqlite3-dev
+      - curl
+      - libncursesw5-dev
+      - xz-utils
+      - tk-dev
+      - libxml2-dev
+      - libxmlsec1-dev
+      - libffi-dev
+      - liblzma-dev
     state: present
-  with_items:
-    - python3-dev
   when: ansible_distribution == 'Ubuntu'
+  become: true
+  become_method: sudo
   tags:
     - Ubuntu
+    - python
+
+- name: "Add Python to shell config file `~/.bashrc`"
+  lineinfile:
+    dest: ~/.bashrc
+    state: present
+    line: "{{ item }}"
+  with_items:
+    - "# TRAIN ansible: python config"
+    - "export PYENV_ROOT=~/.pyenv"
+    - "export PATH=$PYENV_ROOT/bin:$PATH"
+    - "eval \"$(pyenv init -)\""
+  when: ansible_distribution == 'Ubuntu'
+  tags:
+    - python
+
+- name: Install concrete version for python
+  ansible.builtin.shell: "PS1=emulate-interactive && source ~/.bashrc && {{ item }}"
+  with_items:
+    # speedup pyenv commands
+    - cd ~/.pyenv && src/configure && make -C src
+    - pyenv --version
+    - pyenv install 3.11.4
+    - pyenv global 3.11.4
+  args:
+    executable: /bin/bash
+  when: ansible_distribution == 'Ubuntu'
+  tags:
+    - golang
diff --git a/clients/py/setup.cfg b/clients/py/setup.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..ad65c6959b80ad07e3774f339520806533faeaf9
--- /dev/null
+++ b/clients/py/setup.cfg
@@ -0,0 +1,66 @@
+[metadata]
+name = trusted_content_resolver_client
+version = 0.0.0
+
+[options]
+zip_safe = False
+include_package_data = True
+package_dir=
+    =src
+packages = find:
+
+install_requires =
+    requests==2.31.0
+    pydantic==2.4.2
+
+[options.package_data]
+* = *.yaml
+
+[options.packages.find]
+where=src
+
+[options.extras_require]
+dev =
+    pylint
+    pytest
+    mypy
+    types-requests
+    coverage
+
+[isort]
+known_typing=typing
+known_localfolder=trusted_content_resolver_client
+;suppress inspection for section "SpellCheckingInspection"
+sections=FUTURE,TYPING,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER
+
+[coverage:run]
+data_file=.coverage
+branch=True
+source=src
+
+[coverage:report]
+fail_under=16
+show_missing=True
+exclude_lines =
+    pragma: no cover
+    def __repr__
+    if self.debug:
+    if settings.DEBUG
+    raise AssertionError
+    raise NotImplementedError
+    if 0:
+    if __name__ == .__main__.:
+    class .*\bProtocol\):
+    @(abc\.)?abstractmethod
+
+[tool:pytest]
+addopts = --strict-markers -m "not integration" -v
+markers =
+    integration
+testpaths = tests
+filterwarnings =
+    error
+
+[pylint.FORMAT]
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$|See `https://\S+`_
diff --git a/clients/py/setup.py b/clients/py/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..606849326a4002007fd42060b51e69a19c18675c
--- /dev/null
+++ b/clients/py/setup.py
@@ -0,0 +1,3 @@
+from setuptools import setup
+
+setup()
diff --git a/clients/py/src/trusted_content_resolver_client/__init__.py b/clients/py/src/trusted_content_resolver_client/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/clients/py/src/trusted_content_resolver_client/resolve_service_client.py b/clients/py/src/trusted_content_resolver_client/resolve_service_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7686e80c5fb6b565a91233bcd2dcbd62c3d7a56
--- /dev/null
+++ b/clients/py/src/trusted_content_resolver_client/resolve_service_client.py
@@ -0,0 +1,10 @@
+"""
+Propagation of main java client implementation
+"""
+
+
+def resolve_trust_list(*_, **__) -> str:
+    """
+    WIP: To be implemented
+    """
+    return "something"
diff --git a/clients/py/test/bdd/bdd.feature b/clients/py/test/bdd/bdd.feature
deleted file mode 120000
index f419198b6e2fa11c2e54b5b4bdf841040dfe36c9..0000000000000000000000000000000000000000
--- a/clients/py/test/bdd/bdd.feature
+++ /dev/null
@@ -1 +0,0 @@
-../../../../features/bdd.feature
\ No newline at end of file
diff --git a/clients/py/test/bdd/steps/bdd.py b/clients/py/test/bdd/steps/bdd.py
deleted file mode 100644
index e9a7bb9bbbba2582fe4d9f22182674d57d132fb7..0000000000000000000000000000000000000000
--- a/clients/py/test/bdd/steps/bdd.py
+++ /dev/null
@@ -1,98 +0,0 @@
-from dataclasses import dataclass
-from behave import *
-
-import requests
-
-SESSION = requests.Session()
-
-
-@dataclass
-class TrustedContentResolver:
-    app: str
-
-
-@given('we have XFSC TRAIN Trusted Content Resolver REST API')
-def step_impl(context):
-    # TODO make a heartbeat requests
-    # ask kubernetis url
-    # load trusted-content-resolver/service/src/main/resources/application.yml into context
-    context.ctr = TrustedContentResolver('http://localhost:8087')
-    pass
-
-
-@given('an actor X to be verified')
-def step_impl(context):
-    # TODO check the data if available
-    # load input data for actor x into context
-    context.actor_x = {
-        'some': 'info'
-    }
-
-
-@when('we initiate a verification actor X')
-def step_impl(context):
-    response = SESSION.get(f'https://example.com')
-
-    #response = SESSION.post(f'{context.ctr.app}/tcr/verify', data=context.actor_x['some'])
-    context.ctr.response = response
-
-
-@then('actor X gets verified')
-def step_impl(context):
-    assert context.ctr.response
-
-
-@when("we initiate a verification actor Y")
-def step_impl(context):
-    """
-    :type context: behave.runner.Context
-    """
-    raise NotImplementedError(u'STEP: When we initiate a verification actor Y')
-
-
-# @given(
-#     "A request update of trust frameworks and DID configuration is successfully reflected in the DNS Zone File (200)")
-# def step_impl(context):
-#     """
-#     :type context: behave.runner.Context
-#     """
-#     # GET to DNS which return success DID configuration
-#     raise NotImplementedError(
-#         u'STEP: Given A request update of trust frameworks and DID configuration is successfully reflected in the DNS Zone File (200)')
-#
-#
-# @step(
-#     "An instantiation of a trust list is reflected in the trust list storage with possibility to retrieve via API endpoints")
-# def step_impl(context):
-#     """
-#     :type context: behave.runner.Context
-#     """
-#     # qhuery database for
-#     raise NotImplementedError(
-#         u'STEP: And An instantiation of a trust list is reflected in the trust list storage with possibility to retrieve via API endpoints')
-#
-#
-# @given("trust framework pointers example.federation1.de and example.federation2.de")
-# def step_impl(context):
-#     """
-#     :type context: behave.runner.Context
-#     """
-#     context.trust_framework_pointers = 'example.federation1.de' and 'example.federation2.de']
-#
-#
-#     @when("Navigate to listed trust framework pointers")
-#     def step_impl(context):
-#         """
-#         :type context: behave.runner.Context
-#         """
-#         data = VerificationRequest(context.trust_framework_pointers)
-#         response = SESSION.post(f'{context.ctr.app}/tcr/verify', data=data.json())
-#         context.ctr.response = response
-#
-#
-# @then("have example.federation1.de and example.federation2.de should be in trust List VC endpoint")
-# def step_impl(context):
-#     """
-#     :type context: behave.runner.Context
-#     """
-#     assert sql.query('SELECT WHERE x in [xample.federation1.de and example.federation2.de]') is True
diff --git a/clients/py/tests/resolve_service_client_test.py b/clients/py/tests/resolve_service_client_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..de00f8b756cbbac123d0938a51e7459b4cf6537b
--- /dev/null
+++ b/clients/py/tests/resolve_service_client_test.py
@@ -0,0 +1,12 @@
+"""
+Testing python client
+"""
+
+from trusted_content_resolver_client import resolve_service_client
+
+
+def test_resolve_trust_list():
+    """
+    WIP
+    """
+    assert resolve_service_client.resolve_trust_list() == "something"
diff --git a/docker/.env b/docker/.env
index ee100a2bd59192b5ccddd418ed8b75f7481eb800..68879fae30d220a12b4dc4ff2d18fe6b27622e88 100644
--- a/docker/.env
+++ b/docker/.env
@@ -1,6 +1 @@
 COMPOSE_PROJECT_NAME = xfsc-train
-
-### FC SERVER PROPERTIES ###
-CI_REGISTRY=registry.gitlab.com/gaia-x/data-infrastructure-federation-services/cat/fc-service
-# federated-catalog client secret, gaia-x realm
-FC_CLIENT_SECRET=vZo1equicRl1UdxJDWCNNJWe6vJcm2Cg
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..77f788042a944c2bf7bcd73b786be7871115b601
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,45 @@
+## Build Procedure
+
+Ensure you have JDK 17, Maven 3.5.4 (or newer) and Git installed
+
+First clone the TRAIN Trusted Content Resolver (TCR) repository:
+
+``` sh
+git clone git@gitlab.eclipse.org/eclipse/xfsc/train/trusted-content-resolver.git
+```
+
+Then build project with `maven`:
+
+``` sh
+cd <tcr_root_folder>
+mvn clean install 
+```
+
+## Run TCR as local Docker image
+Go to `/docker` folder. Use docker compose to start universal-resolver with did:web driver only:
+
+```sh
+docker compose --env-file unires.env -f uni-resolver-web.yml up -d
+```
+
+or with all available universal-resolver drivers: 
+
+```sh
+docker compose --env-file unires.env -f uni-resolver-all.yml up -d
+```
+
+To test did:web resolution you can try the following CURL commands:
+
+``` sh
+curl -X GET http://localhost:8080/1.0/identifiers/did:web:did.actor:alice
+curl -X GET http://localhost:8080/1.0/identifiers/did:web:did.actor:bob
+curl -X GET http://localhost:8080/1.0/identifiers/did:web:did.actor:mike
+```
+
+Then start TCR: 
+ 
+``` sh
+docker compose up -d
+```
+
+For more information on universal-resolver please see the project on [GitHub](https://github.com/decentralized-identity/universal-resolver)
diff --git a/docker/bare_metal_dev_setup/Dockerfile b/docker/bare_metal_dev_setup/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..87fe9aefd05f0f1f200d26efcaf27a79b3734cca
--- /dev/null
+++ b/docker/bare_metal_dev_setup/Dockerfile
@@ -0,0 +1,14 @@
+ARG UBUNTU_BASE_IMAGE_WITH_TAG
+
+# Specify the parent image from which we build
+FROM ${UBUNTU_BASE_IMAGE_WITH_TAG}
+
+# don't bother with multiple layers since it is local dev purpose container
+# Build the application with cmake
+RUN apt update -y
+RUN DEBIAN_FRONTEND=noninteractive apt install sudo build-essential ansible git zip unzip bash-completion -y
+
+# do not ask password with sudo for ubuntu user, required for ansible automation
+RUN echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+
+#WORKDIR /app
diff --git a/docker/bare_metal_dev_setup/Makefile b/docker/bare_metal_dev_setup/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..564154e3779cd18cb4578ff68dd1ac534f8f59ab
--- /dev/null
+++ b/docker/bare_metal_dev_setup/Makefile
@@ -0,0 +1,43 @@
+TRAIN_UBUNTU_VERSION ?= 23.10
+TRAIN_CONTAINER_ENGINE ?= docker
+TRAIN_UBUNTU_BASE_IMAGE_WITH_TAG ?= ubuntu:$(TRAIN_UBUNTU_VERSION)
+
+TRAIN_CONTAINER_NAME ?= trust-content-resolver
+
+_prepare_container-on-os: _$(TRAIN_CONTAINER_ENGINE)-on-$(shell uname -s)
+_podman-on-Darwin:
+	@podman ps &> /dev/null || podman machine start
+_docker-on-Darwin:
+	# not implemented
+_%-on-Linux:
+	# linux do not require a vm
+_%-on-%:
+	$(error Not supported OS yet)
+
+build: _prepare_container-on-os
+	$(TRAIN_CONTAINER_ENGINE) build \
+		--build-arg UBUNTU_BASE_IMAGE_WITH_TAG=$(TRAIN_UBUNTU_BASE_IMAGE_WITH_TAG) \
+		--tag=trust-content-resolver/$(TRAIN_UBUNTU_BASE_IMAGE_WITH_TAG) \
+		--file=./Dockerfile
+
+ubuntu_bash: _prepare_container-on-os
+	@set -x && if ! $(TRAIN_CONTAINER_ENGINE) container inspect $(TRAIN_CONTAINER_NAME) &> /dev/null; \
+    	then $(TRAIN_CONTAINER_ENGINE) run \
+    		--name $(TRAIN_CONTAINER_NAME) \
+    		--interactive \
+    		--tty \
+    		--volume=../..:/app:rw \
+    		--workdir=/app \
+    		--user 0:0 \
+    			localhost/trust-content-resolver/$(TRAIN_UBUNTU_BASE_IMAGE_WITH_TAG) bash; \
+		else $(TRAIN_CONTAINER_ENGINE) start \
+			--interactive \
+			--attach \
+				$(TRAIN_CONTAINER_NAME); \
+	fi
+
+rm: _prepare_container-on-os
+	$(TRAIN_CONTAINER_ENGINE) rm $(TRAIN_CONTAINER_NAME)
+
+rmi: rm
+	$(TRAIN_CONTAINER_ENGINE) rmi trust-content-resolver/$(TRAIN_UBUNTU_BASE_IMAGE_WITH_TAG)
diff --git a/docker/bare_metal_dev_setup/README.md b/docker/bare_metal_dev_setup/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..da8eaee06853d585267b9ff9560162414986ac26
--- /dev/null
+++ b/docker/bare_metal_dev_setup/README.md
@@ -0,0 +1,12 @@
+Automation for provisioning OS developer environments is done through Ansible playbooks for Ubuntu and macOS.
+
+On macOS, playbooks are executed manually from time to time on developers' machines.
+
+On Linux, it can be integrated into CI/CD with:
+``` bahs
+$ export TRAIN_CONTAINER_ENGINE=podman # if podman is preferred against docker
+$ make rmi # delete previuos image with all containters
+$ make build # add to ubuntu image some requorements for make, go, pyhton, java and js 
+$ make ubuntu_bash # log into ubunut
+> make ansible # provison ubuntu with all tools requires for develop components in go, pyhton, java and js
+```
\ No newline at end of file
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 5004ca9b4e2a93eb5842b18fc707f6da3f26ec75..947c4df1386483db8422934e053acd0e73045da0 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,5 +1,9 @@
 version: '3.7'
 
+#include:
+#  - uni-drivers.yml
+#  - uni-resolver.yml
+
 services:
   server:
     container_name: "tcr-server"
@@ -9,7 +13,7 @@ services:
       dockerfile: Dockerfile
 #    environment:
     ports:
-      - "8087:8087"
+      - "8887:8087"
     networks:
       - "gaia-x"
 #    extra_hosts:
diff --git a/docker/uni-resolver-all.yml b/docker/uni-resolver-all.yml
new file mode 100644
index 0000000000000000000000000000000000000000..71338293a019bb4487e2621aacaeabb2348a4fdd
--- /dev/null
+++ b/docker/uni-resolver-all.yml
@@ -0,0 +1,288 @@
+version: "3.7"
+
+networks:
+  default:
+    name: universal-resolver
+
+services:
+  uni-resolver-web:
+    image: universalresolver/uni-resolver-web:latest
+    ports:
+      - "8080:8080"
+  driver-did-btcr:
+    image: universalresolver/driver-did-btcr:latest
+    environment:
+      uniresolver_driver_did_btcr_bitcoinConnection: ${uniresolver_driver_did_btcr_bitcoinConnection}
+      uniresolver_driver_did_btcr_rpcUrlMainnet: ${uniresolver_driver_did_btcr_rpcUrlMainnet}
+      uniresolver_driver_did_btcr_rpcUrlTestnet: ${uniresolver_driver_did_btcr_rpcUrlTestnet}
+      uniresolver_driver_did_btcr_rpcCertMainnet: ${uniresolver_driver_did_btcr_rpcCertMainnet}
+      uniresolver_driver_did_btcr_rpcCertTestnet: ${uniresolver_driver_did_btcr_rpcCertTestnet}
+    ports:
+      - "8081:8080"
+  driver-did-sov:
+    image: universalresolver/driver-did-sov:latest
+    environment:
+      uniresolver_driver_did_sov_libIndyPath: ${uniresolver_driver_did_sov_libIndyPath}
+      uniresolver_driver_did_sov_poolConfigs: ${uniresolver_driver_did_sov_poolConfigs}
+      uniresolver_driver_did_sov_poolVersions: ${uniresolver_driver_did_sov_poolVersions}
+      uniresolver_driver_did_sov_walletNames: ${uniresolver_driver_did_sov_walletNames}
+      uniresolver_driver_did_sov_submitterDidSeeds: ${uniresolver_driver_did_sov_submitterDidSeeds}
+    ports:
+      - "8082:8080"
+  uni-resolver-driver-did-uport:
+    image: uport/uni-resolver-driver-did-uport:4.1.0
+    ports:
+      - "8083:8081"
+  driver-did-stack:
+    image: universalresolver/driver-did-stack:latest
+    ports:
+      - "8084:8080"
+  driver-dns:
+    image: universalresolver/driver-dns:latest
+    environment:
+      uniresolver_driver_dns_dnsServers: ${uniresolver_driver_dns_dnsServers}
+    ports:
+      - "8087:8080"
+  jolocom-did-driver:
+    image: jolocomgmbh/jolocom-did-driver:latest
+    ports:
+      - "8088:8080"
+  hacera-did-driver:
+    image: hacera/hacera-did-driver:latest
+    ports:
+      - "8089:8080"
+  driver-did-ccp:
+    image: universalresolver/driver-did-ccp:latest
+    ports:
+      - "8091:8080"
+  ontid-driver:
+    image: ontio/ontid-driver:latest
+    ports:
+      - "8093:8080"
+  kilt-did-driver:
+    image: kiltprotocol/kilt-did-driver:2.4.2
+    environment:
+      KILT_BLOCKCHAIN_NODE: ${uniresolver_driver_kilt_blockchain_node}
+    ports:
+      - "8094:8080"
+  evan-did-driver:
+    image: evannetwork/evan-did-driver:latest
+    ports:
+      - "8095:8080"
+  uni-resolver-driver-did-factom:
+    image: sphereon/uni-resolver-driver-did-factom:latest
+    ports:
+      - "8097:8080"
+  uni-resolver-did-v1-driver:
+    image: veresone/uni-resolver-did-v1-driver:latest
+    ports:
+      - "8100:8080"
+  driver-did-mpg:
+    image: mpgshankr/driver-did-mpg:latest
+    ports:
+      - "8103:8080"
+  uni-resolver-driver-did-io:
+    image: iotex/uni-resolver-driver-did-io:latest
+    ports:
+      - "8104:8080"
+  bba-did-driver:
+    container_name: bba-did-driver
+    image: blobaa/bba-did-driver:0.2.2
+    ports:
+      - "8107:8080"
+  schema-registry-did-resolver:
+    image: 51nodes/schema-registry-did-resolver:0.1.1
+    ports:
+      - "8110:8080"
+# runtime error
+#  driver-did-ion:
+#    image: identityfoundation/driver-did-ion:v0.8.1
+#    ports:
+#      - "8111:8080"
+  ace-did-driver:
+    container_name: ace-did-driver
+    image: aceblock/ace-did-driver:latest
+    environment:
+      UNIRESOLVER_DRIVER_DID_ACE: ${UNIRESOLVER_DRIVER_DID_ACE}
+    ports:
+      - "8112:8080"
+  gataca-did-resolver-driver:
+    container_name: gataca-did-resolver-driver
+    image: gatacaid/universal-resolver-driver:2.0.0
+    ports:
+      - "8113:8080"
+  driver-did-icon:
+    image: amuyu/driver-did-icon:0.1.3
+    environment:
+      uniresolver_driver_did_icon_node_url: ${uniresolver_driver_did_icon_node_url}
+      uniresolver_driver_did_icon_score_addr: ${uniresolver_driver_did_icon_score_addr}
+      uniresolver_driver_did_icon_network_id: ${uniresolver_driver_did_icon_network_id}
+    ports:
+      - "8114:8080"
+  driver-did-vaa:
+    image: caictdevelop/driver-did-vaa:1.0.0
+    ports:
+      - "8115:8080"
+  unisot-did-driver:
+    image: unisot/unisot-did-driver:latest
+    ports:
+      - "8116:8080"
+  driver-did-sol:
+    image: identitydotcom/driver-did-sol:3.3.0
+    ports:
+      - "8118:8080"
+  driver-did-lit:
+    image: ibct/driver-did-lit:0.1.1
+    environment:
+      LEDGIS_LIT_ENDPOINT: ${LEDGIS_LIT_ENDPOINT}
+      LEDGIS_LIT_CODE: ${LEDGIS_LIT_CODE}
+    ports:
+      - "8119:8080"
+  driver-did-emtrust:
+    image: halialabsdev/emtrust_did_driver:latest
+    ports:
+      - "8120:8080"
+# image error
+#  driver-didkit:
+#    image: ghcr.io/spruceid/didkit-http:latest
+#    environment:
+#      PORT: 3000
+#      HOST: 0.0.0.0
+#    ports:
+#      - "8121:3000"
+  eosio-driver:
+    container_name: eosio-driver
+    image: gimlyblockchain/eosio-universal-resolver-driver
+    ports:
+      - "8123:8080"
+# image error
+#  orb-did-driver:
+#    container_name: orb-did-driver
+#    image: ghcr.io/trustbloc-cicd/orb-did-driver:v1.0.0-rc4-snapshot-7125f6a
+#    environment:
+#      ORB_DRIVER_HOST_URL: ${ORB_DRIVER_HOST_URL}
+#      ORB_DRIVER_TLS_SYSTEMCERTPOOL: ${ORB_DRIVER_TLS_SYSTEMCERTPOOL}
+#      ORB_DRIVER_VERIFY_RESOLUTION_RESULT_TYPE: ${ORB_DRIVER_VERIFY_RESOLUTION_RESULT_TYPE}
+#    ports:
+#      - "8122:8121"
+#    command: start
+  driver-did-oyd:
+    image: oydeu/oydid-resolver:v0.4.5
+    ports:
+      - "8124:3000"
+  driver-did-moncon:
+    image: camicasii/didresolver-g
+    ports:
+      - "8125:8080"
+  dock-did-driver:
+    image: docknetwork/dock-did-driver:latest
+    ports:
+      - "8099:8080"
+  mydata-did-driver:
+    image: igrantio/uni-resolver-driver-did-mydata:1.3
+    ports:
+      - "8126:8080"
+  driver-did-dns:
+    image: universalresolver/driver-did-dns:latest
+    ports:
+      - "8127:8080"
+  driver-did-indy:
+    image: universalresolver/driver-did-indy:latest
+    environment:
+      uniresolver_driver_did_indy_libIndyPath: ${uniresolver_driver_did_indy_libIndyPath}
+      uniresolver_driver_did_indy_poolConfigs: ${uniresolver_driver_did_indy_poolConfigs}
+      uniresolver_driver_did_indy_poolVersions: ${uniresolver_driver_did_indy_poolVersions}
+      uniresolver_driver_did_indy_walletNames: ${uniresolver_driver_did_indy_walletNames}
+      uniresolver_driver_did_indy_submitterDidSeeds: ${uniresolver_driver_did_indy_submitterDidSeeds}
+    ports:
+      - "8128:8080"
+  everscale-did-driver:
+    image: radianceteamssi/everscale-did-resolver-driver:latest
+    ports:
+      - "8129:8080"
+  alastria-did-driver-mvp2:
+    image: alastria/uni-resolver-driver-did-alastria:mvp2
+    ports:
+      - "8130:8080"
+  cheqd-did-driver:
+    image: ghcr.io/cheqd/did-resolver:3.2.1
+    ports:
+      - "8131:8080"
+    environment:
+      MAINNET_ENDPOINT: "grpc.cheqd.net:443,true,5s"
+      TESTNET_ENDPOINT: "grpc.cheqd.network:443,true,5s"
+      LOG_LEVEL: "warn"
+      RESOLVER_LISTENER: "0.0.0.0:8080"
+  driver-did-com:
+    image: ghcr.io/commercionetwork/uni-resolver-driver-did-com:latest
+    environment:
+      uniresolver_driver_did_com_network: ${uniresolver_driver_did_com_network}
+    ports:
+      - "8132:8080"
+  did-driver-dyne:
+    image: dyne/w3c-did-driver:latest
+    ports:
+      - "8133:8080"
+  did-jwk-driver:
+    image: transmute/restricted-resolver:latest
+    ports:
+      - "8134:8080"
+  did-kscirc-driver:
+    image: k4security/kschain-resolver:latest
+    ports:
+      - "8135:8080"
+  driver-did-iscc:
+    image: ghcr.io/iscc/iscc-did-driver:main
+    ports:
+      - "8136:8080"
+# image error
+#  driver-did-ev:
+#    image: ghcr.io/kaytrust/driver-did-ev:latest
+#    environment:
+#      NODE_HOST: ${uniresolver_driver_did_ev_node_url}
+#      ADDRESS_IM: ${uniresolver_driver_did_ev_address_im}
+#      BASE_BLOCKS: ${uniresolver_driver_did_ev_base_blocks}
+#    ports:
+#      - "8137:8000"
+  driver-did-iid:
+    image: zoeyian/driver-did-iid:latest
+    ports:
+      - "8138:8080"
+  driver-did-bid:
+    image: caictdevelop/driver-did-bid:latest
+    ports:
+      - "8139:8080"
+# image error
+#  driver-did-algo:
+#    image: ghcr.io/bryk-io/algoid-resolver:latest
+#    ports:
+#      - "8140:9091"
+  driver-did-polygonid:
+    image: polygonid/driver-did-polygonid:latest
+    ports:
+      - "8141:8080"
+  driver-did-pdc:
+    image: w744219971/driver-did-pdc:latest
+    ports:
+      - "8142:8080"
+  driver-did-tys:
+    image: itpeoplecorp/tys-did-driver:latest
+    ports:
+      - "8143:8080"
+  driver-did-plc:
+    image: bnewbold/uni-resolver-driver-did-plc:latest
+    ports:
+      - "8144:8000"
+  driver-did-evrc:
+    image: viitorcloud/uni-resolver-driver-did-evrc:latest
+    ports:
+      - "8145:8080"
+  driver-did-keri:
+    image: gleif/did-keri-resolver-service:latest
+    ports:
+      - "8146:7678"
+  driver-did-webs:
+    image: gleif/did-webs-resolver-service:latest
+    ports:
+      - "8147:7677"
+
diff --git a/docker/uni-resolver-web.yml b/docker/uni-resolver-web.yml
new file mode 100644
index 0000000000000000000000000000000000000000..56b7d0178755b682aa216257ebba8bcb871a5306
--- /dev/null
+++ b/docker/uni-resolver-web.yml
@@ -0,0 +1,290 @@
+version: "3.7"
+
+#include:
+#  - uni-drivers.yml
+
+networks:
+  default:
+    name: universal-resolver
+
+services:
+  uni-resolver-web:
+    image: universalresolver/uni-resolver-web:latest
+    ports:
+      - "8080:8080"
+#  driver-did-btcr:
+#    image: universalresolver/driver-did-btcr:latest
+#    environment:
+#      uniresolver_driver_did_btcr_bitcoinConnection: ${uniresolver_driver_did_btcr_bitcoinConnection}
+#      uniresolver_driver_did_btcr_rpcUrlMainnet: ${uniresolver_driver_did_btcr_rpcUrlMainnet}
+#      uniresolver_driver_did_btcr_rpcUrlTestnet: ${uniresolver_driver_did_btcr_rpcUrlTestnet}
+#      uniresolver_driver_did_btcr_rpcCertMainnet: ${uniresolver_driver_did_btcr_rpcCertMainnet}
+#      uniresolver_driver_did_btcr_rpcCertTestnet: ${uniresolver_driver_did_btcr_rpcCertTestnet}
+#    ports:
+#      - "8081:8080"
+#  driver-did-sov:
+#    image: universalresolver/driver-did-sov:latest
+#    environment:
+#      uniresolver_driver_did_sov_libIndyPath: ${uniresolver_driver_did_sov_libIndyPath}
+#      uniresolver_driver_did_sov_poolConfigs: ${uniresolver_driver_did_sov_poolConfigs}
+#      uniresolver_driver_did_sov_poolVersions: ${uniresolver_driver_did_sov_poolVersions}
+#      uniresolver_driver_did_sov_walletNames: ${uniresolver_driver_did_sov_walletNames}
+#      uniresolver_driver_did_sov_submitterDidSeeds: ${uniresolver_driver_did_sov_submitterDidSeeds}
+#    ports:
+#      - "8082:8080"
+  uni-resolver-driver-did-uport:
+    image: uport/uni-resolver-driver-did-uport:4.1.0
+    ports:
+      - "8083:8081"
+#  driver-did-stack:
+#    image: universalresolver/driver-did-stack:latest
+#    ports:
+#      - "8084:8080"
+#  driver-dns:
+#    image: universalresolver/driver-dns:latest
+#    environment:
+#      uniresolver_driver_dns_dnsServers: ${uniresolver_driver_dns_dnsServers}
+#    ports:
+#      - "8087:8080"
+#  jolocom-did-driver:
+#    image: jolocomgmbh/jolocom-did-driver:latest
+#    ports:
+#      - "8088:8080"
+#  hacera-did-driver:
+#    image: hacera/hacera-did-driver:latest
+#    ports:
+#      - "8089:8080"
+#  driver-did-ccp:
+#    image: universalresolver/driver-did-ccp:latest
+#    ports:
+#      - "8091:8080"
+#  ontid-driver:
+#    image: ontio/ontid-driver:latest
+#    ports:
+#      - "8093:8080"
+#  kilt-did-driver:
+#    image: kiltprotocol/kilt-did-driver:2.4.2
+#    environment:
+#      KILT_BLOCKCHAIN_NODE: ${uniresolver_driver_kilt_blockchain_node}
+#    ports:
+#      - "8094:8080"
+#  evan-did-driver:
+#    image: evannetwork/evan-did-driver:latest
+#    ports:
+#      - "8095:8080"
+#  uni-resolver-driver-did-factom:
+#    image: sphereon/uni-resolver-driver-did-factom:latest
+#    ports:
+#      - "8097:8080"
+#  uni-resolver-did-v1-driver:
+#    image: veresone/uni-resolver-did-v1-driver:latest
+#    ports:
+#      - "8100:8080"
+#  driver-did-mpg:
+#    image: mpgshankr/driver-did-mpg:latest
+#    ports:
+#      - "8103:8080"
+#  uni-resolver-driver-did-io:
+#    image: iotex/uni-resolver-driver-did-io:latest
+#    ports:
+#      - "8104:8080"
+#  bba-did-driver:
+#    container_name: bba-did-driver
+#    image: blobaa/bba-did-driver:0.2.2
+#    ports:
+#      - "8107:8080"
+  schema-registry-did-resolver:
+    image: 51nodes/schema-registry-did-resolver:0.1.1
+    ports:
+      - "8110:8080"
+# runtime error
+#  driver-did-ion:
+#    image: identityfoundation/driver-did-ion:v0.8.1
+#    ports:
+#      - "8111:8080"
+#  ace-did-driver:
+#    container_name: ace-did-driver
+#    image: aceblock/ace-did-driver:latest
+#    environment:
+#      UNIRESOLVER_DRIVER_DID_ACE: ${UNIRESOLVER_DRIVER_DID_ACE}
+#    ports:
+#      - "8112:8080"
+#  gataca-did-resolver-driver:
+#    container_name: gataca-did-resolver-driver
+#    image: gatacaid/universal-resolver-driver:2.0.0
+#    ports:
+#      - "8113:8080"
+#  driver-did-icon:
+#    image: amuyu/driver-did-icon:0.1.3
+#    environment:
+#      uniresolver_driver_did_icon_node_url: ${uniresolver_driver_did_icon_node_url}
+#      uniresolver_driver_did_icon_score_addr: ${uniresolver_driver_did_icon_score_addr}
+#      uniresolver_driver_did_icon_network_id: ${uniresolver_driver_did_icon_network_id}
+#    ports:
+#      - "8114:8080"
+#  driver-did-vaa:
+#    image: caictdevelop/driver-did-vaa:1.0.0
+#    ports:
+#      - "8115:8080"
+#  unisot-did-driver:
+#    image: unisot/unisot-did-driver:latest
+#    ports:
+#      - "8116:8080"
+#  driver-did-sol:
+#    image: identitydotcom/driver-did-sol:3.3.0
+#    ports:
+#      - "8118:8080"
+#  driver-did-lit:
+#    image: ibct/driver-did-lit:0.1.1
+#    environment:
+#      LEDGIS_LIT_ENDPOINT: ${LEDGIS_LIT_ENDPOINT}
+#      LEDGIS_LIT_CODE: ${LEDGIS_LIT_CODE}
+#    ports:
+#      - "8119:8080"
+#  driver-did-emtrust:
+#    image: halialabsdev/emtrust_did_driver:latest
+#    ports:
+#      - "8120:8080"
+# image error
+#  driver-didkit:
+#    image: ghcr.io/spruceid/didkit-http:latest
+#    environment:
+#      PORT: 3000
+#      HOST: 0.0.0.0
+#    ports:
+#      - "8121:3000"
+#  eosio-driver:
+#    container_name: eosio-driver
+#    image: gimlyblockchain/eosio-universal-resolver-driver
+#    ports:
+#      - "8123:8080"
+# image error
+#  orb-did-driver:
+#    container_name: orb-did-driver
+#    image: ghcr.io/trustbloc-cicd/orb-did-driver:v1.0.0-rc4-snapshot-7125f6a
+#    environment:
+#      ORB_DRIVER_HOST_URL: ${ORB_DRIVER_HOST_URL}
+#      ORB_DRIVER_TLS_SYSTEMCERTPOOL: ${ORB_DRIVER_TLS_SYSTEMCERTPOOL}
+#      ORB_DRIVER_VERIFY_RESOLUTION_RESULT_TYPE: ${ORB_DRIVER_VERIFY_RESOLUTION_RESULT_TYPE}
+#    ports:
+#      - "8122:8121"
+#    command: start
+#  driver-did-oyd:
+#    image: oydeu/oydid-resolver:v0.4.5
+#    ports:
+#      - "8124:3000"
+#  driver-did-moncon:
+#    image: camicasii/didresolver-g
+#    ports:
+#      - "8125:8080"
+#  dock-did-driver:
+#    image: docknetwork/dock-did-driver:latest
+#    ports:
+#      - "8099:8080"
+#  mydata-did-driver:
+#    image: igrantio/uni-resolver-driver-did-mydata:1.3
+#    ports:
+#      - "8126:8080"
+#  driver-did-dns:
+#    image: universalresolver/driver-did-dns:latest
+#    ports:
+#      - "8127:8080"
+#  driver-did-indy:
+#    image: universalresolver/driver-did-indy:latest
+#    environment:
+#      uniresolver_driver_did_indy_libIndyPath: ${uniresolver_driver_did_indy_libIndyPath}
+#      uniresolver_driver_did_indy_poolConfigs: ${uniresolver_driver_did_indy_poolConfigs}
+#      uniresolver_driver_did_indy_poolVersions: ${uniresolver_driver_did_indy_poolVersions}
+#      uniresolver_driver_did_indy_walletNames: ${uniresolver_driver_did_indy_walletNames}
+#      uniresolver_driver_did_indy_submitterDidSeeds: ${uniresolver_driver_did_indy_submitterDidSeeds}
+#    ports:
+#      - "8128:8080"
+#  everscale-did-driver:
+#    image: radianceteamssi/everscale-did-resolver-driver:latest
+#    ports:
+#      - "8129:8080"
+#  alastria-did-driver-mvp2:
+#    image: alastria/uni-resolver-driver-did-alastria:mvp2
+#    ports:
+#      - "8130:8080"
+#  cheqd-did-driver:
+#    image: ghcr.io/cheqd/did-resolver:3.2.1
+#    ports:
+#      - "8131:8080"
+#    environment:
+#      MAINNET_ENDPOINT: "grpc.cheqd.net:443,true,5s"
+#      TESTNET_ENDPOINT: "grpc.cheqd.network:443,true,5s"
+#      LOG_LEVEL: "warn"
+#      RESOLVER_LISTENER: "0.0.0.0:8080"
+#  driver-did-com:
+#    image: ghcr.io/commercionetwork/uni-resolver-driver-did-com:latest
+#    environment:
+#      uniresolver_driver_did_com_network: ${uniresolver_driver_did_com_network}
+#    ports:
+#      - "8132:8080"
+#  did-driver-dyne:
+#    image: dyne/w3c-did-driver:latest
+#    ports:
+#      - "8133:8080"
+#  did-jwk-driver:
+#    image: transmute/restricted-resolver:latest
+#    ports:
+#      - "8134:8080"
+#  did-kscirc-driver:
+#    image: k4security/kschain-resolver:latest
+#    ports:
+#      - "8135:8080"
+#  driver-did-iscc:
+#    image: ghcr.io/iscc/iscc-did-driver:main
+#    ports:
+#      - "8136:8080"
+# image error
+#  driver-did-ev:
+#    image: ghcr.io/kaytrust/driver-did-ev:latest
+#    environment:
+#      NODE_HOST: ${uniresolver_driver_did_ev_node_url}
+#      ADDRESS_IM: ${uniresolver_driver_did_ev_address_im}
+#      BASE_BLOCKS: ${uniresolver_driver_did_ev_base_blocks}
+#    ports:
+#      - "8137:8000"
+#  driver-did-iid:
+#    image: zoeyian/driver-did-iid:latest
+#    ports:
+#      - "8138:8080"
+#  driver-did-bid:
+#    image: caictdevelop/driver-did-bid:latest
+#    ports:
+#      - "8139:8080"
+# image error
+#  driver-did-algo:
+#    image: ghcr.io/bryk-io/algoid-resolver:latest
+#    ports:
+#      - "8140:9091"
+#  driver-did-polygonid:
+#    image: polygonid/driver-did-polygonid:latest
+#    ports:
+#      - "8141:8080"
+#  driver-did-pdc:
+#    image: w744219971/driver-did-pdc:latest
+#    ports:
+#      - "8142:8080"
+#  driver-did-tys:
+#    image: itpeoplecorp/tys-did-driver:latest
+#    ports:
+#      - "8143:8080"
+#  driver-did-plc:
+#    image: bnewbold/uni-resolver-driver-did-plc:latest
+#    ports:
+#      - "8144:8000"
+#  driver-did-evrc:
+#    image: viitorcloud/uni-resolver-driver-did-evrc:latest
+#    ports:
+#      - "8145:8080"
+#  driver-did-keri:
+#    image: gleif/did-keri-resolver-service:latest
+#    ports:
+#      - "8146:7678"
+#  driver-did-webs:
+#    image: gleif/did-webs-resolver-service:latest
+#    ports:
+#      - "8147:7677"
diff --git a/docker/unires.env b/docker/unires.env
new file mode 100644
index 0000000000000000000000000000000000000000..f49aafb184179d21bf9a8d565a924e4a00681bc3
--- /dev/null
+++ b/docker/unires.env
@@ -0,0 +1,58 @@
+COMPOSE_PROJECT_NAME = universal-resolver
+
+uniresolver_driver_did_btcr_bitcoinConnection=blockcypherapi
+uniresolver_driver_did_btcr_rpcUrlMainnet=http://user:pass@localhost:8332/
+uniresolver_driver_did_btcr_rpcUrlTestnet=http://user:pass@localhost:18332/
+uniresolver_driver_did_btcr_rpcCertMainnet=
+uniresolver_driver_did_btcr_rpcCertTestnet=
+
+uniresolver_driver_did_sov_libIndyPath=
+uniresolver_driver_did_sov_poolConfigs=_;./sovrin/_.txn;staging;./sovrin/staging.txn;builder;./sovrin/builder.txn;danube;./sovrin/danube.txn;idunion;./sovrin/idunion.txn;idunion:test;./sovrin/idunion-test.txn;indicio;./sovrin/indicio.txn;indicio:test;./sovrin/indicio-test.txn;indicio:demo;./sovrin/indicio-demo.txn;bbu;./sovrin/bbu.txn
+uniresolver_driver_did_sov_poolVersions=_;2;staging;2;builder;2;danube;2;idunion;2;idunion:test;2;indicio;2;indicio:test;2;indicio:demo;2;bbu;2
+uniresolver_driver_did_sov_walletNames=_;w1;staging;w2;builder;w3;danube;w4;idunion;w5;idunion:test;w6;indicio;w7;indicio:test;w8;indicio:demo;w9;bbu;w10
+uniresolver_driver_did_sov_submitterDidSeeds=_;_;staging;_;builder;_;danube;_;idunion;_;idunion:test;_;indicio;_;indicio:test;_;indicio:demo;_;bbu;_
+
+uniresolver_driver_did_erc725_ethereumConnections=mainnet;hybrid;ropsten;hybrid;rinkeby;hybrid;kovan;hybrid
+uniresolver_driver_did_erc725_rpcUrls=mainnet;https://mainnet.infura.io/v3/fd9e225bc1234f49b48b295c611078eb;ropsten;https://ropsten.infura.io/v3/fd9e225bc1234f49b48b295c611078eb;rinkeby;https://rinkeby.infura.io/v3/fd9e225bc1234f49b48b295c611078eb;kovan;https://kovan.infura.io/v3/fd9e225bc1234f49b48b295c611078eb
+uniresolver_driver_did_erc725_etherscanApis=mainnet;http://api.etherscan.io/api;ropsten;http://api-ropsten.etherscan.io/api;rinkeby;http://api-rinkeby.etherscan.io/api;kovan;http://api-kovan.etherscan.io/api
+
+uniresolver_driver_did_work_apikey=sxVQUoDE015VhAs5ep4b57DFA5vT3zqvf1Dm1sGe
+uniresolver_driver_did_work_domain=https://credentials.id.workday.com
+
+uniresolver_driver_kilt_blockchain_node=wss://spiritnet.kilt.io
+
+uniresolver_driver_dns_dnsServers=
+
+uniresolver_driver_did_echo_mainnet_rpc_url=http://127.0.0.1:8090/rpc
+uniresolver_driver_did_echo_testnet_rpc_url=http://testnet.echo-dev.io
+uniresolver_driver_did_echo_devnet_rpc_url=http://127.0.0.1:8090/rpc
+
+DID_METHOD_HOST_URL=0.0.0.0:8102
+DID_METHOD_TLS_SYSTEMCERTPOOL=true
+DID_METHOD_MODE=resolver
+
+UNIRESOLVER_DRIVER_DID_ACE=prod
+
+uniresolver_driver_did_icon_node_url=https://sejong.net.solidwallet.io/api/v3
+uniresolver_driver_did_icon_score_addr=cxc7c8b0bb85eca64aecc8cc38628c4bc3c449f1fd
+uniresolver_driver_did_icon_network_id=83
+
+LEDGIS_LIT_ENDPOINT=https://lit.ledgis.io
+LEDGIS_LIT_CODE=lit
+
+ORB_DRIVER_HOST_URL=0.0.0.0:8121
+ORB_DRIVER_TLS_SYSTEMCERTPOOL=true
+ORB_DRIVER_VERIFY_RESOLUTION_RESULT_TYPE=all
+
+uniresolver_driver_did_dns_dnsServers=
+uniresolver_driver_did_dns_didKeyResolver=https://dev.uniresolver.io/1.0/
+
+uniresolver_driver_did_com_network=https://lcd-mainnet.commercio.network
+
+uniresolver_driver_did_ev_node_url=https://polygon-mumbai.g.alchemy.com/v2/jLMUummm16stzMQjW1OB79IwuDjsJqS7
+uniresolver_driver_did_ev_address_im=0x4E4f55190185f2694D331E5c9Fd70a2B75Eb4Bd2
+uniresolver_driver_did_ev_base_blocks=2700000
+
+LOGGING_LEVEL_ROOT: INFO
+MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "*"
+
diff --git a/openapi/tcr_openapi.yaml b/openapi/tcr_openapi.yaml
index efcda1fe6694e13ded9c46a137f12146f6cfa59c..df41a502cd4621aa2f7d5e39b0c4cfbb4d0ede64 100644
--- a/openapi/tcr_openapi.yaml
+++ b/openapi/tcr_openapi.yaml
@@ -54,41 +54,130 @@ components:
       required:
         - code
         - message
-    VerificationRequest:
+    KnownServiceEndpointType:
+      type: string
+      enum:
+        - gx-trust-list-issuer
+        - gx-trust-list-schemas
+        - gx-trust-list-policies
+        - gx-trust-list-apps
+        - gx-trust-list-verifier
+        - gx-trust-list-authorities
+    ResolveRequest:
       type: object
       properties:
         issuer:
           description: Issuer details from the VC/VP (e.g., DID/URI)
           type: string
-        trustSchemePointer:
-          description: Trust Framework Pointer (e.g., example.federation1.de)
-          type: string
+        trustSchemePointers:
+          description: Trust Framework Pointers (e.g., example.federation1.de)
+          type: array
+          items:
+            type: string
         endpointTypes:
           description: Endpoint types to be consideredduring the resolving
           type: array
           items:
-            type: string            
-        trustListServiceType:
+            type: string
+        trustListServiceTypes:
           description: ServiceType of the trust list (e.g., issuance service, verifier service)
-          type: string  
+          type: array
+          items:
+            type: string            
       required:
-        - issuer
-        - trustSchemePointer
-    VerificationResult:
+        - trustSchemePointers
+    ResolveTrustList:
+      type: object
+      properties:
+        endpoint:
+          description: Resolved Trust List VC endpoint
+          type: string
+        trustList:
+          description: Resolved Trust List
+          type: object
+          additionalProperties:
+            type: object
+      required:
+        - endpoint
+        - trustList
+    ResolveResult:
       type: object
       properties:
-        resolvedDID:
+        did:
           description: Corresponding DID mapped to Trust Framework Pointer
-          type: string  
-        resolvedDoc: 
-          description: DID Document of the DID (is is a doc URL or the whole doc content?!)
           type: string
-        trustListEndpoints:  
-          description: Trust List VC endpoint
+        pointers:
+          description: Trust Framework Pointer (e.g., example.federation1.de)
           type: array
           items:
-            type: string            
+            type: string
+        document:
+          description: DID Document of the DID
+          type: object
+          additionalProperties:
+            type: object
+        endpoints:
+          description: Resolved Trust List VC endpoints
+          type: array
+          items:
+            $ref: '#/components/schemas/ResolveTrustList'
+      required:
+        - did
+        - pointers
+        - document
+        - endpoints
+    ResolveResponse:
+      type: array
+      items:
+        $ref: '#/components/schemas/ResolveResult'
 
+    ValidateRequest:
+      type: object
+      properties:
+        issuer:
+          description: Issuer details from the VC/VP (e.g., DID/URI)
+          type: string
+        did:
+          description: DID resolved from Trust Pointer
+          type: string
+# not clear, why do we need it..          
+#        document:
+#          description: DID Document of the DID
+#          type: object
+#          additionalProperties:
+#            type: object
+        endpoints:
+          description: Resolved Trust List VC endpoints
+          type: array
+          items:
+            type: string
+      required:
+        - issuer
+        - did
+#        - document
+        - endpoints
+    ValidateResponse:
+      type: object
+      properties:
+        didVerified: 
+          description: DID verified via well-known did-configuration
+          type: boolean
+        vcVerified:
+          description: VC signature verified
+          type: boolean
+        issuerVerified:
+          description: Validation result of Issuer details (present/not present)
+          type: boolean
+        endpoints:
+          description: If Issuer details are found, display meta data information, public keys, schema from the trust list
+          type: array
+          items:
+            $ref: '#/components/schemas/ResolveTrustList'
+      required:
+        - didVerified
+        - vcVerified
+        - issuerVerified
+          
 tags:
   - name: TrustedContentResolver
     description: Trusted Content Resolver API
@@ -100,25 +189,51 @@ paths:
         - TrustedContentResolver
       summary: Verification result based on issuer & trust scheme pointers
       description: Returns a Verification result from TCR
-      operationId: resolveIssuer
+      operationId: resolveTrustList
       requestBody:
         description: Verification params
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/VerificationRequest'
+              $ref: '#/components/schemas/ResolveRequest'
+        required: true
+      responses:
+        '200':
+          description: Resolved
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ResolveResponse'
+        '400':
+          $ref: '#/components/responses/ClientError'
+        '409':
+          $ref: '#/components/responses/Conflict'
+        '500':
+          $ref: '#/components/responses/ServerError'
+  /validate:
+    post:
+      tags:
+        - TrustedContentResolver
+      summary: Validation result based on /resolve output
+      description: Returns a Validation result from TCR
+      operationId: validateTrustList
+      requestBody:
+        description: Validation params
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/ValidateRequest'
         required: true
       responses:
         '200':
-          description: Verified
+          description: Validated
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/VerificationResult'
+                $ref: '#/components/schemas/ValidateResponse'
         '400':
           $ref: '#/components/responses/ClientError'
         '409':
           $ref: '#/components/responses/Conflict'
         '500':
           $ref: '#/components/responses/ServerError'
-#  /validate:
diff --git a/pom.xml b/pom.xml
index 89b850f7b1dd708781ef2b8a7eb7ef7db7d3258e..edccd4879dd9443aea5f19a2bf9f96827ab3924a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>3.1.2</version>
+        <version>3.1.5</version>
         <relativePath/>
     </parent>
     
@@ -28,9 +28,9 @@
             <url>https://repo.danubetech.com/repository/maven-public/</url>
         </repository>
         <repository>
-			<id>sovrin</id>
-			<url>https://repo.sovrin.org/repository/maven-public</url>
-		</repository>
+            <id>jitpack.io</id>
+            <url>https://jitpack.io</url>
+        </repository>
     </repositories>
 
     <modules>
@@ -50,17 +50,16 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <!-- dependencies -->
-        <spring.version>6.0.11</spring.version>
-        <spring-boot.version>3.1.2</spring-boot.version>
-        <spring-cloud-contract-wiremock.version>4.0.3</spring-cloud-contract-wiremock.version>
-        <mockwebserver.version>4.11.0</mockwebserver.version>
+        <spring.version>6.0.13</spring.version>
+        <spring-boot.version>3.1.5</spring-boot.version>
         <springdoc.version>2.2.0</springdoc.version>
-        <lombok.version>1.18.28</lombok.version>
+        <lombok.version>1.18.30</lombok.version>
         <micrometer.version>1.11.3</micrometer.version>
-        <vc.version>1.2.0</vc.version>
-        <key-format.version>1.8.0</key-format.version>
-        <did.version>1.4.0</did.version>
-        <uni-resolver.version>0.13.0</uni-resolver.version>
+        <vc.version>1.7.0</vc.version>
+        <key-format.version>1.12.0</key-format.version>
+        <did.version>1.11.0</did.version>
+        <ld-signatures.version>1.6.0</ld-signatures.version>
+        <uni-resolver.version>0.16.0</uni-resolver.version>
         <titanium.version>1.3.2</titanium.version>
         <caffeine.version>3.1.8</caffeine.version>        
         <eclipse-collections.version>11.1.0</eclipse-collections.version>
@@ -69,7 +68,15 @@
         <dnsjava.version>3.5.2</dnsjava.version>
         <dnssecjava.version>2.0.0</dnssecjava.version>
         <okhttp.version>4.11.0</okhttp.version>
-        <dss-xades.version>5.12.1</dss-xades.version>
+        <dss.version>5.12.1</dss.version>
+        <java-multihash.version>v1.3.4</java-multihash.version>
+        <snakeyml.version>2.1</snakeyml.version>
+        <xmlsec.version>2.3.4</xmlsec.version>
+        <okio.version>3.6.0</okio.version>
+        <jaxb.version>2.3.1</jaxb.version>
+        <netty-macos.version>4.1.101.Final</netty-macos.version>
+        <junit-jupiter.version>5.10.0</junit-jupiter.version>
+        <junit-platform.version>1.10.0</junit-platform.version>
         <!-- plugins -->
         <plugin.jib.version>3.2.1</plugin.jib.version>
         <plugin.openapi-generator.version>6.4.0</plugin.openapi-generator.version>
@@ -140,11 +147,11 @@
                 <artifactId>micrometer-registry-prometheus</artifactId>
                 <version>${micrometer.version}</version>
             </dependency>
-            <!--dependency>
+            <dependency>
                 <groupId>com.github.ben-manes.caffeine</groupId>
                 <artifactId>caffeine</artifactId>
                 <version>${caffeine.version}</version>
-            </dependency--> 
+            </dependency> 
             <dependency>
                 <groupId>com.apicatalog</groupId>
                 <artifactId>titanium-json-ld</artifactId>
@@ -167,23 +174,14 @@
             </dependency>
             <dependency>
 	            <groupId>decentralized-identity</groupId>
-	            <artifactId>uni-resolver-local</artifactId>
+	            <artifactId>uni-resolver-client</artifactId>
 	            <version>${uni-resolver.version}</version>
             </dependency>
-            <!--
             <dependency>
-                <groupId>decentralized-identity</groupId>
-                <artifactId>uni-resolver-driver-did-sov</artifactId>
-                <version>0.7-SNAPSHOT</version>
+                <groupId>info.weboftrust</groupId>
+                <artifactId>ld-signatures-java</artifactId>
+                <version>${ld-signatures.version}</version>
             </dependency>
-            -->
-<!-- 
-            <dependency>
-	            <groupId>decentralized-identity</groupId>
-	            <artifactId>uni-resolver-driver</artifactId>
-	            <version>${uni-resolver.version}</version>
-            </dependency>
--->            
             <dependency>
                 <groupId>dnsjava</groupId>
                 <artifactId>dnsjava</artifactId>
@@ -201,16 +199,85 @@
             </dependency>
             <dependency>
                 <groupId>eu.europa.ec.joinup.sd-dss</groupId>
-                <artifactId>dss-xades</artifactId>
-                <version>${dss-xades.version}</version>
-            </dependency>            
+                <artifactId>dss-service</artifactId>
+                <version>${dss.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+                <artifactId>dss-tsl-validation</artifactId>
+                <version>${dss.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+                <artifactId>dss-utils-apache-commons</artifactId>
+                <version>${dss.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+                <artifactId>dss-validation-rest</artifactId>
+                <version>${dss.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+                <artifactId>dss-certificate-validation-rest</artifactId>
+                <version>${dss.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.github.multiformats</groupId>
+                <artifactId>java-multihash</artifactId>
+                <version>${java-multihash.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcpkix-jdk15on</artifactId>
                 <version>${bcpkix.jdk15on.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.yaml</groupId>
+                <artifactId>snakeyaml</artifactId>
+                <version>${snakeyml.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.santuario</groupId>
+                <artifactId>xmlsec</artifactId>
+                <version>${xmlsec.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.squareup.okio</groupId>
+                <artifactId>okio</artifactId>
+                <version>${okio.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.xml.bind</groupId>
+                <artifactId>jaxb-api</artifactId>
+                <version>${jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jaxb</groupId>
+                <artifactId>jaxb-runtime</artifactId>
+                <version>${jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-resolver-dns-native-macos</artifactId>
+                <version>${netty-macos.version}</version>
+                <classifier>osx-aarch_64</classifier>
+                <scope>runtime</scope>
+            </dependency>
                         
             <!-- Test dependencies -->
+            <dependency>
+                <groupId>org.junit.platform</groupId>
+                <artifactId>junit-platform-launcher</artifactId>
+                <version>${junit-platform.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.junit.jupiter</groupId>
+                <artifactId>junit-jupiter</artifactId>
+                <version>${junit-jupiter.version}</version>
+                <scope>test</scope>
+            </dependency>
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-starter-test</artifactId>
@@ -218,9 +285,9 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
-                <groupId>org.bitbucket.b_c</groupId>
-                <artifactId>jose4j</artifactId>
-                <version>${jose4j.version}</version>
+                <groupId>com.squareup.okhttp3</groupId>
+                <artifactId>mockwebserver</artifactId>
+                <version>${okhttp.version}</version>
                 <scope>test</scope>
             </dependency>
         </dependencies>
diff --git a/service/Dockerfile b/service/Dockerfile
index afde11b47d79d30fcff89362a8f4562d5a4688de..ee9c67ace18c5dc25fec93deafa45f4064cc406a 100644
--- a/service/Dockerfile
+++ b/service/Dockerfile
@@ -1,3 +1,3 @@
-FROM openjdk:17
+FROM bellsoft/liberica-openjdk-alpine:21
 COPY /target/trusted-content-resolver-service-*.jar trusted-content-resolver-service.jar
 ENTRYPOINT ["java", "-jar","/trusted-content-resolver-service.jar"]
diff --git a/service/pom.xml b/service/pom.xml
index 83c22a091f62cb182ed7df6aa8968b8a6dd5f7b3..00672464f0dc9daced3d8d9414d997df9754486d 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -17,10 +17,6 @@
     <description>Eclipse XFSC TRAIN Trust Content Resolver Server Application</description>
 
     <dependencies>
-        <dependency>
-            <groupId>ch.qos.logback</groupId>
-            <artifactId>logback-classic</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
@@ -33,10 +29,12 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
-        <!--dependency>
+        <!--
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-webflux</artifactId>
-        </dependency-->
+        </dependency>
+        -->
         <dependency>
             <groupId>org.springdoc</groupId>
             <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
@@ -57,23 +55,27 @@
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-tracing-bridge-otel</artifactId>
-        </dependency>        
+        </dependency>
+        <dependency>
+            <groupId>com.github.ben-manes.caffeine</groupId>
+            <artifactId>caffeine</artifactId>
+        </dependency> 
+        <dependency>
+            <groupId>info.weboftrust</groupId>
+            <artifactId>ld-signatures-java</artifactId>
+        </dependency>
         <dependency>
             <groupId>decentralized-identity</groupId>
-	        <artifactId>uni-resolver-local</artifactId>
+	        <artifactId>uni-resolver-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.danubetech</groupId>
+            <artifactId>verifiable-credentials-java</artifactId>
         </dependency>
-        <!--
-		<dependency>
-			<groupId>decentralized-identity</groupId>
-			<artifactId>uni-resolver-driver-did-sov</artifactId>
-			<version>0.4-SNAPSHOT</version>
-			<scope>compile</scope>
-		</dependency>
-		-->
 		<dependency>
             <groupId>dnsjava</groupId>
             <artifactId>dnsjava</artifactId>
-        </dependency>            
+        </dependency>
         <dependency>
             <groupId>org.jitsi</groupId>
             <artifactId>dnssecjava</artifactId>
@@ -84,26 +86,58 @@
         </dependency>
         <dependency>
             <groupId>eu.europa.ec.joinup.sd-dss</groupId>
-            <artifactId>dss-xades</artifactId>
-        </dependency>            
+            <artifactId>dss-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+            <artifactId>dss-tsl-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+            <artifactId>dss-utils-apache-commons</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+            <artifactId>dss-validation-rest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>eu.europa.ec.joinup.sd-dss</groupId>
+            <artifactId>dss-certificate-validation-rest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.multiformats</groupId>
+            <artifactId>java-multihash</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-runtime</artifactId>
+        </dependency>
         
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
             <scope>test</scope>
         </dependency>
-        <!--
         <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcpkix-jdk15on</artifactId>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.bitbucket.b_c</groupId>
-            <artifactId>jose4j</artifactId>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
+            <exclusions>
+				<exclusion>
+                    <groupId>com.vaadin.external.google</groupId>
+                    <artifactId>android-json</artifactId>
+				</exclusion>
+			</exclusions>
         </dependency>
-        -->
     </dependencies>
 
     <build>
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/config/ResolverConfig.java b/service/src/main/java/eu/xfsc/train/tcr/server/config/ResolverConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..6927bdceb7f3e5b3cffb570341846469da3dffc9
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/config/ResolverConfig.java
@@ -0,0 +1,115 @@
+package eu.xfsc.train.tcr.server.config;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.time.Duration;
+import java.util.List;
+
+import org.jitsi.dnssec.validator.ValidatingResolver;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.xbill.DNS.ExtendedResolver;
+import org.xbill.DNS.SimpleResolver;
+
+import com.apicatalog.jsonld.loader.DocumentLoader;
+
+import org.xbill.DNS.Resolver;
+
+import eu.xfsc.train.tcr.server.exception.DidException;
+import eu.xfsc.train.tcr.server.exception.DnsException;
+import foundation.identity.jsonld.ConfigurableDocumentLoader;
+import lombok.extern.slf4j.Slf4j;
+import uniresolver.UniResolver;
+import uniresolver.client.ClientUniResolver;
+
+@Slf4j
+@Configuration
+public class ResolverConfig {
+
+    private final static String DNSROOT = ". IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=";
+	
+	@Bean
+	public UniResolver uniResolver(@Value("${tcr.did.base-uri}") String baseUri,
+			@Value("${tcr.did.timeout}") int timeout) {
+		log.info("uniResolver.enter; configured base URI: {}, timeout: {}", baseUri, timeout);
+		UniResolver resolver;
+		URI uri;
+		try {
+			uri = new URI(baseUri);
+		} catch (URISyntaxException ex) {
+			log.error("uniResolver.error", ex);
+			throw new DidException(ex);
+		}
+		resolver = ClientUniResolver.create(uri);
+		log.info("uniResolver.exit; returning resolver: {}", resolver);
+		return resolver;
+	}
+
+	@Bean
+	public Resolver resolver(@Value("${tcr.dns.hosts}") List<String> dnsHosts,
+			@Value("${tcr.dns.timeout}") int timeout,
+		    @Value("${tcr.dns.dnssec.rootPath}") String dnssecRootPath, 
+		    @Value("${tcr.dns.dnssec.enabled}") boolean dnssecEnabled) {
+		log.info("resolver.enter; configured DNS hosts: {}, timeout: {}, dnssecRootPath: {}, dnssecEnaabled: {}", dnsHosts, timeout, dnssecRootPath, dnssecEnabled);
+		Resolver resolver;
+		try {
+			if (dnsHosts.isEmpty()) {
+				resolver = new SimpleResolver();
+			} else {
+				SimpleResolver[] resolvers = new SimpleResolver[dnsHosts.size()];
+				int idx = 0;
+				for (String dnsHost : dnsHosts) {
+					SimpleResolver r = new SimpleResolver(dnsHost);
+					if (timeout > 0) {
+						r.setTimeout(Duration.ofMillis(timeout));
+					}
+					resolvers[idx++] = r;
+				}
+				resolver = new ExtendedResolver(resolvers);
+			}
+			if (timeout > 0) {
+				resolver.setTimeout(Duration.ofMillis(timeout));
+			}
+			
+			if (dnssecEnabled) {
+				InputStream rootInputStream;
+				File f = new File(dnssecRootPath);
+				if (f.exists()) {
+			        rootInputStream = new FileInputStream(dnssecRootPath);
+			    } else {
+			        rootInputStream = getClass().getClassLoader().getResourceAsStream(dnssecRootPath);
+			        if (rootInputStream == null) {
+			            log.info("resolve; DNSSEC Root-key not found, using hardcoded backup.");
+			            rootInputStream = new ByteArrayInputStream(DNSROOT.getBytes());
+			        }
+			    }
+
+		        ValidatingResolver validatingResolver = new ValidatingResolver(resolver);
+		        validatingResolver.loadTrustAnchors(rootInputStream);
+		        resolver = validatingResolver;
+			}
+		} catch (IOException ex) {
+			log.error("resolver.error", ex);
+			throw new DnsException(ex);
+		}
+		log.info("resolver.exit; returning resolver: {}", resolver);
+		return resolver;
+	}
+
+	@Bean
+	public DocumentLoader documentLoader() {
+		ConfigurableDocumentLoader loader = new ConfigurableDocumentLoader();
+		// TODO: get settings from app props
+		loader.setEnableHttp(true);
+		loader.setEnableHttps(true);
+		return loader;
+	}
+}
+
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/exception/ClientException.java b/service/src/main/java/eu/xfsc/train/tcr/server/exception/ClientException.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fe0d2e26dde410322bb4a82f6cf8ab9b50e21dd
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/exception/ClientException.java
@@ -0,0 +1,17 @@
+package eu.xfsc.train.tcr.server.exception;
+
+public class ClientException extends TrainException {
+
+	public ClientException(String message) {
+		super(message);
+	}
+
+	public ClientException(Throwable cause) {
+		super(cause);
+	}
+
+	public ClientException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+}
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/exception/DNSException.java b/service/src/main/java/eu/xfsc/train/tcr/server/exception/DNSException.java
deleted file mode 100644
index 67670431bf5abfb9072c6a4cd192020898191030..0000000000000000000000000000000000000000
--- a/service/src/main/java/eu/xfsc/train/tcr/server/exception/DNSException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package eu.xfsc.train.tcr.server.exception;
-
-public class DNSException extends Exception {
-    
-    public DNSException(String s) {
-        super(s);
-    }
-}
-
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/exception/DidException.java b/service/src/main/java/eu/xfsc/train/tcr/server/exception/DidException.java
new file mode 100644
index 0000000000000000000000000000000000000000..d270184ec575b08abec2ed47970698338304f2a0
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/exception/DidException.java
@@ -0,0 +1,17 @@
+package eu.xfsc.train.tcr.server.exception;
+
+public class DidException extends TrainException {
+
+	public DidException(String message) {
+		super(message);
+	}
+
+	public DidException(Throwable cause) {
+		super(cause);
+	}
+
+	public DidException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+}
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/exception/DnsException.java b/service/src/main/java/eu/xfsc/train/tcr/server/exception/DnsException.java
new file mode 100644
index 0000000000000000000000000000000000000000..954107f8060f240375239ef6b42a4973c41cd817
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/exception/DnsException.java
@@ -0,0 +1,17 @@
+package eu.xfsc.train.tcr.server.exception;
+
+public class DnsException extends TrainException {
+    
+	public DnsException(String message) {
+		super(message);
+	}
+
+	public DnsException(Throwable cause) {
+		super(cause);
+	}
+
+	public DnsException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
+
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/exception/RestExceptionHandler.java b/service/src/main/java/eu/xfsc/train/tcr/server/exception/RestExceptionHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..d263ffc1bc34f2c7f49c4a9899c5795ed19a4be8
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/exception/RestExceptionHandler.java
@@ -0,0 +1,98 @@
+package eu.xfsc.train.tcr.server.exception;
+
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.GATEWAY_TIMEOUT;
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
+import static org.springframework.http.HttpStatus.NOT_IMPLEMENTED;
+import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+import eu.xfsc.train.tcr.api.generated.model.Error;
+import jakarta.validation.ConstraintViolationException;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * RestExceptionHandler translates RestExceptions to error responses according to the status that is set in
+ * the application exception. Response content format: {"code" : "ExceptionType", "message" : "some exception message"}
+ * Implementation of the {@link ResponseEntityExceptionHandler} exception.
+ */
+@Slf4j
+@ControllerAdvice
+public class RestExceptionHandler extends ResponseEntityExceptionHandler {
+  /**
+   * Method handles the Client Exception.
+   *
+   * @param exception Thrown Client Exception.
+   * @return The custom Federated Catalogue application error with status code 400.
+   */
+  @ExceptionHandler({ClientException.class})
+  protected ResponseEntity<Error> handleBadRequestException(ClientException exception) {
+    log.info("handleBadRequestException; Bad Request error: {}", exception.getMessage());
+    return new ResponseEntity<>(new Error("client_error", exception.getMessage()), BAD_REQUEST);
+  }
+
+  /**
+   * Method handles the Server Exception.
+   *
+   * @param exception Thrown Server Exception.
+   * @return The custom Federated Catalogue application error with status code 500.
+   */
+  @ExceptionHandler({TrainException.class})
+  protected ResponseEntity<Error> handleServerException(TrainException exception) {
+    log.info("handleServerException; Server error: {}", exception.getMessage());
+    return new ResponseEntity<>(new Error("server_error", exception.getMessage()), INTERNAL_SERVER_ERROR);
+  }
+
+  /**
+   * Method handles the Verification Exception.
+   *
+   * @param exception Thrown Server Exception.
+   * @return The custom Federated Catalogue application error with status code 422.
+   */
+  @ExceptionHandler({DidException.class})
+  protected ResponseEntity<Error> handleVerificationException(DidException exception) {
+    log.info("handleVerificationException; Verification error: {}", exception.getMessage());
+    return new ResponseEntity<>(new Error("verification_error", exception.getMessage()), UNPROCESSABLE_ENTITY);
+  }
+
+  /**
+   * Method handles the UnsupportedOperation Exception.
+   *
+   * @param exception Thrown Server Exception.
+   * @return The custom Federated Catalogue application error with status code 501.
+   */
+  @ExceptionHandler({UnsupportedOperationException.class})
+  protected ResponseEntity<Error> handleUnsupportedOperationException(UnsupportedOperationException exception) {
+    log.info("handleUnsupportedOperationException; Unsupported Operation error: {}", exception.getMessage());
+    return new ResponseEntity<>(new Error("processing_error", exception.getMessage()), NOT_IMPLEMENTED);
+  }
+  
+  /**
+   * Method handles the Timeout Exception.
+   *
+   * @param exception Thrown Server Exception.
+   * @return The custom Federated Catalogue application error with status code 504.
+   */
+  @ExceptionHandler({DnsException.class})
+  protected ResponseEntity<Error> handleTimeoutException(DnsException exception) {
+    log.info("handleTimeoutException; Tiomeout error: {}", exception.getMessage());
+    return new ResponseEntity<>(new Error("timeout_error", exception.getMessage()), GATEWAY_TIMEOUT);
+  }
+
+
+  /**
+   * Method handles the constraintViolationException Exception.
+   *
+   * @param exception Thrown Server Exception.
+   * @return The custom Federated Catalogue application error with status code 400.
+   */
+  @ExceptionHandler({ConstraintViolationException.class})
+  protected ResponseEntity<Error> constraintViolationException(ConstraintViolationException exception) {
+    log.info("constraintViolationException; Constraint Violation error: {}", exception.getMessage());
+    return new ResponseEntity<>(new Error("constraint_violation_error", exception.getMessage()), BAD_REQUEST);
+  }
+}
\ No newline at end of file
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/exception/TrainException.java b/service/src/main/java/eu/xfsc/train/tcr/server/exception/TrainException.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8ad53264cd855f63bd099d3794e67321c44f863
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/exception/TrainException.java
@@ -0,0 +1,37 @@
+package eu.xfsc.train.tcr.server.exception;
+
+/**
+ * ServiceException is the main exception that can be thrown during the operations of Federated Catalogue
+ * server application.
+ * Implementation of the {@link RuntimeException} exception.
+ */
+public class TrainException extends RuntimeException {
+  /**
+   * Constructs a new Train Exception with the specified detail message.
+   *
+   * @param message Detailed message about the thrown exception.
+   */
+  public TrainException(String message) {
+    super(message);
+  }
+
+  /**
+   * Constructs a new Train exception with the specified cause.
+   *
+   * @param cause Case of the thrown exception. (A null value is permitted, and indicates that the cause is unknown.)
+   */
+  public TrainException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * Constructs a new Train exception with the specified detail message and cause.
+   *
+   * @param message Detailed message about the thrown exception.
+   * @param cause Cause of the thrown exception. (A null value is permitted, and indicates that the cause is unknown.)
+   */
+  public TrainException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DANETrustManager.java b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DANETrustManager.java
index 36433e22de61bccda5e314ef47f0ba6930d8cfa9..cb18697f801fa38544b66eea75a90fba7503c53e 100644
--- a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DANETrustManager.java
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DANETrustManager.java
@@ -3,7 +3,7 @@ package eu.xfsc.train.tcr.server.legacy;
 import org.xbill.DNS.TLSARecord;
 import org.xbill.DNS.utils.base16;
 
-import eu.xfsc.train.tcr.server.exception.DNSException;
+import eu.xfsc.train.tcr.server.exception.DnsException;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.net.ssl.X509TrustManager;
@@ -43,7 +43,7 @@ public class DANETrustManager implements X509TrustManager {
         
         try {
             this.initDANE();
-        } catch (IOException | DNSException e) {
+        } catch (IOException | DnsException e) {
             throw new CertificateException(e);
         }
         
@@ -131,7 +131,7 @@ public class DANETrustManager implements X509TrustManager {
         this.host = host;
     }
     
-    private void initDANE() throws IOException, DNSException {
+    private void initDANE() throws IOException, DnsException {
         String host = DANETrustManager.DANE_PREFIX + (this.host.endsWith(".") ? this.host : this.host + ".");
         log.debug("initDANE; Looking up TLSA record(s) for {}", host);
         
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DNSHelper.java b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DNSHelper.java
index 5a7b18c9524fbd17d8c9fc1f862ce7d066fba335..7402645977fb7dca6d42cd5f48edeb4eb641f53c 100644
--- a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DNSHelper.java
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/DNSHelper.java
@@ -8,7 +8,7 @@ import org.jitsi.dnssec.validator.ValidatingResolver;
 import org.xbill.DNS.*;
 import org.xbill.DNS.Record;
 
-import eu.xfsc.train.tcr.server.exception.DNSException;
+import eu.xfsc.train.tcr.server.exception.DnsException;
 import lombok.extern.slf4j.Slf4j;
 
 import java.io.*;
@@ -97,13 +97,13 @@ public class DNSHelper {
     }
     
     
-    public Stream<Record> parseMessage(Message response) throws IOException, DNSException {
+    public Stream<Record> parseMessage(Message response) throws IOException, DnsException {
         
         List<RRset> rrSets = response.getSectionRRsets(Section.ANSWER);
         return rrSets.stream().flatMap(s -> s.rrs().stream());
     }
     
-    public List<String> queryTXT(String host) throws IOException, DNSException {
+    public List<String> queryTXT(String host) throws IOException, DnsException {
 
     	Message response = query(host, Type.TXT);
         Stream<Record> records = parseMessage(response);
@@ -112,7 +112,7 @@ public class DNSHelper {
             .toList();
     }
     
-    public List<String> queryPTR(String host) throws IOException, DNSException {
+    public List<String> queryPTR(String host) throws IOException, DnsException {
 
     	Message response = query(host, Type.PTR);
         Stream<Record> records = parseMessage(response);
@@ -121,7 +121,7 @@ public class DNSHelper {
             .toList();
     }
     
-    public List<String> queryURI(String host) throws IOException, DNSException {
+    public List<String> queryURI(String host) throws IOException, DnsException {
         
     	Message response = query(host, Type.URI);
         Stream<Record> records = parseMessage(response);
@@ -130,7 +130,7 @@ public class DNSHelper {
         	.toList();
     }
     
-    public List<SMIMEAcert> querySMIMEA(String host) throws IOException, DNSException {
+    public List<SMIMEAcert> querySMIMEA(String host) throws IOException, DnsException {
         // https://tools.ietf.org/html/rfc6698#section-2
         
         Message response = query(host, Type.SMIMEA);
@@ -141,7 +141,7 @@ public class DNSHelper {
     }
     
     
-    public Message query(String host, int type) throws IOException, DNSException {
+    public Message query(String host, int type) throws IOException, DnsException {
         if (!host.endsWith(".")) {
             host = host + ".";
         }
@@ -164,13 +164,13 @@ public class DNSHelper {
                         log.debug("query; Reason: {}", ((TXTRecord) set.first()).getStrings().get(0));
                     }
                 }
-                throw new DNSException("RCode: " + rcode + " (" + Rcode.string(rcode) + ")");
+                throw new DnsException("RCode: " + rcode + " (" + Rcode.string(rcode) + ")");
             }
         }
         return response;
     }
     
-    public <R extends Record> List<R> queryAndParse(String host, Class recordTypeClass, int recordTypeID) throws IOException, DNSException {
+    public <R extends Record> List<R> queryAndParse(String host, Class recordTypeClass, int recordTypeID) throws IOException, DnsException {
         
         Message response = query(host, recordTypeID);
         List<RRset> rrSets = response.getSectionRRsets(Section.ANSWER);
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/SMIMEAHelper.java b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/SMIMEAHelper.java
index 0997f9cb730547c5385bad89ff304023c88cfbb6..913fe332fb54c4c65b1be1bcc7bef78e0238c525 100644
--- a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/SMIMEAHelper.java
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/SMIMEAHelper.java
@@ -6,7 +6,7 @@ import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.util.List;
 
-import eu.xfsc.train.tcr.server.exception.DNSException;
+import eu.xfsc.train.tcr.server.exception.DnsException;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -37,7 +37,7 @@ public class SMIMEAHelper {
         try {
             smimeas = dns.querySMIMEA(hostname);
             log.debug("verifyXMLdocument; Found {} SMIMEA record(s) for this Document", smimeas.size());
-        } catch (IOException | DNSException e) {
+        } catch (IOException | DnsException e) {
             log.info("verifyXMLdocument.exit; Loading of SMIMEA failed.", e);
             return false;
         }
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/TrustSchemeFactory.java b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/TrustSchemeFactory.java
index 425deeadd660d72eaeff9e5d1396597517c89500..8027c12c1c28eaae0a0c71a05130f2279e5636d9 100644
--- a/service/src/main/java/eu/xfsc/train/tcr/server/legacy/TrustSchemeFactory.java
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/legacy/TrustSchemeFactory.java
@@ -12,10 +12,9 @@ import java.util.List;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import eu.xfsc.train.tcr.server.exception.DNSException;
+import eu.xfsc.train.tcr.server.exception.DnsException;
 
 @Slf4j
-@Component
 public class TrustSchemeFactory {
 	
 	@Value("${tcr.dns.verification.enabled}")
@@ -27,7 +26,7 @@ public class TrustSchemeFactory {
     private SMIMEAHelper smimea = new SMIMEAHelper(dns);
     
     
-    public Collection<TrustScheme> createTrustSchemes(TrustSchemeClaim claim) throws IOException, DNSException {
+    public Collection<TrustScheme> createTrustSchemes(TrustSchemeClaim claim) throws IOException, DnsException {
 
     	Collection<TrustScheme> schemes = new ArrayList<>();
         List<String> schemeHostNames = discoverTrustSchemes(claim);
@@ -73,7 +72,7 @@ public class TrustSchemeFactory {
         List<String> schemes;
         try {
             schemes = dns.queryPTR(hostname);
-        } catch (IOException | DNSException e) {
+        } catch (IOException | DnsException e) {
             log.warn("discoverTrustScheme.error", e);
             schemes = Collections.emptyList();
         }
@@ -95,7 +94,7 @@ public class TrustSchemeFactory {
         List<String> lists;
         try {
             lists = dns.queryURI(schemeHostName);
-        } catch (IOException | DNSException e) {
+        } catch (IOException | DnsException e) {
             log.warn("discoverTrustLists.error", e);
             lists = Collections.emptyList();
         }
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/service/DIDResolver.java b/service/src/main/java/eu/xfsc/train/tcr/server/service/DIDResolver.java
index 3d7f862a8446436e0b99fae285699f77c02dac4b..0a713ff0af631d6679000f6bb9b2ac4e495d15d8 100644
--- a/service/src/main/java/eu/xfsc/train/tcr/server/service/DIDResolver.java
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/service/DIDResolver.java
@@ -1,34 +1,417 @@
 package eu.xfsc.train.tcr.server.service;
 
 
-import java.util.HashMap;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 
-//import uniresolver.driver.did.sov.DidSovDriver;
-import uniresolver.local.LocalUniResolver;
-import uniresolver.result.ResolveResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
+import com.apicatalog.jsonld.JsonLdError;
+import com.apicatalog.jsonld.document.JsonDocument;
+import com.apicatalog.jsonld.loader.DocumentLoader;
+import com.apicatalog.jsonld.loader.DocumentLoaderOptions;
+import com.danubetech.keyformats.crypto.PublicKeyVerifier;
+import com.danubetech.keyformats.crypto.PublicKeyVerifierFactory;
+import com.danubetech.keyformats.jose.JWK;
+import com.danubetech.keyformats.jose.JWSAlgorithm;
+import com.danubetech.keyformats.jose.KeyTypeName;
+import com.danubetech.verifiablecredentials.VerifiableCredential;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTParser;
 
+import eu.xfsc.train.tcr.server.exception.DidException;
+import foundation.identity.did.DIDDocument;
+import foundation.identity.did.Service;
+import foundation.identity.did.VerificationMethod;
+import foundation.identity.jsonld.JsonLDObject;
+import foundation.identity.jsonld.JsonLDUtils;
+import info.weboftrust.ldsignatures.LdProof;
+import info.weboftrust.ldsignatures.verifier.LdVerifier;
+import info.weboftrust.ldsignatures.verifier.LdVerifierRegistry;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import uniresolver.ResolutionException;
+import uniresolver.UniResolver;
+import uniresolver.result.ResolveRepresentationResult;
+
+@Slf4j
+@Component
 public class DIDResolver {
 	
+	private static final Map<String, Object> RESOLVE_OPTIONS = Map.of("accept", "application/did+ld+json");
+	
+	@Autowired
+	private UniResolver resolver;
+	@Autowired
+	private DocumentLoader docLoader;
 	
-	private LocalUniResolver resolver;
 	
-	public void init() {
-		resolver = new LocalUniResolver();
-		//resolver.getDrivers().add(new DidSovDriver());
-		//resolver.getDriver(DidSovDriver.class).setLibIndyPath("./sovrin/lib/libindy.so");
-		//resolver.getDriver(DidSovDriver.class).setPoolConfigs("_;./sovrin/mainnet.txn");
-		//resolver.getDriver(DidSovDriver.class).setPoolVersions("_;2");
+	private DIDDocument resolveDidDocument(String did) {
+		log.debug("resolveDidDocument.enter; got did to resolve: {}", did);
+		try {
+			ResolveRepresentationResult didResult = resolver.resolveRepresentation(did, RESOLVE_OPTIONS);
+			log.debug("resolveDid; resolved to: {}", didResult.toJson());
+			if (didResult.isErrorResult()) {
+				throw new DidException(didResult.getErrorMessage());
+			}
 
-		Map<String, Object> resolveOptions = new HashMap<>();
-		resolveOptions.put("accept", "application/did+ld+json");
+			String docStream = didResult.getDidDocumentStreamAsString();
+			log.debug("resolveDidDocument; doc stream is: {}", docStream);
+			DIDDocument diDoc = DIDDocument.fromJson(docStream);
+			log.debug("resolveDidDocument.exit; returning doc: {}", diDoc);
+			return diDoc; 
+		} catch (ResolutionException ex) {
+            log.warn("resolveDidDocument.error;", ex);
+			throw new DidException(ex);
+		}
+	}
+	
+	private Stream<String> resolveEndpoint(Object ep) {
+		if (ep instanceof String) {
+			return Stream.of(ep.toString());
+		}
+		if (ep instanceof List) {
+			Stream<Stream<String>> sss = ((List) ep).stream().map(e -> resolveEndpoint(e)); 
+			return sss.reduce(Stream.of(), (a, b) -> Stream.concat(a, b));
+		}
+		// else ep is a Map
+		Map<String, Object> eps = (Map<String, Object>) ep;
+		ep = eps.entrySet().iterator().next().getValue();
+		return resolveEndpoint(ep);
+	}
+	
+	public DIDResolveResult resolveDid(String did, List<String> types) {
+		log.debug("resolveDid.enter; got did: {}, types; {}", did, types);
+		Stream<Service> services; 
+		DIDDocument diDoc = resolveDidDocument(did);
+		if (types == null || types.isEmpty()) {
+		    services = diDoc.getServices().stream();
+		} else {
+		    services = diDoc.getServices().stream().filter(s -> {
+		    	if (s.getTypes() != null && !s.getTypes().isEmpty()) {
+		    		return types.stream().anyMatch(t -> s.getTypes().contains(t));
+		    	}
+		    	return types.contains(s.getType());
+		    });
+		}
+		List<String> endpoints = services
+				.flatMap(s -> resolveEndpoint(s.getServiceEndpoint())).toList();
+		log.debug("resolveDid; got endpoints: {}", endpoints);
+		String origin = null;
+		if (!endpoints.isEmpty()) {
+			try {
+				URI uri = new URI(endpoints.get(0));
+				origin = uri.getScheme() + "://" + uri.getHost();
+			} catch (URISyntaxException ex) {
+				log.warn("resolveDid; error constructing origin: {}", ex.getMessage());
+			}
+		}
+		return new DIDResolveResult(diDoc.getJsonObject(), endpoints, origin);
+	}
+	
+	public boolean resolveDidConfig(String origin) {
+		log.debug("resolveDidConfig.enter; got origin: {}", origin);
+		String configUri = origin + "/.well-known/did-configuration";
+		String configUrl = configUri + ".json";
+		JsonDocument doc;
+		try {
+			doc = (JsonDocument) docLoader.loadDocument(JsonLDUtils.stringToUri(configUrl), new DocumentLoaderOptions());
+			log.debug("resolveDidConfig; got document: {}", doc);
+		} catch (JsonLdError ex) {
+			log.error("resolveDidConfig.error", ex);
+			throw new DidException(ex);
+		}
+		
+		if (doc.getJsonContent().isEmpty()) {
+			throw new DidException("empty did-configuration at " + configUrl);
+		}
+		JsonObject json = doc.getJsonContent().get().asJsonObject();
+		String context = json.getString("@context");
+		if (context == null) {
+			throw new DidException("did-configuration missing @context");
+		}
+		//if (!context.startsWith(configUri)) {
+		//	throw new DidException("wrong @context: " + context);
+		//}
+		JsonArray dids = json.getJsonArray("linked_dids");
+		if (dids == null) {
+			throw new DidException("did-configuration missing linked-dids");
+		}
+		if (json.keySet().size() > 2) {
+			throw new DidException("did-configuration contains unexpected members: " + json.keySet());
+		}
+		
+		int passed = 0;
+		String did = null;
+		String alg = null;
+		JsonObject dataProof = null;
+		for (JsonValue linkedDid: dids) {
+			if (linkedDid.getValueType() == ValueType.OBJECT) {
+				String local = resolveLinkedData(linkedDid.asJsonObject(), origin);
+				if (local != null) {
+				    if (did == null) {
+				    	did = local;
+				    	dataProof = linkedDid.asJsonObject();
+				    } else {
+				    	log.debug("resolveDidConfig; additional did resolved: {}; initial: {}", local, did);
+				    }
+					passed++;
+				}
+			} else if (linkedDid.getValueType() == ValueType.STRING) {
+				String local = resolveLinkedJWT(linkedDid.toString(), origin);
+				if (local != null) {
+				    if (alg == null) {
+				    	alg = local;
+				    } else {
+				    	log.debug("resolveDidConfig; additional alg resolved: {}; initial: {}", local, alg);
+				    }
+					passed++;
+				}
+			} else {
+				log.debug("resolveDidConfig; unexpected linked-did type: {}; {}", linkedDid.getValueType(), linkedDid);
+			}
+		}
+		log.debug("resolveDidConfig.exit; resolved: {} DIDs, out of: {}", passed, dids.size());
+		
+		boolean resolved = false;
+		if (did != null) {
+			if (alg == null) {
+				alg = getAlgFromProof(dataProof);
+			}
+			JsonLDObject payload = JsonLDObject.fromJson(dataProof.toString());
+			resolved = verifyVCSignature(payload, did, alg);
+		}
+		log.debug("resolveDidConfig.exit; returning: {}; alg: {}, did: {}", resolved, alg, did);
+		return resolved;
+	}
+	
+	private String resolveLinkedData(JsonObject linkedData, String origin) {
+		if (linkedData.containsKey("id")) {
+			log.debug("resolveLinkedData; unexpected id member");
+			return null;
+		}
+		if (!linkedData.containsKey("issuanceDate")) {
+			log.debug("resolveLinkedData; absent issuanceDate member");
+			return null;
+		}
+		if (!linkedData.containsKey("expirationDate")) {
+			log.debug("resolveLinkedData; absent expirationDate member");
+			return null;
+		}
+		JsonObject credSubj = linkedData.getJsonObject("credentialSubject");
+		if (credSubj == null) {
+			log.debug("resolveLinkedData; absent credentialSubject member");
+			return null;
+		}
+		String did = credSubj.getString("id");
+		if (did == null) {
+			log.debug("resolveLinkedData; absent credentialSubject.id member");
+			return null;
+		}
+		if (!did.startsWith("did:")) {
+			log.debug("resolveLinkedData; unexpected credentialSubject.id value: {}", did);
+			return null;
+		}
+		String subOrigin = credSubj.getString("origin");
+		if (subOrigin == null) {
+			log.debug("resolveLinkedData; absent credentialSubject.origin member");
+			return null;
+		}
+		//if (!subOrigin.equals(origin)) {
+		//	log.debug("resolveLinkedData; unexpected credentialSubject.origin value: {}", subOrigin);
+		//	return null;
+		//}
+		return did;
+	}
+	
+	private String resolveLinkedJWT(String linkedJWT, String origin) {
+		JWT jwt;
+        try {
+            jwt = JWTParser.parse(linkedJWT);
+		} catch (ParseException ex) {
+			log.debug("resolveLinkedJWT; error parsing token: {}", ex.getMessage());
+            return null;
+        }
+        
+        if (!jwt.getHeader().getIncludedParams().contains("alg")) {
+			log.debug("resolveLinkedJWT; absent 'alg' member in header");
+            return null;
+        }
+        if (!jwt.getHeader().getIncludedParams().contains("kid")) {
+			log.debug("resolveLinkedJWT; absent 'kid' member in header");
+            return null;
+        }
+        if (jwt.getHeader().getIncludedParams().size() > 2) {
+			log.debug("resolveLinkedJWT; unexpected header members: {}", jwt.getHeader().getIncludedParams());
+            return null;
+        }
+        
+        try {
+        	Map<String, Object> vc = jwt.getJWTClaimsSet().getJSONObjectClaim("vc");
+            Map<String, Object> credSubj = (Map<String, Object>) vc.get("credentialSubject");
+	    	if (credSubj == null) {
+		    	log.debug("resolveLinkedJWT; absent credentialSubject member");
+			    return null;
+		    }
+	    	String did = (String) credSubj.get("id");
+	    	if (did == null) {
+	    		log.debug("resolveLinkedJWT; absent credentialSubject.id member");
+	    		return null;
+	    	}
+	    	if (!did.equals(jwt.getJWTClaimsSet().getIssuer())) {
+	    		log.debug("resolveLinkedJWT; unexpected iss/did values: {}/{}", jwt.getJWTClaimsSet().getIssuer(), did);
+	    		return null;
+	    	}
+	    	if (!did.equals(jwt.getJWTClaimsSet().getSubject())) {
+	    		log.debug("resolveLinkedJWT; unexpected sub/did values: {}/{}", jwt.getJWTClaimsSet().getSubject(), did);
+	    		return null;
+	    	}
+	    	String subOrigin = (String) credSubj.get("origin");
+	    	if (subOrigin == null) {
+	    		log.debug("resolveLinkedJWT; absent credentialSubject.origin member");
+	    		return null;
+	    	}
+			if (!origin.endsWith(subOrigin)) {
+				log.debug("resolveLinkedData; unexpected credentialSubject.origin value: {}", subOrigin);
+				return null;
+			}
+		} catch (ParseException ex) {
+			log.debug("resolveLinkedJWT; error parsing VC: {}", ex.getMessage());
+            return null;
+		}
+		return jwt.getHeader().getAlgorithm().getName();
+	}
+
+	private boolean verifyVCSignature(JsonLDObject payload, String did, String alg) {
+		DIDDocument diDoc = resolveDidDocument(did);
+		List<VerificationMethod> vrMethods = diDoc.getAssertionMethodVerificationMethodsDereferenced();
+		payload.setDocumentLoader(docLoader);
+		LdProof proof = LdProof.fromJsonObject((Map<String, Object>) payload.getJsonObject().get("proof"));
+		log.debug("verifyVCSignature; payload: {}, proof: {}", payload, proof);
+		boolean verified = vrMethods.stream().anyMatch(vm -> {
+			log.debug("verifyVCSignature; veryfying with: {}", vm);
+			try {
+			    JWK jwkPublic = JWK.fromMap(vm.getPublicKeyJwk());
+				LdVerifier<?> verifier = LdVerifierRegistry.getLdVerifierBySignatureSuiteTerm(proof.getType());
+	    		PublicKeyVerifier<?> pkVerifier = PublicKeyVerifierFactory.publicKeyVerifierForJWK(jwkPublic, alg);
+				verifier.setVerifier(pkVerifier);
+				if (verifier.verify(payload, proof)) {
+					return true;
+				}
+				log.debug("verifyVCSignature; payload not verified; suite: {}", proof.getType());
+			} catch (Exception ex) {
+				log.warn("verifyVCSignature; error verifying signature", ex);
+			}
+			return false;
+		}); 
+		return verified;
+	}
+	
+	private String getAlgFromProof(JsonObject vc) {
+		LdProof proof = LdProof.fromJson(vc.getJsonObject("proof").toString());
+		if (proof.getType().contains(KeyTypeName.Ed25519.getValue())) {
+			return JWSAlgorithm.EdDSA;
+		}
+		if (proof.getType().startsWith("BbsBls")) {
+			return JWSAlgorithm.BBSPlus;
+		}
+		if (proof.getType().startsWith("RSA")) {
+			return JWSAlgorithm.RS256;
+		}
+		if (proof.getType().startsWith("EcdsaSecp256k")) {
+			return JWSAlgorithm.ES256K;
+		}
+		if (proof.getType().startsWith("EcdsaKoblitz")) {
+			return JWSAlgorithm.ES256K;
+		}
+		if (proof.getType().startsWith("JcsEcdsaSecp256k")) {
+			return JWSAlgorithm.ES256K;
+		}
+		// else we got JsonWebSignature2020 which maps to:
+		//Map.of(KeyTypeName.RSA, List.of(JWSAlgorithm.PS256, JWSAlgorithm.RS256),
+		//		KeyTypeName.Ed25519, List.of(JWSAlgorithm.EdDSA),
+		//		KeyTypeName.secp256k1, List.of(JWSAlgorithm.ES256K),
+		//		KeyTypeName.P_256, List.of(JWSAlgorithm.ES256),
+		//		KeyTypeName.P_384, List.of(JWSAlgorithm.ES384)),
+		// so, will need more info on how to choose proper algo..
+		if (proof.getJws() != null) {
+			JWT jwt;
+	        try {
+	            jwt = JWTParser.parse(proof.getJws());
+	            return jwt.getHeader().getAlgorithm().getName();
+			} catch (ParseException ex) {
+				log.debug("getAlgFromProof; error parsing JWS: {}", ex.getMessage());
+	        }
+		}
+		return JWSAlgorithm.ES256K;
+	}
+	
+	public VCResolveResult resolveVC(String uri) {
+		log.debug("resolveVC.enter; got uri: {}", uri);
+		JsonObject jsonVC = loadJsonDocument(uri);
+		VCResolveResult result = new VCResolveResult(false, null, null);
+		if (jsonVC != null) {
+			String json = jsonVC.toString();
+			log.debug("resolveVC; got JSON:: {}", json);
+			VerifiableCredential vc = VerifiableCredential.fromJson(json);
+			Map<String, Object> claims = vc.getCredentialSubject().getClaims();
+			result.setTrustListUri((String) claims.get("trustlistURI"));
+			result.setHash((String) claims.get("hash"));
+			JsonObject vcJson = vc.toJsonObject();
+			String alg = getAlgFromProof(vcJson);
+			String did = vc.getLdProof().getVerificationMethod().toString();
+			result.setVerified(verifyVCSignature(JsonLDObject.fromJson(json), did, alg)); 
+		}		
+		log.debug("resolveVC.exit; returning: {}", result);
+		return result;
+	}
 
-		ResolveResult resolveResult;
-		//resolveResult = resolver.resolve("did:sov:WRfXPg8dantKVubE3HX8pw", resolveOptions);
-		//System.out.println(resolveResult.toJson());
-		//resolveResult = resolver.resolveRepresentation("did:sov:WRfXPg8dantKVubE3HX8pw", resolveOptions);
-		//System.out.println(resolveResult.toJson());		
+	private JsonObject loadJsonDocument(String uri) {
+		log.debug("loadJsonDocument.enter; got uri: {}", uri);
+		JsonDocument doc;
+		try {
+			doc = (JsonDocument) docLoader.loadDocument(JsonLDUtils.stringToUri(uri), new DocumentLoaderOptions());
+		} catch (JsonLdError ex) {
+			log.error("loadDidDocument.error", ex);
+			throw new DidException(ex);
+		}
+		// check for empty..
+		return doc.getJsonContent().get().asJsonObject();
+	}	
+    
+	@Getter
+	@AllArgsConstructor
+	@ToString
+	class DIDResolveResult {
+		
+		private Map<String, Object> document;
+		private List<String> endpoints;
+		private String origin;
+		
+	}
+	
+	@Getter
+	@Setter
+	@AllArgsConstructor
+	@ToString
+	class VCResolveResult {
+		
+		private boolean verified;
+		private String trustListUri;
+		private String hash;
+		
 	}
 
 }
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/service/DNSResolver.java b/service/src/main/java/eu/xfsc/train/tcr/server/service/DNSResolver.java
index b571f93545bf919178e2639a95fb685962f2562a..2d2df55f31cbd637a378cc88e22b58048b12149e 100644
--- a/service/src/main/java/eu/xfsc/train/tcr/server/service/DNSResolver.java
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/service/DNSResolver.java
@@ -1,10 +1,7 @@
 package eu.xfsc.train.tcr.server.service;
 
 import java.io.IOException;
-import java.net.UnknownHostException;
-import java.time.Duration;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -12,10 +9,10 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.jitsi.dnssec.validator.ValidatingResolver;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.xbill.DNS.DClass;
-import org.xbill.DNS.ExtendedResolver;
+import org.xbill.DNS.Flags;
 import org.xbill.DNS.Message;
 import org.xbill.DNS.Name;
 import org.xbill.DNS.PTRRecord;
@@ -24,12 +21,11 @@ import org.xbill.DNS.Rcode;
 import org.xbill.DNS.Record;
 import org.xbill.DNS.Resolver;
 import org.xbill.DNS.Section;
-import org.xbill.DNS.SimpleResolver;
 import org.xbill.DNS.TXTRecord;
 import org.xbill.DNS.Type;
 import org.xbill.DNS.URIRecord;
 
-import eu.xfsc.train.tcr.server.exception.DNSException;
+import eu.xfsc.train.tcr.server.exception.DnsException;
 import eu.xfsc.train.tcr.server.legacy.TrustScheme;
 import eu.xfsc.train.tcr.server.legacy.TrustSchemeClaim;
 import eu.xfsc.train.tcr.server.legacy.TrustSchemeFactory;
@@ -39,40 +35,14 @@ import lombok.extern.slf4j.Slf4j;
 @Component
 public class DNSResolver {
 	
-
-	private Resolver resolver;
+	private static final String PREFIX = "_scheme._trust.";
 	
-	public DNSResolver(@Value("${tcr.dns.hosts}") List<String> dnsHosts, @Value("${tcr.dns.timeout}") int timeout) {
-		log.info("<init>.enter; configured DNS hosts: {}, timeout: {}", dnsHosts, timeout);
-		try {
-			if (dnsHosts.isEmpty()) {
-			    resolver = new SimpleResolver();
-			} else {
-	            SimpleResolver[] resolvers = new SimpleResolver[dnsHosts.size()];
-	            int idx = 0;
-	            for (String dnsHost: dnsHosts) {
-	            	SimpleResolver r = new SimpleResolver(dnsHost);
-	            	if (timeout > 0) {
-	            	    r.setTimeout(Duration.ofMillis(timeout));
-	            	}
-	            	resolvers[idx] = r;
-	            	idx++;
-	            }
-	            resolver = new ExtendedResolver(resolvers);
-			}
-			if (timeout > 0 ) {
-	            resolver.setTimeout(Duration.ofMillis(timeout));
-			}
-		} catch (UnknownHostException ex) {
-			log.error("<init}.error", ex);
-			throw new IllegalArgumentException(ex);
-		}
-		log.info("<init>.exit; configured resolver: {}", resolver);
-	}
+	@Autowired
+	private Resolver resolver;
 	
-	public Collection<String> resolveDid(String domain) throws Exception {
+	public Collection<String> resolveDomain(String domain) throws Exception {
 		Set<String> results = new HashSet<>();
-	    Set<String> uris = resolvePtr(domain);
+	    Set<String> uris = resolvePtr(domain); // we can get another PTRs here?
 	    for (String uri: uris) {
 	        Set<String> dids = resolveUri(uri);
 	        results.addAll(dids);
@@ -80,75 +50,87 @@ public class DNSResolver {
 		return results;
 	}
 	
-	private static final String PREFIX = "_scheme._trust.";
+	public Collection<String> resolveDomains(List<String> domains) throws Exception {
+		Set<String> results = new HashSet<>();
+		for (String domain: domains) {
+	        Set<String> uris = resolvePtr(domain); // we can get another PTRs here?
+	        for (String uri: uris) {
+	            Set<String> dids = resolveUri(uri);
+	            results.addAll(dids);
+	        }
+	    }
+		return results;
+	}
 	
-    private String fixHostName(String host) {
-        if (host.startsWith(PREFIX)) {
-            return host;
-        } else {
-            return PREFIX + host;
-        }
-    }
-    
+    /**
+     * resolves DNS PTR record
+     * 
+     * @param ptr - the PTR record to query
+     * @return the resolved Set<String> 
+     */
     private Set<String> resolvePtr(String ptr) {
         log.debug("resolvePtr.enter; got PTR: {}", ptr);
-        String host = fixHostName(ptr);
-        
-        Set<String> set;
-        try {
-            set = query(host, Type.PTR)
-            	.filter(r -> r instanceof PTRRecord)
-                .map(r -> ((PTRRecord) r).getTarget().toString())
-                .collect(Collectors.toSet());
-        } catch (IOException | DNSException e) {
-            log.warn("resolvePtr.error", e);
-            set = Collections.emptySet();
-        }
+        Set<String> set = query(ptr, Type.PTR)
+           	.filter(r -> r instanceof PTRRecord)
+            .map(r -> ((PTRRecord) r).getTarget().toString())
+            .collect(Collectors.toSet());
         log.debug("resolvePtr.exit; returning uris: {}", set);
         return set;
     }
     
+    /**
+     * resolves DNS URI record
+     * 
+     * @param ptr - the URI record to query
+     * @return the resolved Set<String> 
+     */
     private Set<String> resolveUri(String uri) {
         log.debug("resolveUri.enter; got URI: {}", uri);
-        String host = fixHostName(uri);
-        
-        Set<String> set;
-        try {
-            set = query(host, Type.URI)
-            	.filter(r -> r instanceof URIRecord)
-                .map(r -> ((URIRecord) r).getTarget())
-                .collect(Collectors.toSet());
-        } catch (IOException | DNSException e) {
-            log.warn("resolveUri.error", e);
-            set = Collections.emptySet();
-        }
+        Set<String> set = query(uri, Type.URI)
+           	.filter(r -> r instanceof URIRecord)
+            .map(r -> ((URIRecord) r).getTarget())
+            .collect(Collectors.toSet());
         log.debug("resolveUri.exit; returning dids: {}", set);
         return set;
     }
 	
-	
-    private Stream<Record> query(String host, int type) throws IOException, DNSException {
-        if (!host.endsWith(".")) {
-            host = host + ".";
+	/**
+	 * 
+	 * @param uri - the domain to be queried
+	 * @param type - DNS record type
+	 * @return the stream of DNS records
+	 * @throws IOException
+	 * @throws DnsException
+	 */
+    private Stream<Record> query(String uri, int type) {
+        if (!uri.startsWith(PREFIX)) {
+            uri = PREFIX + uri;
+        }
+        if (!uri.endsWith(".")) {
+            uri = uri + ".";
         }
         
-        Record query = Record.newRecord(Name.fromConstantString(host), type, DClass.IN);
-        log.debug("query; DNS query: " + query.toString());
-        Message response = resolver.send(Message.newQuery(query));
-        //if (!response.getHeader().getFlag(Flags.AD)) {
-        //    log.debug("query; NO AD flag present!");
-            //throw new DNSException("No AD flag. (Host not using DNSSec?)");
-        //}
-        
+        Record query = Record.newRecord(Name.fromConstantString(uri), type, DClass.IN);
+        log.debug("query; DNS query: {}", query);
+        Message response;
+		try {
+			response = resolver.send(Message.newQuery(query));
+		} catch (IOException ex) {
+            log.warn("query.error ", ex);
+            return Stream.empty();
+		}
+
         int rcode = response.getRcode();
-        if (rcode != Rcode.SERVFAIL && rcode != Rcode.NOERROR) {
-            for (RRset set: response.getSectionRRsets(Section.ADDITIONAL)) {
-                log.debug("query; Zone: {}", set.getName());
-                if (set.getName().equals(Name.root) && set.getType() == Type.TXT && set.getDClass() == ValidatingResolver.VALIDATION_REASON_QCLASS) {
-                    log.info("query; Reason: {}", ((TXTRecord) set.first()).getStrings().get(0));
+        log.debug("query; got RCode: {} ({}); AD Flag present: {}", rcode, Rcode.string(rcode), response.getHeader().getFlag(Flags.AD));
+        if (rcode != Rcode.NOERROR) {
+        	// the code below is just to log an additional info about error condition
+            for (RRset rrSet: response.getSectionRRsets(Section.ADDITIONAL)) {
+                log.debug("query; Zone: {}", rrSet.getName());
+                if (rrSet.getName().equals(Name.root) && rrSet.getType() == Type.TXT && rrSet.getDClass() == ValidatingResolver.VALIDATION_REASON_QCLASS) {
+                    log.info("query; Reason: {}", ((TXTRecord) rrSet.first()).getStrings().get(0));
                 }
-                throw new DNSException("RCode: " + rcode + " (" + Rcode.string(rcode) + ")");
             }
+            return Stream.empty();
         }
         
         List<RRset> rrSets = response.getSectionRRsets(Section.ANSWER);
@@ -157,7 +139,7 @@ public class DNSResolver {
     
 	
     
-	
+	// TODO: to be removed, most probably
     public Collection<String> verifyIdentity(String issuer, String claim) throws Exception {
         log.debug("verifyIdentity.enter; issuer: {}, claim: {}", issuer, claim);
 
@@ -167,7 +149,7 @@ public class DNSResolver {
         List<String> resp = null;
         Collection<TrustScheme> schemes = tsFactory.createTrustSchemes(tsClaim);
         if (schemes.isEmpty()) {
-            throw new IOException("Did not find TrustScheme / TrustList");
+            throw new DnsException("Did not find TrustScheme / TrustList");
         }
 
         //resp.VerificationResult.FoundCorrespondingTrustScheme = scheme.getSchemeIdentifierCleaned();
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/service/ResolutionService.java b/service/src/main/java/eu/xfsc/train/tcr/server/service/ResolutionService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0a07f7e92f9ecd4e2ccf88ffd695c5f6f0d5ecb
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/service/ResolutionService.java
@@ -0,0 +1,153 @@
+package eu.xfsc.train.tcr.server.service;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import eu.europa.esig.trustedlist.jaxb.tsl.TrustStatusListType;
+import eu.europa.esig.trustedlist.jaxb.tsl.TSPType;
+import eu.xfsc.train.tcr.api.generated.model.ResolveRequest;
+import eu.xfsc.train.tcr.api.generated.model.ResolveResult;
+import eu.xfsc.train.tcr.api.generated.model.ResolveTrustList;
+import eu.xfsc.train.tcr.api.generated.model.ValidateRequest;
+import eu.xfsc.train.tcr.api.generated.model.ValidateResponse;
+import eu.xfsc.train.tcr.server.generated.controller.TrustedContentResolverApiDelegate;
+import eu.xfsc.train.tcr.server.service.DIDResolver.DIDResolveResult;
+import eu.xfsc.train.tcr.server.service.DIDResolver.VCResolveResult;
+import eu.xfsc.train.tcr.server.service.TLResolver.TLResolveResult;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Implementation of the
+ * {@link eu.xfsc.train.tcr.server.generated.controller.TrustedContentResolverApiDelegate}
+ * interface.
+ */
+@Slf4j
+@Service
+public class ResolutionService implements TrustedContentResolverApiDelegate {
+
+	private static final TypeReference<Map<String, Object>> MAP_TYPE_REF = new TypeReference<Map<String, Object>>() {
+	};
+
+	@Autowired
+	private DNSResolver reDns;
+	@Autowired
+	private DIDResolver reDid;
+	@Autowired
+	private TLResolver reTL;
+	@Autowired
+	private ObjectMapper jsonMapper;
+
+	@Override
+	public ResponseEntity<List<ResolveResult>> resolveTrustList(ResolveRequest resolveRequest) {
+		log.debug("resolveTrustList.enter; got request: {}", resolveRequest);
+		Map<String, ResolveResult> result = new HashMap<>();
+		resolveRequest.getTrustSchemePointers().forEach(ptr -> {
+			Collection<String> dids = null;
+			try {
+				dids = reDns.resolveDomain(ptr);
+			} catch (Exception ex) {
+				log.warn("resolveTrustList.error", ex);
+				// add error block to response?
+			}
+			if (dids != null) {
+				dids.forEach(did -> {
+					ResolveResult rr = result.computeIfAbsent(did, s -> new ResolveResult().did(s));
+					if (rr.getPointers().contains(ptr)) {
+						log.debug("resolveTrustList; DID {} for PTR {} has been already resolved", did, ptr);
+					} else {
+						rr.addPointersItem(ptr);
+						DIDResolveResult didRes = reDid.resolveDid(did, resolveRequest.getEndpointTypes());
+						if (didRes.getOrigin() != null) {
+							// here we perform well-known did-configuration check..
+							if (!reDid.resolveDidConfig(didRes.getOrigin())) {
+								// should we remove the not-verified entry?
+								log.info("resolveTrustList; resolved origin not verified: {}", didRes.getOrigin());
+							}
+						}
+						rr.setDocument(didRes.getDocument());
+						didRes.getEndpoints().forEach(endpoint -> {
+							ResolveTrustList rtl = new ResolveTrustList().endpoint(endpoint);
+							VCResolveResult vcRes = reDid.resolveVC(endpoint);
+							//reTL.validateDocument(vcRes.getTrustListUri());
+							TLResolveResult tl = reTL.resolveTLHash(vcRes.getTrustListUri(), vcRes.getHash()); 
+							if (tl != null) {
+								Optional<TSPType> tsPro = findIssuerProvider(tl.getTrustList(), resolveRequest.getIssuer());
+								if (tsPro.isPresent()) {
+									rtl.setTrustList(convertToMap(tsPro.get()));
+								}
+							}
+							rr.addEndpointsItem(rtl);
+						});
+					}
+				});
+			}
+		});
+		log.debug("resolveTrustList.exit; returning result: {}", result);
+		return ResponseEntity.ok(result.values().stream().toList());
+	}
+
+	@Override
+    public ResponseEntity<ValidateResponse> validateTrustList(ValidateRequest validateRequest) {
+		log.debug("validateTrustList.enter; got request: {}", validateRequest);
+		ValidateResponse result = new ValidateResponse();
+		DIDResolveResult didRes = reDid.resolveDid(validateRequest.getDid(), null);
+		if (didRes.getOrigin() == null) {
+			result.setDidVerified(false);
+			log.info("validateTrustList; origin not resolved");
+		} else {
+			// here we perform well-known did-configuration check..
+			result.setDidVerified(reDid.resolveDidConfig(didRes.getOrigin()));
+			if (!result.getDidVerified()) {
+				log.info("validateTrustList; resolved origin not verified: {}", didRes.getOrigin());
+			}
+		}
+		validateRequest.getEndpoints().forEach(endpoint -> {
+			ResolveTrustList rtl = new ResolveTrustList().endpoint(endpoint);
+			VCResolveResult vcRes = reDid.resolveVC(endpoint);
+			result.setVcVerified(vcRes.isVerified());
+			if (vcRes.getTrustListUri() != null) {
+				TrustStatusListType tl = reTL.resolveTL(vcRes.getTrustListUri(), false);
+				if (tl != null) {
+					Optional<TSPType> tsPro = findIssuerProvider(tl, validateRequest.getIssuer());
+					if (tsPro.isPresent()) {
+						rtl.setTrustList(convertToMap(tsPro.get()));
+						result.setIssuerVerified(true);
+						result.addEndpointsItem(rtl);
+					}
+				}
+			}
+			
+		});
+		log.debug("validateTrustList.exit; returning result: {}", result);
+		return ResponseEntity.ok(result);
+	}
+	
+	private Optional<TSPType> findIssuerProvider(TrustStatusListType trustList, String issuer) {
+		return trustList.getTrustServiceProviderList().getTrustServiceProvider().stream()
+				.filter(tsp -> tsp.getTSPInformation().getTSPName().getName().stream()
+						.anyMatch(n -> issuer.equals(n.getValue()))).findFirst();
+	}
+	
+
+	private Map<String, Object> convertToMap(TSPType tsp) {
+		try {
+			byte[] json = jsonMapper.writeValueAsBytes(tsp);
+			return jsonMapper.readValue(json, MAP_TYPE_REF);
+		} catch (IOException ex) {
+			log.warn("convertToMap.error; ", ex);
+			return null;
+		}
+	}
+
+}
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/service/TLResolver.java b/service/src/main/java/eu/xfsc/train/tcr/server/service/TLResolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..06c2e89bc4dee8b196afd4af982b8d3bfc77bfff
--- /dev/null
+++ b/service/src/main/java/eu/xfsc/train/tcr/server/service/TLResolver.java
@@ -0,0 +1,278 @@
+package eu.xfsc.train.tcr.server.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.OptionalInt;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import eu.europa.esig.dss.enumerations.MimeType;
+import eu.europa.esig.dss.enumerations.MimeTypeEnum;
+import eu.europa.esig.dss.model.DSSDocument;
+import eu.europa.esig.dss.model.DSSException;
+import eu.europa.esig.dss.model.FileDocument;
+import eu.europa.esig.dss.service.crl.OnlineCRLSource;
+import eu.europa.esig.dss.service.ocsp.OnlineOCSPSource;
+import eu.europa.esig.dss.service.http.commons.CommonsDataLoader;
+import eu.europa.esig.dss.service.http.commons.FileCacheDataLoader;
+import eu.europa.esig.dss.spi.client.http.DSSFileLoader;
+import eu.europa.esig.dss.spi.client.http.IgnoreDataLoader;
+import eu.europa.esig.dss.spi.tsl.TrustedListsCertificateSource;
+import eu.europa.esig.dss.spi.x509.CertificateSource;
+import eu.europa.esig.dss.spi.x509.KeyStoreCertificateSource;
+import eu.europa.esig.dss.spi.x509.aia.DefaultAIASource;
+import eu.europa.esig.dss.tsl.cache.CacheCleaner;
+import eu.europa.esig.dss.tsl.function.OfficialJournalSchemeInformationURI;
+import eu.europa.esig.dss.tsl.job.TLValidationJob;
+import eu.europa.esig.dss.tsl.source.LOTLSource;
+import eu.europa.esig.dss.tsl.source.TLSource;
+import eu.europa.esig.dss.tsl.sync.AcceptAllStrategy;
+import eu.europa.esig.dss.validation.CommonCertificateVerifier;
+import eu.europa.esig.dss.validation.SignedDocumentValidator;
+import eu.europa.esig.dss.validation.reports.Reports;
+import eu.europa.esig.trustedlist.TrustedListFacade;
+import eu.europa.esig.trustedlist.jaxb.tsl.TrustStatusListType;
+import io.ipfs.multihash.Multihash;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class TLResolver {
+	
+	// Should be externalized
+	private static final String LOTL_URL = "https://ec.europa.eu/tools/lotl/eu-lotl.xml";
+	private static final String OJ_URL = "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=uriserv:OJ.C_.2019.276.01.0001.01.ENG";
+	
+	private final TrustedListFacade facade = TrustedListFacade.newFacade();
+	
+	@Autowired
+	private ObjectMapper jsonMapper;
+	
+	public TrustStatusListType resolveTL(String uri) {
+		return resolveTL(uri, false);
+	}
+	
+	public TrustStatusListType resolveTL(String uri, boolean validate) {
+		log.debug("resolveTL.enter; got uri: {}, validate: {}", uri, validate);
+		
+		TrustStatusListType trustList = null;
+		try {
+			String content = resolveContent(uri);
+			trustList = parseContent(content, validate);
+		} catch (IOException | JAXBException | XMLStreamException | SAXException ex) {
+			log.error("resolveTL.error;", ex); 
+		}
+		log.debug("resolveTL.exit; returning TL: {}", trustList);
+		return trustList;
+	}
+	
+	public TLResolveResult resolveTLHash(String uri, String hash) {
+		log.debug("resolveTLHash.enter; got uri: {}, hash: {}", uri, hash);
+
+		String content = null;
+		TrustStatusListType trustList = null;
+		try {
+			content = resolveContent(uri);
+			trustList = parseContent(content, false);
+		} catch (Exception ex) {
+			log.warn("resolveTLHash.error reading TrustList", ex);
+		}
+		if (trustList == null) {
+			return null;
+		}
+        
+		TLResolveResult tlResult = new TLResolveResult(trustList, null, false);
+		try {
+			Multihash vcHash = Multihash.fromBase58(hash); // .decode(hash); 
+			Multihash.Type mType = vcHash.getType();
+
+			String algo = getDigestType(mType);
+			log.debug("resolveTLHash; hash algo is: {}", algo);
+			MessageDigest md = MessageDigest.getInstance(algo);
+			md.update(content.getBytes()); 
+			Multihash tlHash = new Multihash(mType, md.digest());
+			tlResult.setTlHash(tlHash.toString());
+			tlResult.setHashVerified(vcHash.equals(tlHash));
+		} catch (Exception ex) {
+			log.warn("resolveTLHash.error verifying Hash: {}", ex.getMessage());
+		}
+		log.debug("resolveTLHash.exit; returning: {}", tlResult);
+		return tlResult;
+	}
+	
+	private String resolveContent(String uri) throws IOException {
+		DSSFileLoader dl = onlineLoader();
+		DSSDocument tlDoc = dl.getDocument(uri);
+		log.debug("resolveContent; got TL doc with type: {}", tlDoc.getMimeType());
+		InputStream input = tlDoc.openStream();
+		return new String(input.readAllBytes(), StandardCharsets.UTF_8);
+	}
+	
+	private TrustStatusListType parseContent(String content, boolean validate) throws JAXBException, XMLStreamException, IOException, SAXException {
+		MimeType type = getDocType(content);
+		if (type == MimeTypeEnum.XML) {
+			return facade.unmarshall(content, validate);
+		} 
+		if (type == MimeTypeEnum.JSON) {
+			return jsonMapper.readValue(content, TrustStatusListType.class);
+		} 
+		log.info("parseContent; got content with unknown type: {}", type);
+		return null;
+	}
+
+	private MimeType getDocType(String content) {
+		OptionalInt opt = content.chars().filter(c -> c == '<' || c == '{').findFirst();
+		if (opt.isPresent()) {
+			if (opt.getAsInt() == '<') {
+				return MimeTypeEnum.XML;
+			} else if (opt.getAsInt() == '{') {
+				return MimeTypeEnum.JSON;
+			}
+		}
+		return MimeTypeEnum.BINARY;
+	}
+	
+	private String getDigestType(Multihash.Type mType) throws NoSuchAlgorithmException {
+		switch (mType) {
+			case sha1: return "SHA-1";
+			case sha2_256: return "SHA-256";
+			case sha2_512: return "SHA-512";
+			case sha3_256: return "SHA3-256";
+		}
+		throw new NoSuchAlgorithmException("Unsupported MType: " + mType);
+	}
+	
+	public boolean validateTL(String path) {
+		log.debug("validateTL.enter; got path: {}", path);
+		TLSource tlSource = new TLSource();
+		tlSource.setUrl(path);
+		TLValidationJob tlvJob = new TLValidationJob();
+		tlvJob.setTrustedListSources(tlSource);
+		tlvJob.setOfflineDataLoader(offlineLoader());
+		tlvJob.offlineRefresh();
+
+		tlvJob.setOnlineDataLoader(onlineLoader());
+		tlvJob.onlineRefresh();
+		log.debug("validateTL.exit; summary: {}", tlvJob.getSummary());
+		return true;
+	}
+	
+	public void validateDocument(String path) {
+		log.debug("validateDocument.enter got path: {}", path);
+		CommonCertificateVerifier commonCertificateVerifier = new CommonCertificateVerifier();
+		TLValidationJob job = job();
+		TrustedListsCertificateSource trustedListsCertificateSource = new TrustedListsCertificateSource();
+		job.setTrustedListCertificateSource(trustedListsCertificateSource);
+		job.onlineRefresh();
+		commonCertificateVerifier.setTrustedCertSources(trustedListsCertificateSource);
+		commonCertificateVerifier.setCrlSource(new OnlineCRLSource());
+		commonCertificateVerifier.setOcspSource(new OnlineOCSPSource());
+		commonCertificateVerifier.setAIASource(new DefaultAIASource());
+		
+		SignedDocumentValidator validator = SignedDocumentValidator.fromDocument(new FileDocument(path));
+		validator.setCertificateVerifier(commonCertificateVerifier);
+		Reports repo = validator.validateDocument();
+		log.debug("validateDocument.exit; report: {}", repo.getXmlSimpleReport());
+	}
+
+
+	private TLValidationJob job() {
+		TLValidationJob job = new TLValidationJob();
+		job.setOfflineDataLoader(offlineLoader());
+		job.setOnlineDataLoader(onlineLoader());
+		job.setTrustedListCertificateSource(trustedCertificateSource());
+		job.setSynchronizationStrategy(new AcceptAllStrategy());
+		job.setCacheCleaner(cacheCleaner());
+
+		LOTLSource europeanLOTL = europeanLOTL();
+		job.setListOfTrustedListSources(europeanLOTL);
+
+		//job.setLOTLAlerts(Arrays.asList(ojUrlAlert(europeanLOTL), lotlLocationAlert(europeanLOTL)));
+		//job.setTLAlerts(Arrays.asList(tlSigningAlert(), tlExpirationDetection()));
+
+		return job;
+	}
+
+	private TrustedListsCertificateSource trustedCertificateSource() {
+		return new TrustedListsCertificateSource();
+	}
+
+	private LOTLSource europeanLOTL() {
+		LOTLSource lotlSource = new LOTLSource();
+		lotlSource.setUrl(LOTL_URL);
+		//lotlSource.setCertificateSource(officialJournalContentKeyStore());
+		lotlSource.setSigningCertificatesAnnouncementPredicate(new OfficialJournalSchemeInformationURI(OJ_URL));
+		lotlSource.setPivotSupport(true);
+		return lotlSource;
+	}
+
+	private CertificateSource officialJournalContentKeyStore() {
+		try {
+			return new KeyStoreCertificateSource(new File("src/main/resources/keystore.p12"), "PKCS12", "dss-password");
+		} catch (IOException e) {
+			throw new DSSException("Unable to load the keystore", e);
+		}
+	}
+
+	private DSSFileLoader offlineLoader() {
+		FileCacheDataLoader offlineFileLoader = new FileCacheDataLoader();
+		offlineFileLoader.setCacheExpirationTime(-1); // negative value means cache never expires
+		offlineFileLoader.setDataLoader(new IgnoreDataLoader());
+		offlineFileLoader.setFileCacheDirectory(tlCacheDirectory());
+		return offlineFileLoader;
+	}
+
+	private DSSFileLoader onlineLoader() {
+		FileCacheDataLoader onlineFileLoader = new FileCacheDataLoader();
+		onlineFileLoader.setCacheExpirationTime(0);
+		onlineFileLoader.setDataLoader(new CommonsDataLoader()); // instance of DataLoader which can access to Internet (proxy,...)
+		onlineFileLoader.setFileCacheDirectory(tlCacheDirectory());
+		return onlineFileLoader;
+	}
+
+	private File tlCacheDirectory() {
+		File rootFolder = new File(System.getProperty("java.io.tmpdir"));
+		File tslCache = new File(rootFolder, "dss-tsl-loader");
+		if (tslCache.mkdirs()) {
+			log.info("TL Cache folder : {}", tslCache.getAbsolutePath());
+		}
+		return tslCache;
+	}
+
+	private CacheCleaner cacheCleaner() {
+		CacheCleaner cacheCleaner = new CacheCleaner();
+		cacheCleaner.setCleanMemory(true);
+		cacheCleaner.setCleanFileSystem(true);
+		cacheCleaner.setDSSFileLoader(offlineLoader());
+		return cacheCleaner;
+	}
+	
+	@Getter
+	@Setter
+	@AllArgsConstructor
+	@ToString
+	class TLResolveResult {
+		
+		private TrustStatusListType trustList;
+		private String tlHash;
+		private boolean hashVerified;
+		
+	}
+		
+	
+}
diff --git a/service/src/main/java/eu/xfsc/train/tcr/server/service/VerificationService.java b/service/src/main/java/eu/xfsc/train/tcr/server/service/VerificationService.java
deleted file mode 100644
index 67e2bd8dc8beadc4561e057e6c9e4aa4b6ca6b14..0000000000000000000000000000000000000000
--- a/service/src/main/java/eu/xfsc/train/tcr/server/service/VerificationService.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package eu.xfsc.train.tcr.server.service;
-
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Service;
-
-import eu.xfsc.train.tcr.api.generated.model.VerificationRequest;
-import eu.xfsc.train.tcr.api.generated.model.VerificationResult;
-import eu.xfsc.train.tcr.server.generated.controller.TrustedContentResolverApiDelegate;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * Implementation of the {@link eu.xfsc.fc.server.generated.controller.SessionApiDelegate} interface.
- */
-@Slf4j
-@Service
-public class VerificationService implements TrustedContentResolverApiDelegate {
-	
-	@Autowired
-	private DNSResolver dns;
-
-
-    @Override
-    public ResponseEntity<VerificationResult> resolveIssuer(VerificationRequest verificationRequest) {
-        log.debug("resolveIssuer.enter; got request: {}", verificationRequest);
-        try {
-			Collection<String> addresses = dns.resolveDid(verificationRequest.getTrustSchemePointer());
-        	//Collection<String> addresses = dns.verifyIdentity(verificationRequest.getIssuer(), verificationRequest.getTrustSchemePointer());
-	        VerificationResult result = new VerificationResult();
-	        result.setResolvedDID(verificationRequest.getIssuer());
-	        result.setTrustListEndpoints(new ArrayList<>(addresses));
-	        log.debug("resolveIssuer.exit; returning result: {}", result);
-	        return ResponseEntity.ok(result);
-		} catch (Exception ex) {
-			log.error("resolveIssuer.error", ex);
-			ResponseEntity response = ResponseEntity.internalServerError().body(ex.getMessage());
-			return response;
-		}
-    }
-
-}
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index 0cd04ba532bd8bbe759c895e7e96685d16b59314..5fb5f51666ad462560e6d6494a42657c63d9b517 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -21,7 +21,7 @@ server:
 
 spring:
   application:
-    name: federated-catalogue-service
+    name: trusted-content-resolver
   mvc:
     log-request-details: true
 
@@ -40,16 +40,24 @@ logging:
     eu.xfsc.train.tcr: DEBUG
     org.springframework.web: INFO
     org.xbill.DNS: DEBUG
+    uniresolver: DEBUG
     
 tcr:
+  did:
+   # base-uri: http://localhost:8080/1.0
+    base-uri: https://dev.uniresolver.io/1.0
+    timeout: 500
   dns:
     hosts: 1.1.1.1, 8.8.8.8, 8.8.4.4
 #      - 1.1.1.1 doesn't work this way'
 #      - 8.8.8.8
 #      - 8.8.4.4
-    timeout: 2010
-    verification:
-      enabled: true  #DANE..
+    timeout: 500
+    dnssec:
+      enabled: false  #DANE..
+      rootPath: /wrong/path
   http:
     timeout: 10
+  tl:
+    verify: true
     
\ No newline at end of file
diff --git a/service/src/test/java/eu/xfsc/train/tcr/server/controller/ResolutionControllerTest.java b/service/src/test/java/eu/xfsc/train/tcr/server/controller/ResolutionControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e6a634f59250a6a9748aa43d6224e55bd4623f1
--- /dev/null
+++ b/service/src/test/java/eu/xfsc/train/tcr/server/controller/ResolutionControllerTest.java
@@ -0,0 +1,192 @@
+package eu.xfsc.train.tcr.server.controller;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import eu.xfsc.train.tcr.api.generated.model.Error;
+import eu.xfsc.train.tcr.api.generated.model.ResolveRequest;
+import eu.xfsc.train.tcr.api.generated.model.ResolveResult;
+import eu.xfsc.train.tcr.api.generated.model.ResolveTrustList;
+import eu.xfsc.train.tcr.api.generated.model.ValidateRequest;
+import eu.xfsc.train.tcr.api.generated.model.ValidateResponse;
+import uniresolver.UniResolver;
+import uniresolver.result.ResolveRepresentationResult;
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+@ActiveProfiles("test")
+@ExtendWith(SpringExtension.class)
+public class ResolutionControllerTest {
+
+    @Autowired
+    private MockMvc mockMvc;
+    @Autowired
+    private ObjectMapper jsonMapper;
+	@MockBean
+	private UniResolver uniResolver;
+	
+	private static final String testDoc = """
+			{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"],"id":"did:web:essif.trust-scheme.de","verificationMethod":[{"id":"did:web:essif.trust-scheme.de#owner","type":"JsonWebKey2020",
+			"controller":"did:web:essif.trust-scheme.de","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"U8vPLaL0zjnRSjVwaYQNfPVW5k9j_XMF6dTxTOiAojs"}}],"service":[{"id":"did:web:essif.trust-scheme.de#issuer-list",
+			"type":"issuer-list","serviceEndpoint":"https://essif.iao.fraunhofer.de/files/policy/schuelerausweis.xml"}],"authentication":["did:web:essif.trust-scheme.de#owner"],
+			"assertionMethod":["did:web:essif.trust-scheme.de#owner"]}""";
+	
+	private static final String essifDoc = """
+			{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"],"id":"did:web:essif.iao.fraunhofer.de","verificationMethod":[{"id":"did:web:essif.iao.fraunhofer.de#owner","type":"JsonWebKey2020",
+			"controller":"did:web:essif.iao.fraunhofer.de","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"yaHbNw6nj4Pn3nGPHyyTqP-QHXYNJIpkA37PrIOND4c"}}],"service":[{"id":"did:web:essif.iao.fraunhofer.de#issuer-list",
+			"type":"issuer-list","serviceEndpoint":"https://essif.iao.fraunhofer.de/files/trustlist/federation1.test.train.trust-scheme.de.json"}],"authentication":["did:web:essif.iao.fraunhofer.de#owner"],
+			"assertionMethod":["did:web:essif.iao.fraunhofer.de#owner"]}""";
+	
+    private static final TypeReference<List<ResolveResult>> LIST_TYPE_REF = new TypeReference<List<ResolveResult>>() {
+    };
+    private static final TypeReference<Map<String, Object>> MAP_TYPE_REF = new TypeReference<Map<String, Object>>() {
+    };
+	
+
+    @Test
+    public void postResolveRequestShouldReturnFailureResponse() throws Exception {
+
+    	String did1 = "did:web:essif.trust-scheme.de";
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, testDoc.getBytes(), null);
+        when(uniResolver.resolveRepresentation(eq(did1), any())).thenReturn(rrr);
+    	String did2 = "did:web:essif.iao.fraunhofer.de";
+    	rrr = ResolveRepresentationResult.build(null, essifDoc.getBytes(), null);
+        when(uniResolver.resolveRepresentation(eq(did2), any())).thenReturn(rrr);
+    	
+        String ptr = "did-web.test.train.trust-scheme.de";
+        ResolveRequest request = new ResolveRequest();
+        request.setIssuer("https://test-issuer.sample.org");
+        request.addEndpointTypesItem("issuer-list");
+        request.addTrustSchemePointersItem(ptr); 
+        
+        String response = mockMvc
+            .perform(MockMvcRequestBuilders.post("/resolve")
+            .content(jsonMapper.writeValueAsString(request))		
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isUnprocessableEntity())
+            .andReturn()
+            .getResponse()
+            .getContentAsString();
+        Error error = jsonMapper.readValue(response, Error.class);
+        assertEquals("verification_error", error.getCode());
+    }
+
+    @Test
+    public void postResolveRequestShouldReturnEmptyResponse() throws Exception {
+      
+    	String did = "did:web:essif.trust-scheme.de";
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, testDoc.getBytes(), null);
+        when(uniResolver.resolveRepresentation(eq(did), any())).thenReturn(rrr);
+
+        String ptr = "did-web.test.train.trust-scheme.de";
+        ResolveRequest request = new ResolveRequest();
+        request.setIssuer("https://test-issuer.sample.org");
+        request.addEndpointTypesItem("wrong-type"); 
+        request.addTrustSchemePointersItem(ptr);
+        
+        String response = mockMvc
+            .perform(MockMvcRequestBuilders.post("/resolve")
+            .content(jsonMapper.writeValueAsString(request))		
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andReturn()
+            .getResponse()
+            .getContentAsString();
+        List<ResolveResult> result = jsonMapper.readValue(response, LIST_TYPE_REF);
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        ResolveResult rr = result.get(0);
+        assertEquals(did, rr.getDid());
+        assertEquals(List.of(ptr), rr.getPointers());
+        assertNotNull(rr.getDocument());
+        assertTrue(rr.getEndpoints().isEmpty());
+    }
+
+    @Test
+    public void postResolveRequestShouldReturnTrustListResponse() throws Exception {
+      
+    	String did = "did:web:essif.iao.fraunhofer.de";
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, essifDoc.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(did), any())).thenReturn(rrr);
+   	
+        String ptr = "gxfs.test.train.trust-scheme.de";
+        String issuer = "https://www.federation1.com/";
+        ResolveRequest request = new ResolveRequest(issuer, List.of(ptr), null, null);
+        
+        String response = mockMvc
+            .perform(MockMvcRequestBuilders.post("/resolve")
+            .content(jsonMapper.writeValueAsString(request))		
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andReturn()
+            .getResponse()
+            .getContentAsString();
+        List<ResolveResult> result = jsonMapper.readValue(response, LIST_TYPE_REF);
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        ResolveResult rr = result.get(0);
+        assertEquals(did, rr.getDid());
+        assertEquals(List.of(ptr), rr.getPointers());
+        assertNotNull(rr.getDocument());
+        assertFalse(rr.getEndpoints().isEmpty());
+        ResolveTrustList rtl = rr.getEndpoints().get(0);
+        assertEquals("https://essif.iao.fraunhofer.de/files/trustlist/federation1.test.train.trust-scheme.de.json", rtl.getEndpoint());
+        Map<String, Object> tsp = (Map<String, Object>) rtl.getTrustList().get("tspinformation");
+        Map<String, Object> tspn = (Map<String, Object>) tsp.get("tspname");
+        Map<String, Object> name = ((List<Map<String, Object>>) tspn.get("name")).get(0);
+        assertEquals(issuer, name.get("value"));
+    }
+
+    
+    @Test
+    public void postValidateRequestShouldReturnValidateResponse() throws Exception {
+      
+    	String did = "did:web:essif.iao.fraunhofer.de";
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, essifDoc.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(did), any())).thenReturn(rrr);
+   	
+        String issuer = "https://www.federation1.com/";
+        ValidateRequest request = new ValidateRequest(issuer, did, //jsonMapper.readValue(essifDoc, MAP_TYPE_REF), 
+        		List.of("https://essif.iao.fraunhofer.de/files/trustlist/federation1.test.train.trust-scheme.de.json"));
+        
+        String response = mockMvc
+            .perform(MockMvcRequestBuilders.post("/validate")
+            .content(jsonMapper.writeValueAsString(request))		
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andReturn()
+            .getResponse()
+            .getContentAsString();
+        ValidateResponse result = jsonMapper.readValue(response, ValidateResponse.class);
+        assertNotNull(result);
+    }
+    
+}
+
+
diff --git a/service/src/test/java/eu/xfsc/train/tcr/server/controller/VerificationControllerTest.java b/service/src/test/java/eu/xfsc/train/tcr/server/controller/VerificationControllerTest.java
deleted file mode 100644
index 57bfa11ab9e48c06bc981a6f0c6b33f54daa8b87..0000000000000000000000000000000000000000
--- a/service/src/test/java/eu/xfsc/train/tcr/server/controller/VerificationControllerTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package eu.xfsc.train.tcr.server.controller;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import eu.xfsc.train.tcr.api.generated.model.VerificationRequest;
-import eu.xfsc.train.tcr.api.generated.model.VerificationResult;
-
-
-@SpringBootTest
-@AutoConfigureMockMvc
-//@ActiveProfiles("test")
-@ExtendWith(SpringExtension.class)
-public class VerificationControllerTest {
-
-    @Autowired
-    private MockMvc mockMvc;
-    @Autowired
-    private ObjectMapper jsonMapper;
-
-    
-    @Test
-    public void postVerifyRequestShouldReturnSuccessResponse() throws Exception {
-      
-        VerificationRequest request = new VerificationRequest();
-        request.setIssuer("https://test-issuer.sample.org");
-        request.setTrustSchemePointer("did-web.test.train.trust-scheme.de"); 
-        
-        String response = mockMvc
-            .perform(MockMvcRequestBuilders.post("/resolve")
-            .content(jsonMapper.writeValueAsString(request))		
-            .contentType(MediaType.APPLICATION_JSON))
-            .andExpect(status().isOk())
-            .andReturn()
-            .getResponse()
-            .getContentAsString();
-        VerificationResult result = jsonMapper.readValue(response, VerificationResult.class);
-        assertNotNull(result);
-        assertTrue(result.getTrustListEndpoints().contains("did:web:essif.trust-scheme.de"));
-    }
-    
-}
diff --git a/service/src/test/java/eu/xfsc/train/tcr/server/service/DIDResolverTest.java b/service/src/test/java/eu/xfsc/train/tcr/server/service/DIDResolverTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3efcfaceeeb9b788155aade99491c2a26b807e58
--- /dev/null
+++ b/service/src/test/java/eu/xfsc/train/tcr/server/service/DIDResolverTest.java
@@ -0,0 +1,142 @@
+package eu.xfsc.train.tcr.server.service;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import uniresolver.UniResolver;
+import uniresolver.result.ResolveRepresentationResult;
+
+@SpringBootTest
+@ActiveProfiles("test")
+@ExtendWith(SpringExtension.class)
+public class DIDResolverTest {
+
+	@MockBean
+	//@Autowired
+	private UniResolver uniResolver;
+	@Autowired
+	private DIDResolver didResolver;
+	
+	private static final String fhDidEssif = "did:web:essif.iao.fraunhofer.de";
+
+	private static final String fhDidTrust = "did:web:essif.trust-scheme.de";
+	
+	private static final String didDocSingleEP = """
+			{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"],"id":"did:web:essif.trust-scheme.de","verificationMethod":[{"id":"did:web:essif.trust-scheme.de#owner","type":"JsonWebKey2020",
+			"controller":"did:web:essif.trust-scheme.de","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"U8vPLaL0zjnRSjVwaYQNfPVW5k9j_XMF6dTxTOiAojs"}}],"service":[{"id":"did:web:essif.trust-scheme.de#issuer-list",
+			"type":"issuer-list","serviceEndpoint":"https://essif.iao.fraunhofer.de/files/policy/schuelerausweis.xml"}],"authentication":["did:web:essif.trust-scheme.de#owner"],
+			"assertionMethod":["did:web:essif.trust-scheme.de#owner"]}""";
+
+	private static final String didDocManyEP = """
+			{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"],"id":"did:web:essif.trust-scheme.de","verificationMethod":[{"id":"did:web:essif.trust-scheme.de#owner","type":"JsonWebKey2020",
+			"controller":"did:web:essif.trust-scheme.de","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"U8vPLaL0zjnRSjVwaYQNfPVW5k9j_XMF6dTxTOiAojs"}}],"service":[{"id":"did:web:essif.trust-scheme.de#issuer-list",
+			"type":"issuer-list","serviceEndpoint":["https://essif.iao.fraunhofer.de/firstEP", "https://essif.iao.fraunhofer.de/secondEP"]}],"authentication":["did:web:essif.trust-scheme.de#owner"],
+			"assertionMethod":["did:web:essif.trust-scheme.de#owner"]}""";
+	
+	private static final String didDocObjectEP = """
+			{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"],"id":"did:web:essif.trust-scheme.de","verificationMethod":[{"id":"did:web:essif.trust-scheme.de#owner","type":"JsonWebKey2020",
+			"controller":"did:web:essif.trust-scheme.de","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"U8vPLaL0zjnRSjVwaYQNfPVW5k9j_XMF6dTxTOiAojs"}}],"service":[{"id":"did:web:essif.trust-scheme.de#issuer-list",
+			"type":"issuer-list","serviceEndpoint":{"services":["https://essif.iao.fraunhofer.de/firstEP", "https://essif.iao.fraunhofer.de/secondEP"]}}],"authentication":["did:web:essif.trust-scheme.de#owner"],
+			"assertionMethod":["did:web:essif.trust-scheme.de#owner"]}""";
+	
+	private static final String didDocKeyVC = """
+			{"@context": ["https://www.w3.org/ns/did/v1", {"Ed25519VerificationKey2018": "https://w3id.org/security#Ed25519VerificationKey2018", "publicKeyJwk": {"@id": "https://w3id.org/security#publicKeyJwk", "@type": "@json"}}],
+			 "id": "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM", "verificationMethod": [{"id": "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM#z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM", "type": "Ed25519VerificationKey2018",
+		     "controller": "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM", "publicKeyJwk": {"kty": "OKP", "crv": "Ed25519", "x": "hbtAIehGcx_wXTFzIYJzrHOwl8IGV8EzRgx__FUEnso"}}], "authentication": [
+		     "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM#z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM"], "assertionMethod": ["did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM#z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM"]}""";
+	
+	private static final String didDocEssif = """
+			{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/jws-2020/v1"],"id":"did:web:essif.iao.fraunhofer.de","verificationMethod":[{"id":"did:web:essif.iao.fraunhofer.de#owner","type":"JsonWebKey2020",
+			"controller":"did:web:essif.iao.fraunhofer.de","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"yaHbNw6nj4Pn3nGPHyyTqP-QHXYNJIpkA37PrIOND4c"}}],"service":[{"id":"did:web:essif.iao.fraunhofer.de#issuer-list",
+			"type":"issuer-list","serviceEndpoint":"https://essif.iao.fraunhofer.de/files/trustlist/federation1.test.train.trust-scheme.de.json"}],"authentication":["did:web:essif.iao.fraunhofer.de#owner"],
+			"assertionMethod":["did:web:essif.iao.fraunhofer.de#owner"]}""";
+	
+    @Test
+    public void testDIDResolutionSingleEP() throws Exception {
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, didDocSingleEP.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(fhDidTrust), any())).thenReturn(rrr);
+    	
+        DIDResolver.DIDResolveResult didRes = didResolver.resolveDid(fhDidTrust, null);
+        assertNotNull(didRes);
+        assertNotNull(didRes.getDocument());
+        assertTrue(didRes.getEndpoints().contains("https://essif.iao.fraunhofer.de/files/policy/schuelerausweis.xml"));
+    }
+
+    @Test
+    public void testDIDResolutionManyEP() throws Exception {
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, didDocManyEP.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(fhDidTrust), any())).thenReturn(rrr);
+    	
+        DIDResolver.DIDResolveResult didRes = didResolver.resolveDid(fhDidTrust, null);
+        assertNotNull(didRes);
+        assertNotNull(didRes.getDocument());
+        assertEquals(2, didRes.getEndpoints().size());
+        assertTrue(didRes.getEndpoints().contains("https://essif.iao.fraunhofer.de/firstEP"));
+        assertTrue(didRes.getEndpoints().contains("https://essif.iao.fraunhofer.de/secondEP"));
+    }
+    
+    @Test
+    public void testDIDResolutionObjectEP() throws Exception {
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, didDocObjectEP.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(fhDidTrust), any())).thenReturn(rrr);
+    	
+        DIDResolver.DIDResolveResult didRes = didResolver.resolveDid(fhDidTrust, null);
+        assertNotNull(didRes);
+        assertNotNull(didRes.getDocument());
+        assertEquals(2, didRes.getEndpoints().size());
+        assertTrue(didRes.getEndpoints().contains("https://essif.iao.fraunhofer.de/firstEP"));
+        assertTrue(didRes.getEndpoints().contains("https://essif.iao.fraunhofer.de/secondEP"));
+    }
+    
+    @Test
+    public void testDIDConfigResolution() throws Exception {
+    	String did = "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM";
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, didDocKeyVC.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(did), any())).thenReturn(rrr);
+    	
+    	String origin = "https://identity.foundation";
+    	boolean verified = didResolver.resolveDidConfig(origin);
+    	assertTrue(verified);
+    }
+    
+    @Test
+    public void testDIDAndConfigResolution() throws Exception {
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, didDocEssif.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(fhDidEssif), any())).thenReturn(rrr);
+    	
+        DIDResolver.DIDResolveResult didRes = didResolver.resolveDid(fhDidEssif, null);
+        assertNotNull(didRes);
+        assertNotNull(didRes.getDocument());
+        assertEquals("https://essif.iao.fraunhofer.de", didRes.getOrigin());
+        assertEquals(List.of("https://essif.iao.fraunhofer.de/files/trustlist/federation1.test.train.trust-scheme.de.json"), didRes.getEndpoints());
+    	
+        // now test config..
+    	boolean verified = didResolver.resolveDidConfig("https://essif.iao.fraunhofer.de");
+    	assertTrue(verified); 
+    }
+    
+    @Test
+    public void testTLResolution() throws Exception {
+    	ResolveRepresentationResult rrr = ResolveRepresentationResult.build(null, didDocEssif.getBytes(), null); 
+        when(uniResolver.resolveRepresentation(eq(fhDidEssif), any())).thenReturn(rrr);
+
+    	DIDResolver.VCResolveResult vcRes = didResolver.resolveVC("https://essif.iao.fraunhofer.de/files/trustlist/federation1.test.train.trust-scheme.de.json");
+        assertEquals("https://tspa.trust-scheme.de/tspa_train_domain/api/v1/scheme/federation1.test.train.trust-scheme.de", vcRes.getTrustListUri());
+        assertTrue(vcRes.isVerified());
+    }
+    
+}
diff --git a/service/src/test/java/eu/xfsc/train/tcr/server/service/DNSResolverTest.java b/service/src/test/java/eu/xfsc/train/tcr/server/service/DNSResolverTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..459945a030f2c3d896275270844f88724361fcfc
--- /dev/null
+++ b/service/src/test/java/eu/xfsc/train/tcr/server/service/DNSResolverTest.java
@@ -0,0 +1,5 @@
+package eu.xfsc.train.tcr.server.service;
+
+public class DNSResolverTest {
+
+}
diff --git a/service/src/test/java/eu/xfsc/train/tcr/server/service/TLResolverTest.java b/service/src/test/java/eu/xfsc/train/tcr/server/service/TLResolverTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..431e7bac332a33e775cf5d52671a4a3834f3d845
--- /dev/null
+++ b/service/src/test/java/eu/xfsc/train/tcr/server/service/TLResolverTest.java
@@ -0,0 +1,113 @@
+package eu.xfsc.train.tcr.server.service;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.File;
+import java.net.URL;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import eu.europa.esig.trustedlist.jaxb.tsl.TrustStatusListType;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@SpringBootTest
+@ActiveProfiles("test")
+@ExtendWith(SpringExtension.class)
+public class TLResolverTest {
+	
+	private static final String fh_TrustList_Uri = "https://tspa.trust-scheme.de/tspa_train_domain/api/v1/scheme/federation1.test.train.trust-scheme.de";
+	private static final String fh_TrustList_Hash = "Qmb6gRAKQmVopCVDs1TMspu3crtoQ7JLLWY6rYNb5yVeWY"; 
+
+	@Autowired
+	private TLResolver tlResolver;
+
+	@Test
+	public void testTLResolveXMLFile() throws Exception {
+		URL url = this.getClass().getResource("/SampleTrustList.xml");
+		File file = new File(url.getFile());
+		assertTrue(file.exists());
+		TrustStatusListType list = tlResolver.resolveTL(file.getCanonicalFile().toURI().toString());
+		assertNotNull(list);
+	}
+
+	@Test
+	public void testTLResolveJSONFile() throws Exception {
+		URL url = this.getClass().getResource("/SampleTrustList.json");
+		File file = new File(url.getFile());
+		assertTrue(file.exists());
+		TrustStatusListType list = tlResolver.resolveTL(file.getCanonicalFile().toURI().toString());
+		assertNotNull(list);
+	}
+
+	@Test
+	public void testTLResolveXMLUri() throws Exception {
+		TrustStatusListType list = tlResolver.resolveTL(fh_TrustList_Uri, false);
+		assertNotNull(list);
+	}
+
+	@Test
+	public void testTLResolveWithHash() throws Exception {
+		TLResolver.TLResolveResult tlRes = tlResolver.resolveTLHash(fh_TrustList_Uri, fh_TrustList_Hash);
+		assertNotNull(tlRes);
+		assertTrue(tlRes.isHashVerified());
+	}
+
+	@Test
+	public void testTLValidationXML() throws Exception {
+		URL url = this.getClass().getResource("/schuelerausweis.xml");
+		File file = new File(url.getFile());
+		assertTrue(file.exists());
+
+		boolean valid = tlResolver.validateTL(file.getCanonicalFile().toURI().toString());
+		assertTrue(valid);
+	}
+
+	@Test
+	public void testTLValidationJSON() throws Exception {
+		URL url = this.getClass().getResource("/FHTrustList.json");
+		File file = new File(url.getFile());
+		assertTrue(file.exists());
+		boolean valid = tlResolver.validateTL(file.getCanonicalFile().toURI().toString());
+		assertTrue(valid);
+	}
+	
+	@Test
+	public void testValidateSampleTrustList() throws Exception {
+		// File cache = new File("cache");
+		// cache.deleteOnExit();
+
+		URL url = this.getClass().getResource("/SampleTrustList.xml");
+		File file = new File(url.getFile());
+		assertTrue(file.exists());
+
+		tlResolver.validateDocument(file.getPath());
+		// assertTrue(valid);
+	}
+
+	@Test
+	public void testValidateTL_21() throws Exception {
+		URL url = this.getClass().getResource("/TL-21.xml");
+		File file = new File(url.getFile());
+		assertTrue(file.exists());
+
+		long stamp = System.currentTimeMillis();
+		tlResolver.validateDocument(file.getPath());
+		stamp = System.currentTimeMillis() - stamp;
+		log.info("testValidateTL_21; first validation took {} ms", stamp);
+		
+		stamp = System.currentTimeMillis();
+		tlResolver.validateDocument(file.getPath());
+		stamp = System.currentTimeMillis() - stamp;
+		log.info("testValidateTL_21; second validation took {} ms", stamp);
+	}
+	
+}
\ No newline at end of file
diff --git a/service/src/test/resources/FHTrustList.json b/service/src/test/resources/FHTrustList.json
new file mode 100644
index 0000000000000000000000000000000000000000..e8ecaeaea7f0b33e64413b4c2b00889e05c67f17
--- /dev/null
+++ b/service/src/test/resources/FHTrustList.json
@@ -0,0 +1,121 @@
+{
+   "TrustServiceStatusList": {
+      "SchemeInformation": {
+         "TSLVersionIdentifier": "1",
+         "TSLSequenceNumber": "1",
+         "TSLType": "http://TRAIN/TrstSvc/TrustedList/TSLType/federation1-POC",
+         "SchemeOperatorName": {
+            "Name": "Federation 1"
+         },
+         "SchemeOperatorAddress": {
+            "PostalAddresses": {
+               "PostalAddress": {
+                  "StreetAddress": "Hauptsrasse",
+                  "Locality": "Stuttgart",
+                  "PostalCode": "70563",
+                  "CountryName": "DE"
+               }
+            },
+            "ElectronicAddress": {
+               "URI": "mailto:admin@federation1.de"
+            }
+         },
+         "SchemeName": {
+            "Name": "federation1.train.trust-scheme.de"
+         },
+         "SchemeInformationURI": {
+            "URI": "https://TRAIN/interoperability/federation-Directory"
+         },
+         "SchemeTypeCommunityRules": {
+            "URI": "https://TrustScheme_TRAIN.example.com/en/federation1-dir-rules.html"
+         },
+         "SchemeTerritory": "EU",
+         "PolicyOrLegalNotice": {
+            "TSLLegalNotice": "The applicable legal framework for the present trusted list is TBD. Valid legal notice text will be created."
+         },
+         "PointersToOtherTSL": "",
+         "ListIssueDateTime": "2021-12-15T00:00:00Z",
+         "LastUpdated": "2021-12-15T00:00:00Z"
+      }
+   },
+  "TrustServiceProvider": {
+    "TSPCurrentStatus": "string",
+    "StatusStartingTime": "string",
+    "TSPInformation": {
+      "TSPName": "string",
+      "TSPLegalName": "string",
+      "TSPRole": "string",
+      "TrustSchemeName": "string",
+      "OtherTSL": "string",
+      "TSPInformationURI": "string",
+      "TSPLegalBasis": "string",
+      "TSPEntityIdentifierList": {
+        "TSPEntityIdendifier": [
+          {
+            "Type": "string",
+            "Value": "string"
+          }
+        ]
+      },
+      "TSPCertificationList": {
+        "TSPCertification": [
+          {
+            "Type": "string",
+            "Value": "string"
+          }
+        ]
+      },
+      "TSPKeywords": "string",
+      "Address": {
+        "ElectronicAddress": "string",
+        "PostalAddress": {
+          "StreetAddress1": "string",
+          "StreetAddress2": "string",
+          "City": "string",
+          "State": "string",
+          "Country": "string",
+          "PostalCode": "string"
+        }
+      }
+    },
+    "SubmitterInfo": {
+      "Name": "string",
+      "Address": {
+        "ElectronicAddress": "string",
+        "PostalAddress": {
+          "StreetAddress1": "string",
+          "StreetAddress2": "string",
+          "City": "string",
+          "State": "string",
+          "Country": "string",
+          "PostalCode": "string"
+        }
+      }
+    },
+    "TSPServices": {
+      "TSPService": [
+        {
+          "ServiceCurrentStatus": "string",
+          "StatusStartingTime": "string",
+          "ServiceName": "string",
+          "ServiceTypeIdentifier": "string",
+          "ServiceSupplyPoint": "string",
+          "ServiceDefinitionURI": "string",
+          "ServiceDigitalIdentity": {
+            "Value": "string",
+            "KeyType": "string"
+          },
+          "AdditionalServiceInformation": {
+            "ServiceIssuedCredentialTypes": [
+              {
+                "CredentialType": "string"
+              }
+            ],
+            "ServiceGovernanceURI": "string",
+            "ServiceBusinessRulesURI": "string"
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/SampleTrustList.json b/service/src/test/resources/SampleTrustList.json
new file mode 100644
index 0000000000000000000000000000000000000000..9801328489268c13ba0f12b12b296d43842a3995
--- /dev/null
+++ b/service/src/test/resources/SampleTrustList.json
@@ -0,0 +1,320 @@
+{
+	"TrustServiceStatusList": {
+		"SchemeInformation": {
+			"HistoricalInformationPeriod": "65535",
+			"ListIssueDateTime": "2022-09-27T00:00:00Z",
+			"NextUpdate": "2022-12-27T00:00:00Z",
+			"PolicyOrLegalNotice": {
+				"TSLLegalNotice": {
+					"#text": "This is an experimental list for the GXFS Federation Notary.",
+					"@xml:lang": "en"
+				}
+			},
+			"SchemeInformationURI": {
+				"URI": {
+					"#text": "https://dl.gi.de/handle/20.500.12116/38702",
+					"@xml:lang": "en"
+				}
+			},
+			"SchemeName": {
+				"Name": {
+					"#text": "DE:TRAIN",
+					"@xml:lang": "en"
+				}
+			},
+			"SchemeOperatorAddress": {
+				"ElectronicAddress": {
+					"URI": [
+						{
+							"#text": "mailto:mail@federation1.com",
+							"@xml:lang": "en"
+						},
+						{
+							"#text": "https://www.federation1.com",
+							"@xml:lang": "en"
+						}
+					]
+				},
+				"PostalAddresses": {
+					"PostalAddress": {
+						"@xml:lang": "en",
+						"CountryName": "DE",
+						"Locality": "K\u00f6ln",
+						"PostalCode": "50825",
+						"StreetAddress": "Lichtstra\u00dfe 43h"
+					}
+				}
+			},
+			"SchemeOperatorName": {
+				"Name": {
+					"#text": "Federation 1 Notary",
+					"@xml:lang": "en"
+				}
+			},
+			"SchemeTerritory": "GLOBAL",
+			"SchemeTypeCommunityRules": {
+				"URI": {
+					"#text": "https://train.trustscheme.de /schemerules/ngi.train.trustscheme.de",
+					"@xml:lang": "en"
+				}
+			},
+			"StatusDeterminationApproach": "http://uri.etsi.org/TrstSvc/TrustedList/StatusDetn/EUappropriate",
+			"TSLSequenceNumber": "1",
+			"TSLType": "http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUgeneric",
+			"TSLVersionIdentifier": "5"
+		},
+		"TrustServiceProviderList": {
+			"TrustServiceProvider": {
+				"StatusStartingTime": {
+					"dateTime": "2022-11-22T00:00:00Z"
+				},
+				"TSPCurrentStatus": {
+					"Name": {
+						"#text": "Active",
+						"@xml:lang": "en"
+					}
+				},
+				"TSPInformation": {
+					"TSPAddress": {
+						"ElectronicAddress": {
+							"URI": {
+								"#text": "mailto:mail.notary1@federation.com",
+								"@xml:lang": "en"
+							}
+						},
+						"PostalAddresses": {
+							"PostalAddress": {
+								"@xml:lang": "en",
+								"CountryName": "DE",
+								"Locality": "K\u00f6ln",
+								"PostalCode": "50825",
+								"StreetAddress": "Lichtstra\u00dfe 43h"
+							}
+						}
+					},
+					"TSPCertificationList": {
+						"TSPCertification": [
+							{
+								"@xml:lang": "en",
+								"Scope": null,
+								"Type": "LEI",
+								"Value": "1234567"
+							},
+							{
+								"@xml:lang": "en",
+								"Scope": null,
+								"Type": "Gaia-X Compliance",
+								"Value": "1234567"
+							},
+							{
+								"@xml:lang": "en",
+								"Scope": null,
+								"Type": "eidas",
+								"Value": "1234567"
+							}
+						]
+					},
+					"TSPInformationURI": {
+						"URI": {
+							"#text": "https://notary1.info/TRAIN/info",
+							"@xml:lang": "en"
+						}
+					},
+					"TSPName": {
+						"Name": {
+							"#text": "Notary 1",
+							"@xml:lang": "en"
+						}
+					},
+					"TSPTradeName": {
+						"Name": [
+							{
+								"#text": "NTRUK-SC090312",
+								"@xml:lang": "en"
+							},
+							{
+								"#text": "Notary Federation 1",
+								"@xml:lang": "en"
+							}
+						]
+					}
+				},
+				"TSPServices": {
+					"TSPService": [
+						{
+							"ServiceInformation": {
+								"AdditionalServiceInformation": {
+									"ServiceBusinessRules": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953",
+									"ServiceCredentialTypes": {
+										"CredentialType": [
+											"X.509",
+											"did:web"
+										]
+									},
+									"ServiceGovernanceURI": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953"
+								},
+								"ServiceDigitalIdentity": {
+									"did": "did:web:notary.federation1.com",
+									"x509": "242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf"
+								},
+								"ServiceName": {
+									"Name": {
+										"#text": "Federation Participant Membership Credential",
+										"@xml:lang": "en"
+									}
+								},
+								"ServiceStatus": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted",
+								"ServiceSupplyPoints": {
+									"ServiceSupplyPoint": "https://participant.membership.notary1.federation.com"
+								},
+								"ServiceTypeIdentifier": "https://participant.membership.notary1.federation.com",
+								"StatusStartingTime": "2022-09-29T22:00:00Z",
+								"TSPServiceDefinitionURI": {
+									"URI": "https://notary1.info/schema/V-2022-1/participant_membership.json"
+								}
+							}
+						},
+						{
+							"ServiceInformation": {
+								"AdditionalServiceInformation": {
+									"ServiceBusinessRules": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953",
+									"ServiceCredentialTypes": {
+										"CredentialType": [
+											"X.509",
+											"did:web"
+										]
+									},
+									"ServiceGovernanceURI": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953"
+								},
+								"ServiceDigitalIdentity": {
+									"did": "did:web:notary.federation1.com",
+									"x509": "242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf"
+								},
+								"ServiceName": {
+									"Name": {
+										"#text": "Federation Principal Credential",
+										"@xml:lang": "en"
+									}
+								},
+								"ServiceStatus": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted",
+								"ServiceSupplyPoints": {
+									"ServiceSupplyPoint": "https://verifier.research.identiproof.io/"
+								},
+								"ServiceTypeIdentifier": "https://principal.membership.notary1.federation.com",
+								"StatusStartingTime": "2022-09-29T22:00:00Z",
+								"TSPServiceDefinitionURI": {
+									"URI": "https://notary1.info/schema/V-2022-1/participant_membership.json"
+								}
+							}
+						},
+						{
+							"ServiceInformation": {
+								"AdditionalServiceInformation": {
+									"ServiceBusinessRules": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953",
+									"ServiceCredentialTypes": {
+										"CredentialType": [
+											"X.509",
+											"did:web"
+										]
+									},
+									"ServiceGovernanceURI": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953"
+								},
+								"ServiceDigitalIdentity": {
+									"did": "did:web:notary.federation1.com",
+									"x509": "242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf"
+								},
+								"ServiceName": {
+									"Name": {
+										"#text": "Federation Consumer Credential",
+										"@xml:lang": "en"
+									}
+								},
+								"ServiceStatus": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted",
+								"ServiceSupplyPoints": {
+									"ServiceSupplyPoint": "https://verifier.research.identiproof.io/"
+								},
+								"ServiceTypeIdentifier": "https://consumer.membership.notary1.federation.com",
+								"StatusStartingTime": "2022-09-29T22:00:00Z",
+								"TSPServiceDefinitionURI": {
+									"URI": "https://notary1.info/schema/V-2022-1/participant_membership.json"
+								}
+							}
+						},
+						{
+							"ServiceInformation": {
+								"AdditionalServiceInformation": {
+									"ServiceBusinessRules": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953",
+									"ServiceCredentialTypes": {
+										"CredentialType": [
+											"X.509",
+											"did:web"
+										]
+									},
+									"ServiceGovernanceURI": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953"
+								},
+								"ServiceDigitalIdentity": {
+									"did": "did:web:notary.federation1.com",
+									"x509": "242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf"
+								},
+								"ServiceName": {
+									"Name": {
+										"#text": "Federation Resource Credential",
+										"@xml:lang": "en"
+									}
+								},
+								"ServiceStatus": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted",
+								"ServiceSupplyPoints": {
+									"ServiceSupplyPoint": "https://resource.membership.notary1.federation.com"
+								},
+								"ServiceTypeIdentifier": "https://resource.membership.notary1.federation.com",
+								"StatusStartingTime": "2022-09-29T22:00:00Z",
+								"TSPServiceDefinitionURI": {
+									"URI": "https://notary1.info/schema/V-2022-1/participant_membership.json"
+								}
+							}
+						},
+						{
+							"ServiceInformation": {
+								"AdditionalServiceInformation": {
+									"ServiceBusinessRules": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953",
+									"ServiceCredentialTypes": {
+										"CredentialType": [
+											"X.509",
+											"did:web"
+										]
+									},
+									"ServiceGovernanceURI": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953"
+								},
+								"ServiceDigitalIdentity": {
+									"did": "did:web:notary.federation1.com",
+									"x509": "242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf"
+								},
+								"ServiceName": {
+									"Name": {
+										"#text": "Federation Onboarding Credential",
+										"@xml:lang": "en"
+									}
+								},
+								"ServiceStatus": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted",
+								"ServiceSupplyPoints": {
+									"ServiceSupplyPoint": "https://onboarding.membership.notary1.federation.com"
+								},
+								"ServiceTypeIdentifier": "https://onboarding.membership.notary1.federation.com",
+								"StatusStartingTime": "2022-09-29T22:00:00Z",
+								"TSPServiceDefinitionURI": {
+									"URI": "https://notary1.info/schema/V-2022-1/participant_membership.json"
+								}
+							}
+						}
+					]
+				},
+				"UID": {
+					"Name": {
+						"#text": "2325",
+						"@xml:lang": "en"
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/service/src/test/resources/SampleTrustList.xml b/service/src/test/resources/SampleTrustList.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc9e273c0f5cf90ad84ea17a2975c6c4f9f58457
--- /dev/null
+++ b/service/src/test/resources/SampleTrustList.xml
@@ -0,0 +1,281 @@
+<TrustServiceStatusList
+	xmlns="http://uri.etsi.org/02231/v2#"
+	xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"
+	xmlns:ns3="http://uri.etsi.org/01903/v1.3.2#"
+	xmlns:ns4="http://uri.etsi.org/02231/v2/additionaltypes#"
+	xmlns:ns5="http://uri.etsi.org/TrstSvc/SvcInfoExt/eSigDir-1999-93-EC-TrustedList/#"
+	xmlns:ns6="http://uri.etsi.org/01903/v1.4.1#"
+	TSLTag="http://uri.etsi.org/19612/TSLTag">
+	<SchemeInformation>
+		<TSLVersionIdentifier>5</TSLVersionIdentifier>
+		<TSLSequenceNumber>1</TSLSequenceNumber>
+		<TSLType>http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUgeneric</TSLType>
+		<SchemeOperatorName>
+			<Name xml:lang="en">Federation 1 Notary</Name>
+		</SchemeOperatorName>
+		<SchemeOperatorAddress>
+			<PostalAddresses>
+				<PostalAddress xml:lang="en">
+					<StreetAddress>Lichtstraße 43h</StreetAddress>
+					<Locality>Köln</Locality>
+					<PostalCode>50825</PostalCode>
+					<CountryName>DE</CountryName>
+				</PostalAddress>
+			</PostalAddresses>
+			<ElectronicAddress>
+				<URI xml:lang="en">mailto:mail@federation1.com</URI>
+				<URI xml:lang="en">https://www.federation1.com</URI>
+			</ElectronicAddress>
+		</SchemeOperatorAddress>
+		<SchemeName>
+			<Name xml:lang="en">DE:TRAIN</Name>
+		</SchemeName>
+		<SchemeInformationURI>
+			<URI xml:lang="en">https://dl.gi.de/handle/20.500.12116/38702</URI>
+		</SchemeInformationURI>
+		<StatusDeterminationApproach>http://uri.etsi.org/TrstSvc/TrustedList/StatusDetn/EUappropriate</StatusDeterminationApproach>
+		<SchemeTypeCommunityRules>
+			<URI xml:lang="en">https://train.trustscheme.de/schemerules/ngi.train.trustscheme.de</URI>
+		</SchemeTypeCommunityRules>
+		<SchemeTerritory>GLOBAL</SchemeTerritory>
+		<PolicyOrLegalNotice>
+			<TSLLegalNotice xml:lang="en">This is an experimental list for the GXFS Federation Notary.</TSLLegalNotice>
+		</PolicyOrLegalNotice>
+		<HistoricalInformationPeriod>65535</HistoricalInformationPeriod>
+		<ListIssueDateTime>2022-09-27T00:00:00Z</ListIssueDateTime>
+		<NextUpdate>
+		  <dateTime>2023-12-27T00:00:00Z</dateTime>
+		</NextUpdate>
+	</SchemeInformation>
+	<TrustServiceProviderList>
+		<TrustServiceProvider>
+			<!-- 
+			<UID>
+				<Name xml:lang="en">2325</Name>
+			</UID>
+			-->
+			<TSPInformation>
+				<TSPName>
+					<Name xml:lang="en">Notary 1</Name>
+				</TSPName>
+				<TSPTradeName>
+					<Name xml:lang="en">NTRUK-SC090312</Name>
+					<Name xml:lang="en">Notary Federation 1 </Name>
+				</TSPTradeName>
+				<TSPAddress>
+					<PostalAddresses>
+						<PostalAddress xml:lang="en">
+							<StreetAddress>Lichtstraße 43h</StreetAddress>
+							<Locality>Köln</Locality>
+							<PostalCode>50825</PostalCode>
+							<CountryName>DE</CountryName>
+						</PostalAddress>
+					</PostalAddresses>
+					<ElectronicAddress>
+						<URI xml:lang="en">mailto:mail.notary1@federation.com</URI>
+					</ElectronicAddress>
+				</TSPAddress>
+				<TSPInformationURI>
+					<URI xml:lang="en">https://notary1.info/TRAIN/info</URI>
+				</TSPInformationURI>
+				<!-- 
+				<TSPCertificationList>
+					<TSPCertification xml:lang="en">
+						<Type>LEI</Type>
+						<Value>1234567</Value>
+						<Scope></Scope>
+					</TSPCertification>
+					<TSPCertification xml:lang="en">
+						<Type>Gaia-X Compliance</Type>
+						<Value>1234567</Value>
+						<Scope></Scope>
+					</TSPCertification>
+					<TSPCertification xml:lang="en">
+						<Type>eidas</Type>
+						<Value>1234567</Value>
+						<Scope></Scope>
+					</TSPCertification>
+				</TSPCertificationList>
+				-->
+			</TSPInformation>
+			<TSPServices>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>https://participant.membership.notary1.federation.com</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Federation Participant Membership Credential</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+						    <DigitalId><Other>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</Other></DigitalId>
+						    <!-- 
+							<x509>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</x509>
+							<did>did:web:notary.federation1.com</did>
+							-->
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted</ServiceStatus>
+						<StatusStartingTime>2022-09-29T22:00:00Z</StatusStartingTime>
+						<ServiceSupplyPoints>
+							<ServiceSupplyPoint>https://participant.membership.notary1.federation.com</ServiceSupplyPoint>
+						</ServiceSupplyPoints>
+						<TSPServiceDefinitionURI>
+							<URI xml:lang="en">https://notary1.info/schema/V-2022-1/participant_membership.json</URI>
+						</TSPServiceDefinitionURI>
+						<!-- 
+						<AdditionalServiceInformation>
+							<ServiceCredentialTypes>
+								<CredentialType>X.509</CredentialType>
+								<CredentialType>did:web</CredentialType>
+							</ServiceCredentialTypes>
+							<ServiceGovernanceURI>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceGovernanceURI>
+							<ServiceBusinessRules>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceBusinessRules>
+						</AdditionalServiceInformation>
+						-->
+					</ServiceInformation>
+				</TSPService>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>https://principal.membership.notary1.federation.com</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Federation Principal Credential</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+						    <DigitalId><Other>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</Other></DigitalId>
+						    <!-- 
+							<x509>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</x509>
+							<did>did:web:notary.federation1.com</did>
+							-->
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted</ServiceStatus>
+						<StatusStartingTime>2022-09-29T22:00:00Z</StatusStartingTime>
+						<ServiceSupplyPoints>
+							<ServiceSupplyPoint>https://verifier.research.identiproof.io/
+							</ServiceSupplyPoint>
+						</ServiceSupplyPoints>
+						<TSPServiceDefinitionURI>
+							<URI xml:lang="en">https://notary1.info/schema/V-2022-1/participant_membership.json</URI>
+						</TSPServiceDefinitionURI>
+						<!-- 
+						<AdditionalServiceInformation>
+							<ServiceCredentialTypes>
+								<CredentialType>X.509</CredentialType>
+								<CredentialType>did:web</CredentialType>
+							</ServiceCredentialTypes>
+							<ServiceGovernanceURI>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceGovernanceURI>
+							<ServiceBusinessRules>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceBusinessRules>
+						</AdditionalServiceInformation>
+						-->
+					</ServiceInformation>
+				</TSPService>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>https://consumer.membership.notary1.federation.com</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Federation Consumer Credential</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+						    <DigitalId><Other>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</Other></DigitalId>
+						    <!-- 
+							<x509>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</x509>
+							<did>did:web:notary.federation1.com</did>
+							-->
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted</ServiceStatus>
+						<StatusStartingTime>2022-09-29T22:00:00Z</StatusStartingTime>
+						<ServiceSupplyPoints>
+							<ServiceSupplyPoint>https://verifier.research.identiproof.io/</ServiceSupplyPoint>
+						</ServiceSupplyPoints>
+						<TSPServiceDefinitionURI>
+							<URI xml:lang="en">https://notary1.info/schema/V-2022-1/participant_membership.json</URI>
+						</TSPServiceDefinitionURI>
+						<!-- 
+						<AdditionalServiceInformation>
+							<ServiceCredentialTypes>
+								<CredentialType>X.509</CredentialType>
+								<CredentialType>did:web</CredentialType>
+							</ServiceCredentialTypes>
+							<ServiceGovernanceURI>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceGovernanceURI>
+							<ServiceBusinessRules>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceBusinessRules>
+						</AdditionalServiceInformation>
+						-->
+					</ServiceInformation>
+				</TSPService>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>https://resource.membership.notary1.federation.com</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Federation Resource Credential</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+						    <DigitalId><Other>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</Other></DigitalId>
+						    <!-- 
+							<x509>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</x509>
+							<did>did:web:notary.federation1.com</did>
+							-->
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted</ServiceStatus>
+						<StatusStartingTime>2022-09-29T22:00:00Z</StatusStartingTime>
+						<ServiceSupplyPoints>
+							<ServiceSupplyPoint>https://resource.membership.notary1.federation.com</ServiceSupplyPoint>
+						</ServiceSupplyPoints>
+						<TSPServiceDefinitionURI>
+							<URI xml:lang="en">https://notary1.info/schema/V-2022-1/participant_membership.json</URI>
+						</TSPServiceDefinitionURI>
+						<!-- 
+						<AdditionalServiceInformation>
+							<ServiceCredentialTypes>
+								<CredentialType>X.509</CredentialType>
+								<CredentialType>did:web</CredentialType>
+							</ServiceCredentialTypes>
+							<ServiceGovernanceURI>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceGovernanceURI>
+							<ServiceBusinessRules>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceBusinessRules>
+						</AdditionalServiceInformation>
+						-->
+					</ServiceInformation>
+				</TSPService>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>https://onboarding.membership.notary1.federation.com</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Federation Onboarding Credential</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+						    <DigitalId><Other>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</Other></DigitalId>
+						    <!-- 
+							<x509>242364735r634785634857348957349587395473957395739573932458743rz3ufgf3hrfv3hfv3hfv3hfv3hf</x509>
+							<did>did:web:notary.federation1.com</did>
+							-->
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted</ServiceStatus>
+						<StatusStartingTime>2022-09-29T22:00:00Z</StatusStartingTime>
+						<ServiceSupplyPoints>
+							<ServiceSupplyPoint>https://onboarding.membership.notary1.federation.com</ServiceSupplyPoint>
+						</ServiceSupplyPoints>
+						<TSPServiceDefinitionURI>
+							<URI xml:lang="en">https://notary1.info/schema/V-2022-1/participant_membership.json</URI>
+						</TSPServiceDefinitionURI>
+						<!-- 
+						<AdditionalServiceInformation>
+							<ServiceCredentialTypes>
+								<CredentialType>X.509</CredentialType>
+								<CredentialType>did:web</CredentialType>
+							</ServiceCredentialTypes>
+							<ServiceGovernanceURI>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceGovernanceURI>
+							<ServiceBusinessRules>https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32021R0953</ServiceBusinessRules>
+						</AdditionalServiceInformation>
+						-->
+					</ServiceInformation>
+				</TSPService>
+			</TSPServices>
+			<!-- 
+			<TSPCurrentStatus>
+				<Name xml:lang="en">Active</Name>
+			</TSPCurrentStatus>
+			-->
+			<!-- 
+			<StatusStartingTime>
+				<dateTime>2022-11-22T00:00:00Z</dateTime>
+			</StatusStartingTime>
+			-->
+		</TrustServiceProvider>
+	</TrustServiceProviderList>
+</TrustServiceStatusList>
\ No newline at end of file
diff --git a/service/src/test/resources/TL-21.xml b/service/src/test/resources/TL-21.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fed7309a67ce2487b167c5fe1c6e3604ec14ed6a
--- /dev/null
+++ b/service/src/test/resources/TL-21.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><TrustServiceStatusList xmlns="http://uri.etsi.org/02231/v2#" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://uri.etsi.org/02231/v2/additionaltypes#" xmlns:ns4="http://uri.etsi.org/01903/v1.3.2#" xmlns:ns5="http://uri.etsi.org/TrstSvc/SvcInfoExt/eSigDir-1999-93-EC-TrustedList/#" xmlns:ns6="http://uri.etsi.org/01903/v1.4.1#" Id="TL12345" TSLTag="http://uri.etsi.org/19612/TSLTag">
+    <SchemeInformation>
+        <TSLVersionIdentifier>5</TSLVersionIdentifier>
+        <TSLSequenceNumber>1</TSLSequenceNumber>
+        <TSLType>http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUgeneric</TSLType>
+        <SchemeOperatorName>
+            <Name xml:lang="en">LU Operator name</Name>
+        </SchemeOperatorName>
+        <SchemeOperatorAddress>
+            <PostalAddresses>
+                <PostalAddress xml:lang="en">
+                    <StreetAddress>TEST</StreetAddress>
+                    <Locality>TEST</Locality>
+                    <PostalCode>TEST</PostalCode>
+                    <CountryName>EU</CountryName>
+                </PostalAddress>
+            </PostalAddresses>
+            <ElectronicAddress>
+                <URI xml:lang="en">mailto:test@test.test</URI>
+            </ElectronicAddress>
+        </SchemeOperatorAddress>
+        <SchemeName>
+            <Name xml:lang="en">LU: TEST</Name>
+        </SchemeName>
+        <SchemeInformationURI>
+            <URI xml:lang="en">https://eidas.ec.europa.eu/efda/api/v2/validation-tests/testcase/test-disclaimer/</URI>
+        </SchemeInformationURI>
+        <StatusDeterminationApproach>https://eidas.ec.europa.eu/efda/api/v2/validation-tests/testcase/test-disclaimer/</StatusDeterminationApproach>
+        <SchemeTypeCommunityRules>
+            <URI xml:lang="en">http://uri.etsi.org/TrstSvc/TrustedList/schemerules/EUcommon</URI>
+            <URI xml:lang="en">http://uri.etsi.org/TrstSvc/TrustedList/schemerules/LU</URI>
+        </SchemeTypeCommunityRules>
+        <SchemeTerritory>LU</SchemeTerritory>
+        <PolicyOrLegalNotice>
+            <TSLLegalNotice xml:lang="en">TEST</TSLLegalNotice>
+        </PolicyOrLegalNotice>
+        <HistoricalInformationPeriod>65535</HistoricalInformationPeriod>
+        <PointersToOtherTSL>
+            <OtherTSLPointer>
+                <ServiceDigitalIdentities>
+                    <ServiceDigitalIdentity>
+                        <DigitalId>
+                            <X509Certificate>MIIDRjCCAi6gAwIBAgIBATANBgkqhkiG9w0BAQ0FADBVMRQwEgYDVQQDDAtDRVJULUxPVEwtMjEYMBYGA1UECgwPRVUgT3JnYW5pemF0aW9uMRYwFAYDVQQLDA1DRVJUIEZPUiBURVNUMQswCQYDVQQGEwJMVTAeFw0yMjExMTIwMDAwMDhaFw0yNDExMTIwMDAwMDhaMFUxFDASBgNVBAMMC0NFUlQtTE9UTC0yMRgwFgYDVQQKDA9FVSBPcmdhbml6YXRpb24xFjAUBgNVBAsMDUNFUlQgRk9SIFRFU1QxCzAJBgNVBAYTAkxVMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzy2BuWbXWS5L/xSdiz51KKncA04f8drUqjzAJeie2C7nsHdDJchmy+q5jwK6leCn1rNHpSaN9RZlHDrQb6TkDJ3QksCpQNZcVvxAafF//0MkJu9aSHOH5C7hLdM0TEVUz8DSbBQFqO81dh1zR148/r+wJ7E1ecth5N3f6xtkst1BiAfvGfLdfpc0T8cx+sKBBxRnfVBBTUR09XjJ8NSnsBA7ioGla6KlD/hBRkiGgJd4mOC4m5hrKvyxv4UXdciv2AF7FpO76bdwAdvXKUihye8KEj1kzRCOc30EVzxjTDYnWvaHIXsiwmCRvnLE3spgK+f6jWiQRWSfSgoY4W/pGQIDAQABoyEwHzAdBgNVHQ4EFgQUVR/75/0qY5gTPFwN3SA2OJepSegwDQYJKoZIhvcNAQENBQADggEBABB5ohWXYSeQscfdN1M4OJlnYxGNjrHwJrKwwRusTxr8m6n2aNErw0s6nNBt74gesLUmsQSF2sVa6+RqSZ5+ce9A/lQZgN1UsU4EQGZuyE+KaNHc3pmLkiCgdvpfWMh+bXGNqI9AzSoyx+qqGDc+Ylwj5Py2sJui+8qnNzcnfvYyIsSmRZVvILcnxoFHpnd8U7grhZxdodjAF1WqwWhZrzMJK6uaTKmVi0lHSrWpanj+zFzU1c5XNDGFH6U5JLF4zk9M4a+nv77vZJ46btbvoAQmtSayGm/reNVHhKyUkm8dgN36EuDCcl7c53MGtqquPUXQF9BhDy7JU5sdiMr6TWE=</X509Certificate>
+                        </DigitalId>
+                    </ServiceDigitalIdentity>
+                </ServiceDigitalIdentities>
+                <TSLLocation>https://eidas.ec.europa.eu/efda/api/v2/validation-tests/testcase/tl/LOTL-2.xml</TSLLocation>
+                <AdditionalInformation>
+                    <OtherInformation>
+                        <SchemeTerritory>EU</SchemeTerritory>
+                    </OtherInformation>
+                    <OtherInformation>
+                        <TSLType>http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUlistofthelists</TSLType>
+                    </OtherInformation>
+                    <OtherInformation>
+                        <SchemeOperatorName>
+                            <Name xml:lang="en">EU Operator name</Name>
+                        </SchemeOperatorName>
+                    </OtherInformation>
+                    <OtherInformation>
+                        <ns3:MimeType>application/vnd.etsi.tsl+xml</ns3:MimeType>
+                    </OtherInformation>
+                </AdditionalInformation>
+            </OtherTSLPointer>
+        </PointersToOtherTSL>
+        <ListIssueDateTime>2023-11-11T00:00:00Z</ListIssueDateTime>
+        <NextUpdate>
+            <dateTime>2023-12-13T00:00:00Z</dateTime>
+        </NextUpdate>
+    </SchemeInformation>
+    <TrustServiceProviderList>
+        <TrustServiceProvider>
+            <TSPInformation>
+                <TSPName>
+                    <Name xml:lang="en">TSP-21.1 Name</Name>
+                </TSPName>
+                <TSPTradeName>
+                    <Name xml:lang="en">TSP-21.1 Trade name</Name>
+                </TSPTradeName>
+                <TSPAddress>
+                    <PostalAddresses>
+                        <PostalAddress xml:lang="en">
+                            <StreetAddress>Street address</StreetAddress>
+                            <Locality>Locality</Locality>
+                            <StateOrProvince>Province</StateOrProvince>
+                            <PostalCode>123</PostalCode>
+                            <CountryName>LU</CountryName>
+                        </PostalAddress>
+                    </PostalAddresses>
+                    <ElectronicAddress>
+                        <URI xml:lang="en">mailto:test@test.test</URI>
+                    </ElectronicAddress>
+                </TSPAddress>
+                <TSPInformationURI>
+                    <URI xml:lang="en">http://tsp.information.uri/test</URI>
+                </TSPInformationURI>
+            </TSPInformation>
+            <TSPServices>
+                <TSPService>
+                    <ServiceInformation>
+                        <ServiceTypeIdentifier>http://uri.etsi.org/TrstSvc/Svctype/CA/QC</ServiceTypeIdentifier>
+                        <ServiceName>
+                            <Name xml:lang="en">TS-21.1.1 Name</Name>
+                        </ServiceName>
+                        <ServiceDigitalIdentity>
+                            <DigitalId>
+<X509Certificate>MIIDYTCCAkmgAwIBAgIBAzANBgkqhkiG9w0BAQsFADBSMRMwEQYDVQQDDApTREktMjEuMS4xMRYwFAYDVQQKDA1UU1AtMjEuMSBOYW1lMRYwFAYDVQQLDA1DRVJUIEZPUiBURVNUMQswCQYDVQQGEwJMVTAeFw0yMjExMTIwMDAwMDlaFw0yNDExMTIwMDAwMDlaMFIxEzARBgNVBAMMClNESS0yMS4xLjExFjAUBgNVBAoMDVRTUC0yMS4xIE5hbWUxFjAUBgNVBAsMDUNFUlQgRk9SIFRFU1QxCzAJBgNVBAYTAkxVMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhtsCMi4dNZ/1SlwL0F2S6LG5FKtviLxCIx6KsmQP7zFrcmEEG7wnr5QYN2uuTXuUtYaS6HoDJlC1RNuHPquBhhC1VQD2IqxnYW4TsyjkQml5Bw8R679nMlUgU8r+wloPq/5mExOz3pG29n/W1eJnm7yyCEnOMkLwxEzuBcVThJhNQd6XwImrYqZSjD85c9wtVrNemdIAgwZV14ICTs8jX6VgazPHl+NUSMBM2JS6aKlm1BkykOQe7SwHJymXSUKqaPprUugrFZDXF3QkkXfDLQlkRZXGd+Ig5UE9HGFfbBxkXVJp58v65AGIsURsxU4W00oznDzoAyVwCjLokNqcEQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFEHXjq4Qe9q4ukmHl2znE9NQjdc1MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEUa4NvQpRB2CD0qAOkrx3WwVVKREwx4LON4AjOxcfzmq3yI+/dtFHRY3Yy6EMErmuhpcnzG8Tzf48pE0gOGVXdu9FSk6/Zps4w2+bnvIQQfobRzPfjX6ntp1PQaT48lzw2NnNPjcW7ny4oHoCoERDAez6OfPzMFQwk+/nN5DQJXK6rQdmxLJr6AHjOvHGutV3gApN7etKJaK9lTmPcwogaQ69y71zwqHliXoJyfEqqu7L+lzCLEC8PLCkktR4YmqYrWTGEn4eJf6aNt/5EuY7Om6sCJZHl7LsfDXEWOy5w4hvATDIMubPjnnRnTEgr8qGs8Ph6f4/t016o4AkinFSc=</X509Certificate>
+                            </DigitalId>
+                            <DigitalId>
+<X509SubjectName>C=LU,OU=CERT FOR TEST,O=TSP-21.1 Name,CN=SDI-21.1.1</X509SubjectName>
+                            </DigitalId>
+                        </ServiceDigitalIdentity>
+                        <ServiceStatus>http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted</ServiceStatus>
+                        <StatusStartingTime>2016-06-30T22:00:00Z</StatusStartingTime>
+                        <ServiceInformationExtensions>
+                            <Extension Critical="true">
+<AdditionalServiceInformation>
+    <URI xml:lang="en">http://uri.etsi.org/TrstSvc/TrustedList/SvcInfoExt/ForeSignatures</URI>
+</AdditionalServiceInformation>
+                            </Extension>
+                        </ServiceInformationExtensions>
+                    </ServiceInformation>
+                </TSPService>
+            </TSPServices>
+        </TrustServiceProvider>
+    </TrustServiceProviderList>
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="id-aedb1ef81dba548eb80100d1c5849106"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference Id="xml_ref_id" URI=""><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>pDpTS8XpPc8n3sCRt3Wpuv9+8PfgOxM35omUzVtPULU=</ds:DigestValue></ds:Reference><ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xades-id-aedb1ef81dba548eb80100d1c5849106"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>cgJODlMb6hcakJaLY5zjS0sl8NXhqr+Q5/5w0lIS+Io=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue Id="value-id-aedb1ef81dba548eb80100d1c5849106">F4Pb2f8swSwL9p9E1tARyhor+15s7rc6PKRSDG6fEbwNHAEtrR5uCm9TDRQb0Gfk9rrMUrc+gK9QAmqz1VWOsz5IfAFOFvpUQHoQybp/EtmoUnfiZlr3E8OsJjhYOnqu/EqibSPegBtiKzdRnKI45VH409wrv7mciNZ3bhvPkOgKcXgdchIuRkjYFXz+y1K17vwyyx7FOF9Iy+AtWEacxp3figLktc92d37xW171e1ZZcVuCiH1NCaiNdmEjb6qiUb1VTpAjKdJaZbLudxAfZVYvZI2dGPinxva2fegGwTPgldqKI6vhLkXRnL2OePIPyRM48Q4qr+FiVeTZzGimXg==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDVDCCAjygAwIBAgIBAjANBgkqhkiG9w0BAQ0FADBcMRkwFwYDVQQDDBBDRVJULVRMLTIxLVdST05HMRowGAYDVQQKDBFUTDIxIE9yZ2FuaXphdGlvbjEWMBQGA1UECwwNQ0VSVCBGT1IgVEVTVDELMAkGA1UEBhMCTFUwHhcNMjIxMTEyMDAwMDA4WhcNMjQxMTEyMDAwMDA4WjBcMRkwFwYDVQQDDBBDRVJULVRMLTIxLVdST05HMRowGAYDVQQKDBFUTDIxIE9yZ2FuaXphdGlvbjEWMBQGA1UECwwNQ0VSVCBGT1IgVEVTVDELMAkGA1UEBhMCTFUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDezi/F/qxz3atjE7o3fJl9+WXIGBVt4/j+HoBh8a4Hd1KQxy/PmFctfW/xtLmjHzY6RPz8s/vGat+yC2LOnxrQ6vrjFJfe2Z1SuBLcqB57icTLjwNjEpCOw7IaB8WElDtAxpyPauQ8iFFdTeSJNY/hhvTKwaI4YTXaeO2mxoQ5/QMniYcxpvcStSlejXqXVMaN+JLLAvNJaxVlDuaOPvN6CsDlPKVdNOmlIrWthJjw0x1VwmzLfhHJkFsE2CIM68sJ4jj38tyfdpjXFXBpCNkLkvkMO/wKRHMszHBpcJQCkoQ8Mjb5WQ7WPEwsvo4mQEbFMM67GVi+13Xxf1TrwkVnAgMBAAGjITAfMB0GA1UdDgQWBBQnDCTRgW2Hs9c08sNDMTLU4vKpmjANBgkqhkiG9w0BAQ0FAAOCAQEALFKFfec2uElYiTCwoH/otOoeJTh1O/hg2oLbmNX4mRjGx9l3ancMBV+0zl6YJ3EhudXOfB5SBlLwg9gYmyyx2dpVLXSHWKG2Vku9bW9G4ZpgYXFHfvDia+G/ktrTVzUHIGADt6IZ+LoBI7K/t9dX26PaNPglXha0Ct/ygpDLtEnO9UhPLAqKy48R5ik/QQJ1y6dTjbw/JzfgRuUHx7/VqWMfmZqSHzofm6AN4wkSKyUbR9uC/RbT3Lc0hslbJEXiKwGsh5skgu0Bg1x2Fumt1H3rdbKfpYStghGPJeJWRaAtGVkpLEp114zukFxCsN4a6IuqvlrYM3lDFP7meBXcRQ==</ds:X509Certificate></ds:X509Data></ds:KeyInfo><ds:Object><xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Target="#id-aedb1ef81dba548eb80100d1c5849106"><xades:SignedProperties Id="xades-id-aedb1ef81dba548eb80100d1c5849106"><xades:SignedSignatureProperties><xades:SigningTime>2023-11-12T00:01:00Z</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/><ds:DigestValue>3rdRffkS4baRCjG5xLatj5+wKjasfamCnyTKyZ8g14rDkZgUG52j71TsRiqBMgdRfTZGw2eACHNXQUDV4322zw==</ds:DigestValue></xades:CertDigest><xades:IssuerSerial><ds:X509IssuerName>C=LU,OU=CERT FOR TEST,O=TL21 Organization,CN=CERT-TL-21-WRONG</ds:X509IssuerName><ds:X509SerialNumber>2</ds:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate></xades:SignedSignatureProperties><xades:SignedDataObjectProperties><xades:DataObjectFormat ObjectReference="#xml_ref_id"><xades:MimeType>application/octet-stream</xades:MimeType></xades:DataObjectFormat></xades:SignedDataObjectProperties></xades:SignedProperties></xades:QualifyingProperties></ds:Object></ds:Signature></TrustServiceStatusList>
\ No newline at end of file
diff --git a/service/src/test/resources/application.yml b/service/src/test/resources/application-test.yml
similarity index 82%
rename from service/src/test/resources/application.yml
rename to service/src/test/resources/application-test.yml
index 379b9d2abcbaa5314741fe0f18d1f4a1fb78da12..169958cbff002904c7889d638a32179b363df4c0 100644
--- a/service/src/test/resources/application.yml
+++ b/service/src/test/resources/application-test.yml
@@ -9,8 +9,9 @@ tcr:
   dns:
     hosts:
     timeout: 2000
-    verification:
-      enabled: false  
+    dnssec:
+      enabled: true
+        
   http:
     timeout: 10
     
\ No newline at end of file
diff --git a/service/src/test/resources/schuelerausweis.xml b/service/src/test/resources/schuelerausweis.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9931ed119c42c60265ff1a2d565bda8e1c516636
--- /dev/null
+++ b/service/src/test/resources/schuelerausweis.xml
@@ -0,0 +1,323 @@
+<TrustServiceStatusList
+	xmlns="http://uri.etsi.org/02231/v2#"
+	xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"
+	xmlns:ns3="http://uri.etsi.org/01903/v1.3.2#"
+	xmlns:ns4="http://uri.etsi.org/02231/v2/additionaltypes#"
+	xmlns:ns5="http://uri.etsi.org/TrstSvc/SvcInfoExt/eSigDir-1999-93-EC-TrustedList/#"
+	xmlns:ns6="http://uri.etsi.org/01903/v1.4.1#"
+	TSLTag="http://uri.etsi.org/19612/TSLTag">
+	<SchemeInformation>
+		<TSLVersionIdentifier>5</TSLVersionIdentifier>
+		<TSLSequenceNumber>1</TSLSequenceNumber>
+		<TSLType>http://uri.etsi.org/TrstSvc/TrustedList/TSLType/EUgeneric</TSLType>
+		<SchemeOperatorName>
+			<Name xml:lang="en">ONCE</Name>
+		</SchemeOperatorName>
+		<SchemeOperatorAddress>
+			<PostalAddresses>
+				<PostalAddress xml:lang="de">
+				    <StreetAddress>somewhere in Deutschland</StreetAddress>
+				    <Locality>Deutschland</Locality>
+					<PostalCode>111111</PostalCode>
+					<CountryName>DE</CountryName>
+				</PostalAddress>
+			</PostalAddresses>
+			<ElectronicAddress>
+				<URI xml:lang="en">mailto:alice@TrustSchemeESSIF_TRAIN.example.com</URI>
+				<URI xml:lang="en">https://TrustSchemeESSIF_TRAIN.example.com/Servicemenu/English</URI>
+			</ElectronicAddress>
+		</SchemeOperatorAddress>
+		<SchemeName>
+			<Name xml:lang="en">Trust Scheme ONCE Example: Trusted list including information related to the qualified schools under ONCE ecosystem</Name>
+		</SchemeName>
+		<SchemeInformationURI>
+			<URI xml:lang="en">https://TrustSchemeESSIF_TRAIN.example.com/en/tsl_e.htm</URI>
+		</SchemeInformationURI>
+		<StatusDeterminationApproach>test</StatusDeterminationApproach>
+		<SchemeTypeCommunityRules>
+			<URI xml:lang="en">https://TrustSchemeESSIF_TRAIN.example.com/en/schemerules.xml</URI>
+		</SchemeTypeCommunityRules>
+		<SchemeTerritory>Deutschland</SchemeTerritory>
+		<PolicyOrLegalNotice>
+			<TSLLegalNotice xml:lang="en">The applicable legal framework for the present trusted list is ONCE Regulation No ??.</TSLLegalNotice>
+		</PolicyOrLegalNotice>
+		<HistoricalInformationPeriod>65535</HistoricalInformationPeriod>
+		<ListIssueDateTime>2019-01-01T00:00:00Z</ListIssueDateTime>
+		<NextUpdate>
+			<dateTime>2021-01-01T00:00:00Z</dateTime>
+		</NextUpdate>
+		<DistributionPoints>
+			<URI>https://TrustSchemeESSIF_TRAIN.example.com/trust-list.xml</URI>
+		</DistributionPoints>
+	</SchemeInformation>
+	<TrustServiceProviderList>
+		<TrustServiceProvider>
+			<TSPInformation>
+				<TSPName>
+					<Name xml:lang="en">MusterMann Schule</Name>
+				</TSPName>
+				<TSPTradeName>
+					<Name xml:lang="en">VAT-11111111</Name>
+				</TSPTradeName>
+				<TSPAddress>
+					<PostalAddresses>
+						<PostalAddress xml:lang="en">
+							<StreetAddress>Hauptstr 7</StreetAddress>
+				            <Locality>Deutschland</Locality>
+							<PostalCode>70569</PostalCode>
+							<CountryName>DE</CountryName>
+						</PostalAddress>
+					</PostalAddresses>
+					<ElectronicAddress>
+						<URI xml:lang="en">https://www.schule.example.com/en/</URI>
+						<URI xml:lang="en">mailto:info@schule.example.com</URI>
+					</ElectronicAddress>
+				</TSPAddress>
+				<TSPInformationURI>
+					<URI xml:lang="en">https://www.schule.example.com/en/info</URI>
+				</TSPInformationURI>
+				<!-- 
+				<IssuerName>
+					<Name xml:lang="en">did:jolo:3eda3790b040704ba8b8b30534874d692de25deeffb7ef46f0cd99c6543afdc3</Name>
+				</IssuerName>
+				-->
+			</TSPInformation>
+			<TSPServices>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>http://TrustSchemeschule.example.com/ServiceTypes/thirdparties/
+						</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">schuelersusweis</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+							<DigitalId>
+								<X509Certificate>MIIEETCCAvmgAwIBAgIEAVTL9zANBgkqhkiG9w0BAQ0FADBkMQwwCgYDVQQDEwNtZWExMjAwBgNVBAoTKVVuaXRlZCBO</X509Certificate>
+							</DigitalId>
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://TrustSchemeESSIF_TRAIN.example.com/ServiceTypes/Servicestatus/granted/</ServiceStatus>
+						<StatusStartingTime>2019-01-01T00:00:00Z</StatusStartingTime>
+					</ServiceInformation>
+				</TSPService>
+			</TSPServices>
+		</TrustServiceProvider>
+		<TrustServiceProvider>
+			<TSPInformation>
+				<TSPName>
+					<Name xml:lang="de">regio iT Demo-1: Gymnasium an der Gartenstraße (MG)</Name>
+				</TSPName>
+				<!--
+				<IssuerName>
+					<Name xml:lang="en">M5kPLHELwtS4Lxrmw2mAKG</Name>
+				</IssuerName>
+				-->
+				<TSPTradeName>
+					<Name xml:lang="en">VAT-11111111</Name>
+				</TSPTradeName>
+				<TSPAddress>
+					<PostalAddresses>
+						<PostalAddress xml:lang="en">
+							<StreetAddress>Hauptstr 7</StreetAddress>
+							<Locality>Deutschland</Locality>
+							<PostalCode>70569</PostalCode>
+							<CountryName>DE</CountryName>
+						</PostalAddress>
+					</PostalAddresses>
+					<ElectronicAddress>
+						<URI xml:lang="en">https://www.schule.example.com/en/</URI>
+						<URI xml:lang="en">mailto:info@schule.example.com</URI>
+					</ElectronicAddress>
+				</TSPAddress>
+				<TSPInformationURI>
+					<URI xml:lang="en">https://www.schule.example.com/en/info</URI>
+				</TSPInformationURI>
+			</TSPInformation>
+			<TSPServices>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>http://TrustSchemeschule.example.com/ServiceTypes/thirdparties/</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Demo-1</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+							<DigitalId>
+								<X509Certificate>MIIEETCCAvmgAwIBAgIEAVTL9zANBgkqhkiG9w0BAQ0FADBkMQwwCgYDVQQDEwNtZWExMjAwBgNVBAoTKVVuaXRlZCBO</X509Certificate>
+							</DigitalId>
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://TrustSchemeESSIF_TRAIN.example.com/ServiceTypes/Servicestatus/granted/</ServiceStatus>
+						<StatusStartingTime>2019-01-01T00:00:00Z</StatusStartingTime>
+					</ServiceInformation>
+				</TSPService>
+			</TSPServices>
+		</TrustServiceProvider>
+		<TrustServiceProvider>
+			<TSPInformation>
+				<TSPName>
+					<Name xml:lang="en">regio iT DEV</Name>
+				</TSPName>
+				<!-- 
+				<IssuerName>
+					<Name xml:lang="en">Przc8rbKzWrteKvPH4pGvT</Name>
+				</IssuerName>
+				-->
+				<TSPTradeName>
+					<Name xml:lang="en">VAT-11111111</Name>
+				</TSPTradeName>
+				<TSPAddress>
+					<PostalAddresses>
+						<PostalAddress xml:lang="en">
+							<StreetAddress>Hauptstr 7</StreetAddress>
+ 				            <Locality>Deutschland</Locality>
+							<PostalCode>70569</PostalCode>
+							<CountryName>DE</CountryName>
+						</PostalAddress>
+					</PostalAddresses>
+					<ElectronicAddress>
+						<URI xml:lang="en">https://www.schule.example.com/en/</URI>
+						<URI xml:lang="en">mailto:info@schule.example.com</URI>
+					</ElectronicAddress>
+				</TSPAddress>
+				<TSPInformationURI>
+					<URI xml:lang="en">https://www.schule.example.com/en/info</URI>
+				</TSPInformationURI>
+			</TSPInformation>
+			<TSPServices>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>http://TrustSchemeschule.example.com/ServiceTypes/thirdparties/
+						</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">DEV</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+							<DigitalId>
+								<X509Certificate>MIIEETCCAvmgAwIBAgIEAVTL9zANBgkqhkiG9w0BAQ0FADBkMQwwCgYDVQQDEwNtZWExMjAwBgNVBAoTKVVuaXRlZCBO</X509Certificate>
+							</DigitalId>
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://TrustSchemeESSIF_TRAIN.example.com/ServiceTypes/Servicestatus/granted/
+						</ServiceStatus>
+						<StatusStartingTime>2019-01-01T00:00:00Z</StatusStartingTime>
+					</ServiceInformation>
+				</TSPService>
+			</TSPServices>
+		</TrustServiceProvider>
+		<TrustServiceProvider>
+			<TSPInformation>
+				<TSPName>
+					<Name xml:lang="en">regio iT Demo-2: Mönchengladbach-Ausweis</Name>
+				</TSPName>
+				<!-- 
+				<IssuerName>
+					<Name xml:lang="en">2MiHNdshRpfShqxk3g8gGd</Name>
+				</IssuerName>
+				-->
+				<TSPTradeName>
+					<Name xml:lang="en">VAT-11111111</Name>
+				</TSPTradeName>
+				<TSPAddress>
+					<PostalAddresses>
+						<PostalAddress xml:lang="en">
+							<StreetAddress>Hauptstr 7</StreetAddress>
+				            <Locality>Deutschland</Locality>
+							<PostalCode>70569</PostalCode>
+							<CountryName>DE</CountryName>
+						</PostalAddress>
+					</PostalAddresses>
+					<ElectronicAddress>
+						<URI xml:lang="en">https://www.schule.example.com/en/</URI>
+						<URI xml:lang="en">mailto:info@schule.example.com</URI>
+					</ElectronicAddress>
+				</TSPAddress>
+				<TSPInformationURI>
+					<URI xml:lang="en">https://www.schule.example.com/en/info</URI>
+				</TSPInformationURI>
+			</TSPInformation>
+			<TSPServices>
+				<TSPService>
+					<ServiceInformation>
+						<ServiceTypeIdentifier>http://TrustSchemeschule.example.com/ServiceTypes/thirdparties/
+						</ServiceTypeIdentifier>
+						<ServiceName>
+							<Name xml:lang="en">Demo-2</Name>
+						</ServiceName>
+						<ServiceDigitalIdentity>
+							<DigitalId>
+								<X509Certificate>MIIEETCCAvmgAwIBAgIEAVTL9zANBgkqhkiG9w0BAQ0FADBkMQwwCgYDVQQDEwNt
+									ZWExMjAwBgNVBAoTKVVuaXRlZCBO </X509Certificate>
+							</DigitalId>
+						</ServiceDigitalIdentity>
+						<ServiceStatus>http://TrustSchemeESSIF_TRAIN.example.com/ServiceTypes/Servicestatus/granted/
+						</ServiceStatus>
+						<StatusStartingTime>2019-01-01T00:00:00Z</StatusStartingTime>
+					</ServiceInformation>
+				</TSPService>
+			</TSPServices>
+		</TrustServiceProvider>
+	</TrustServiceProviderList>
+	<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="id-f77bf9f6605f3e0a6f15785801da6e08">
+		<ds:SignedInfo>
+			<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+			<ds:SignatureMethod	Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
+			<ds:Reference Id="r-id-f77bf9f6605f3e0a6f15785801da6e08-1" URI="">
+				<ds:Transforms>
+					<ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
+						<ds:XPath>not(ancestor-or-self::ds:Signature)</ds:XPath>
+					</ds:Transform>
+					<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+				</ds:Transforms>
+				<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+				<ds:DigestValue>sG//6RNhH+mjxPuE4sFgjjsU5rQvoh8kKOiOVmPlhBg=</ds:DigestValue>
+			</ds:Reference>
+			<ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xades-id-f77bf9f6605f3e0a6f15785801da6e08">
+				<ds:Transforms>
+					<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+				</ds:Transforms>
+				<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+				<ds:DigestValue>qFuTow4cFrzFCuPugWRMrJiofYMPkolxeaRFSb6Ip5c=</ds:DigestValue>
+			</ds:Reference>
+		</ds:SignedInfo>
+		<ds:SignatureValue
+			Id="value-id-f77bf9f6605f3e0a6f15785801da6e08">mCAOTSzddi5e8sQzHEvyo2mwmTfGTmT1Kd/0I3+rz4aM/BkBEAJ0AE1x6Nk+mVU2/y6+iQElOm2TNwfcyMRuG+kSBPLsgCjXWzi0Uhikh5t3gvtrvguOAsM/Xih5VjMSthIoAL2CZMLi+vPsdmYixfvHeVl96udO/P/wYgTrFR5jn8lkQRsYs8+m810fozOm+zLm+j92jcBp1xJhwNqyNHIgiLWOnWhrUYSD9tY5be+moqZQYbi6EWxCH1Em9soa+2eUrFxZ1nQZosUqhzsTV2jV9xqIFECyxOfCNwACtOU4ATH0dbfSwIOqzvnLlWCjbPF8VKdZz4uOpRnZXDkMAw==
+		</ds:SignatureValue>
+		<ds:KeyInfo>
+			<ds:X509Data>
+				<ds:X509Certificate>MIIEETCCAvmgAwIBAgIEAVTL9zANBgkqhkiG9w0BAQ0FADBkMQwwCgYDVQQDEwNtZWExMjAwBgNVBAoTKVVuaXRlZCBOYXRpb25hbCBPcmdhbml6YXRpb24gZm9yIHJlZnVnZWVzMRMwEQYDVQQHEwpDb3BlbmhhZ2VuMQswCQYDVQQGEwJETjAeFw0yMDAxMDkwOTA5MDFaFw0yNjExMTMwOTA5MDFaMGcxDzANBgNVBAMTBmpvcmRhbjEyMDAGA1UEChMpVW5pdGVkIE5hdGlvbmFsIE9yZ2FuaXphdGlvbiBmb3IgcmVmdWdlZXMxEzARBgNVBAcTCkNvcGVuaGFnZW4xCzAJBgNVBAYTAkROMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArxj4uGQWD1Wl9d0FuraCTi7iZ50GSk9vyPUdQZGCqGOYeXGNF8GqNthXAQJVB7vs7J5GTa/bSezGOevvS3wYTHMMWYXvT3FdhmyD+2bpnrHy+UkRNh69d5KBb23Ih+cK7ReTqGCTMZ50Q/Dg7qMru1Z7nAM0qHqewhZuT/OCcRI0ycoDeJz4620Jd19db8D0FCAQntWkOtIAIZKn92B8IyjjQi7ddk9Z4w5lz4M3SSjzOi4DQ/SBzstf0VbB9S+HabGA3byqLLNX5o5z/qfNNWXSim8tZsNyj6W19zobKsVwmYSTmw3gJPooQ696vIMyz5Q3DiQcOJyf8kQy8XVVgwIDAQABo4HHMIHEMB8GA1UdIwQYMBaAFFbgaDVQP34mJ9fXiPJS27XmuDQnMA8GA1UdEwQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgK0MDEGA1UdEQQqMCiCJmpvcmRhbi5kYWZpLWRlbW8ubGlnaHRlc3QubmxuZXRsYWJzLm5sMC4GA1UdEgQnMCWCI21lYS5kYWZpLWRlbW8ubGlnaHRlc3QubmxuZXRsYWJzLm5sMB0GA1UdDgQWBBTmGg8mcxog22WBsNhFKHqkAGlL6TANBgkqhkiG9w0BAQ0FAAOCAQEAOEaGtiZ8axLodER8m3FpCC6y83Q8DQVFdhmmslULf6MW9C18Fdk6MH5On3Hkm+qmLR6a55cENuDAGgIoczGlyeYFBndypQJfp2SZK1SKXR5hb0HspCo5FOW8bdqJivVjLbaW/aF4MOzhHJzlRkeJbP2clq7LD1M16bASEnB35kwksbWQRN6WQqKVzot8zd11xiWMFUpbSVRlX8Jb62jCMwC/nt0p4JCJ+8ETVtnKf88IGAVShZ+4tt/J42SjuNT8CB3St7iRGZmE1iuE2AeVfD8V1N17GItlOXy9FQ6RgqlU01SORu2uV3xqzTTxIcsEY/DO99PfEtexrW4hFSNarA==
+				</ds:X509Certificate>
+				<ds:X509Certificate>MIIEDzCCAvegAwIBAgIEBTl/sTANBgkqhkiG9w0BAQ0FADBmMQ4wDAYDVQQDEwV1bmhjcjEyMDAGA1UEChMpVW5pdGVkIE5hdGlvbmFsIE9yZ2FuaXphdGlvbiBmb3IgcmVmdWdlZXMxEzARBgNVBAcTCkNvcGVuaGFnZW4xCzAJBgNVBAYTAkROMB4XDTIwMDEwOTA5MDkwMVoXDTI2MTExMzA5MDkwMVowZDEMMAoGA1UEAxMDbWVhMTIwMAYDVQQKEylVbml0ZWQgTmF0aW9uYWwgT3JnYW5pemF0aW9uIGZvciByZWZ1Z2VlczETMBEGA1UEBxMKQ29wZW5oYWdlbjELMAkGA1UEBhMCRE4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIB+VYoqe9r2aFxQMoyuONIXZgO2xnprEnn/RPLikvnAulX/xYMFpcU0SSbopfsdK/XMQiFIFmAO5GjcEqIV+WQ84NlQsTBd+I/VnGwLje4JH9Hc3ppj4xuaBzaX8wiXqoBQtV8Y9LlicRenvaBM29li3CvqLdONOeIUgAH8VF5d3YNmXGWoyIuZv9sruebnrGajjgU2xP0fUdexBx1LbpaafhoSy1KcER0B0PTyofdSR5CV3exwiRUuS48sob/I0IdrJVAPqKmWrosXha+Xj6ejZU473XnPBii6KZlZhOMv0ht29kOixM+5sttswGxP9poraiE1r5yYBC4hV1RcrPAgMBAAGjgcYwgcMwHwYDVR0jBBgwFoAUoI1m4qYD7gRYZQ+sDjyHGqmfRS0wDwYDVR0TBAgwBgEB/wIBAzAOBgNVHQ8BAf8EBAMCArQwLgYDVR0RBCcwJYIjbWVhLmRhZmktZGVtby5saWdodGVzdC5ubG5ldGxhYnMubmwwMAYDVR0SBCkwJ4IldW5oY3IuZGFmaS1kZW1vLmxpZ2h0ZXN0Lm5sbmV0bGFicy5ubDAdBgNVHQ4EFgQUVuBoNVA/fiYn19eI8lLbtea4NCcwDQYJKoZIhvcNAQENBQADggEBAGGLS7+TZGI0pJKg6TOzu5YjDvlaobwKbjpgMWTFvaC1wJJkPZpBXBUmcvef/d4sJjI+6o/4y13LxEeMZGt+7ORJ+D+gvwdZS3KUIRegn77UzIBef/eplwIUBnzNIRV0p2nuMMDQPyzPg+DogvYzoFVZmfXyv5zWsfPwetMTARILKd42QAprGe/3NwhMOTHghE7ejlpfeUFbTCemmxZMZJku4tw1Qzoqd70G64GXahyawigrGK8Up/HXjK3L1Xy8+ED71YGnHIgosoeLGioemzT5lFTKgudefZ41TSaY2sT/CEuc3cCTutVPIiVjDHIaFeI5pa/zsnOJ3a71+T2iXKY=
+				</ds:X509Certificate>
+				<ds:X509Certificate>MIID7DCCAtSgAwIBAgIEALxhTjANBgkqhkiG9w0BAQ0FADBmMQ4wDAYDVQQDEwV1bmhjcjEyMDAGA1UEChMpVW5pdGVkIE5hdGlvbmFsIE9yZ2FuaXphdGlvbiBmb3IgcmVmdWdlZXMxEzARBgNVBAcTCkNvcGVuaGFnZW4xCzAJBgNVBAYTAkROMB4XDTIwMDEwOTA5MDkwMVoXDTI2MTExMzA5MDkwMVowZjEOMAwGA1UEAxMFdW5oY3IxMjAwBgNVBAoTKVVuaXRlZCBOYXRpb25hbCBPcmdhbml6YXRpb24gZm9yIHJlZnVnZWVzMRMwEQYDVQQHEwpDb3BlbmhhZ2VuMQswCQYDVQQGEwJETjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJLCCpTbuaZtpf/CDwxK70ijUnzaJARx2Oyw0KAS0FXlnF614PO1m2mgCvWYLoOoTAzA4wNPUrkvtRHmblKs5n6dyRDp8d8Yl27gocjPHtTjjUoTe+EwpMWLUSa41n/8AMZ3mLRRQnWk8mZSntQzmiox1fIxV4f8aJqwwXdly1uCfBjbBLotWZ2fFyb/VocUDf6n4DJK2W9gwuxcCd6n8koFwgfH6D2Z54f5LUfkzvJwAZxAzSsb8VuzGVcNbmXvfKuKL94dZ/R7wJG+J28bVWyHLxvYK4q911s+Q88vBw0zOhIIO3hF8tL2n0qrEL+nxRMjM4nMScHWDDy7pwqwcX8CAwEAAaOBoTCBnjAfBgNVHSMEGDAWgBSgjWbipgPuBFhlD6wOPIcaqZ9FLTAPBgNVHRMECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwICtDAwBgNVHREEKTAngiV1bmhjci5kYWZpLWRlbW8ubGlnaHRlc3QubmxuZXRsYWJzLm5sMAkGA1UdEgQCMAAwHQYDVR0OBBYEFKCNZuKmA+4EWGUPrA48hxqpn0UtMA0GCSqGSIb3DQEBDQUAA4IBAQAm0i8U88wODD0rThZVCFVtLs8oGwXvulrhpIPeduVTI0Z+7/vblBYrAJp8IsGTk/VmLfi31oY+o1Q+qJq1giuQlyRwuCkGoQgDdzSzbcUpm4l3GRIzDDHsK54OqMxXHuZyvT+3eJwrx+tN7TDn+Rf94J8d0bs4Hy30GoVmNe4nEdPUuMtVPL54//X/Mkr56Ul2+qtv9D8nPSD+chHEAUizlt0yfGsSq+f3hc63DXZIqh2E9YgZqKIrmRfQXF6Nb4D9QrK0pmz0NJ6umcvfBIbEYz1VSNdUfHw7C9zfc5VUan9+PKXxft3kQXylN8ZeInmhwu4sMTr/zRQL0C6BtNMx
+				</ds:X509Certificate>
+			</ds:X509Data>
+		</ds:KeyInfo>
+		<ds:Object>
+			<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Target="#id-f77bf9f6605f3e0a6f15785801da6e08">
+				<xades:SignedProperties Id="xades-id-f77bf9f6605f3e0a6f15785801da6e08">
+					<xades:SignedSignatureProperties>
+						<xades:SigningTime>2020-01-09T17:04:34Z</xades:SigningTime>
+						<xades:SigningCertificate>
+							<xades:Cert>
+								<xades:CertDigest>
+									<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
+									<ds:DigestValue>rgs+nklEAZB0nfaXoxixYEbMe8gU7ElHQaNuWKsW8UUXJgVtJM6gXd/DKSOxdPhcTEEhS8/d3o92qSUNyS6C0A==</ds:DigestValue>
+								</xades:CertDigest>
+								<xades:IssuerSerial>
+								    <ds:X509IssuerName>MHAwaKRmMGQxDDAKBgNVBAMTA21lYTEyMDAGA1UEChMpVW5pdGVkIE5hdGlvbmFsIE9yZ2FuaXphdGlvbiBmb3IgcmVmdWdlZXMxEzARBgNVBAcTCkNvcGVuaGFnZW4xCzAJBgNVBAYTAkROAgQBVMv3</ds:X509IssuerName>
+								    <ds:X509SerialNumber>123</ds:X509SerialNumber>
+								</xades:IssuerSerial>
+							</xades:Cert>
+						</xades:SigningCertificate>
+						<xades:SignaturePolicyIdentifier>
+							<xades:SignaturePolicyImplied />
+						</xades:SignaturePolicyIdentifier>
+						<xades:SignatureProductionPlace />
+					</xades:SignedSignatureProperties>
+					<xades:SignedDataObjectProperties>
+						<xades:DataObjectFormat ObjectReference="#r-id-f77bf9f6605f3e0a6f15785801da6e08-1">
+							<xades:MimeType>text/xml</xades:MimeType>
+						</xades:DataObjectFormat>
+					</xades:SignedDataObjectProperties>
+				</xades:SignedProperties>
+			</xades:QualifyingProperties>
+		</ds:Object>
+	</ds:Signature>
+</TrustServiceStatusList>