diff --git a/README.md b/README.md
index da736d550..4f8b79388 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,13 @@ Please be aware, that versions starting from 4.1.3 are __NOT__ backwards compati
        * [Service Description Overview](#datamanager_provided_services)
        * [Endpoints](#datamanager_endpoints)
 	       * [Client](#datamanager_endpoints_client)
-    8. [Certificate Authority](#ca)
+    8. [TimeManager](#timemanager)
+       * [System Design Description Overview](#timemanager_sdd)
+       * [Services and Use Cases](#timemanager_usecases)  
+       * [Service Description Overview](#timemanager_provided_services)
+       * [Endpoints](#timemanager_endpoints)
+	       * [Client](#timemanager_endpoints_client)
+    9. [Certificate Authority](#ca)
        * [System Design Description Overview](#ca_sdd)
        * [Services and Use Cases](#ca_usecases)  
        * [Endpoints](#ca_endpoints)
@@ -268,6 +274,7 @@ Authorization will be available on ```https://localhost:8445``` <br />
 Orchestrator will be available on ```https://localhost:8441``` <br />
 Event Handler will be available on ```https://localhost:8455``` <br />
 DataManager will be available on ```https://localhost:8461``` <br />
+TimeManager will be available on ```https://localhost:8463``` <br />
 Gatekeeper will be available on ```https://localhost:8449``` <br />
 Gateway will be available on ```https://localhost:8453``` <br />
 
@@ -4808,11 +4815,6 @@ This service can only be used by other core services, therefore this is not part
 
 The purpose of DataManager supporting core system is to provide storage of sensor data.
 
-![#1589F0](https://placehold.it/15/1589F0/000000?text=+) `AH Service Registry`
-![#f03c15](https://placehold.it/15/f03c15/000000?text=+) `AH Authorization` 
-![#c5f015](https://placehold.it/15/c5f015/000000?text=+) `AH Orchestrator`
-![#ffcc44](https://placehold.it/15/ffcc44/000000?text=+) `AH DataManager`
-![Alt text](/documentation/datamanager/overview.png)
 
 The DataManager provides features for producers and consumers to:
 * Store SenML sensor and actuator data,
@@ -4859,7 +4861,7 @@ The DataManager has the following use cases:
 Swagger API documentation is available on: `https://<host>:<port>` <br />
 The base URL for the requests: `http://<host>:<port>/datamanager`
 
-
+<a name="datamanager_endpoints_client" />
 
 ### Client endpoint description<br />
 
@@ -4884,8 +4886,6 @@ GET /datamanager/echo
 
 Returns a "Got it!" message with the purpose of testing the system availability.
 
-<a name="datamanager_endpoints_client" />
-
 <a name="datamanager_proxyendpoints_getsys" />
 
 ### Get system list
@@ -4944,20 +4944,20 @@ __GetServiceDataResponse__ output:
 ```json
 
 [
-   {
+  {
     "bn": "string",
-	  "bt": 0.0,
-	  "bu": "string",
-	  "bver": 0
-   }, {
+    "bt": 0.0,
+    "bu": "string",
+    "bver": 0
+  }, {
     "n": "string",
-	  "t": 0.0,
-	  "u": "string",
-	  "v": 0.0,
-	  "vs": "string",
-	  "vb": false,
-	  "vd": "string"
-   }
+    "t": 0.0,
+    "u": "string",
+    "v": 0.0,
+    "vs": "string",
+    "vb": false,
+    "vd": "string"
+  }
 ]
 ```
 
@@ -4972,25 +4972,25 @@ Stores sensor data in a service endpoint in the proxy cache.
 
 <a name="datamanager_putsrvdata_request" />
 
-__PutSServiceDataRequest__ input:
+__PutServiceDataRequest__ input:
 
 ```json
 
 [
-   {
+  {
     "bn": "string",
-	  "bt": 0.0,
-	  "bu": "string",
-	  "bver": 0
-    }, {
-     "n": "string",
-	   "t": 0.0,
-	   "u": "string",
-	   "v": 0.0,
-	   "vs": "string",
-	   "vb": false,
-	   "vd": "string"
-    }
+    "bt": 0.0,
+    "bu": "string",
+    "bver": 0
+  }, {
+    "n": "string",
+    "t": 0.0,
+    "u": "string",
+    "v": 0.0,
+    "vs": "string",
+    "vb": false,
+    "vd": "string"
+  }
 ]
 ```
 
@@ -5053,20 +5053,20 @@ __GetServiceDataResponse__ output:
 ```json
 
 [
-   {
-        "bn": "string",
-	"bt": 0.0,
-	"bu": "string",
-	"bver": 0
-   }, {
-        "n": "string",
-	"t": 0.0,
-	"u": "string",
-	"v": 0.0,
-	"vs": "string",
-	"vb": false,
-	"vd": "string"
-   }
+  {
+    "bn": "string",
+    "bt": 0.0,
+    "bu": "string",
+    "bver": 0
+  }, {
+    "n": "string",
+    "t": 0.0,
+    "u": "string",
+    "v": 0.0,
+    "vs": "string",
+    "vb": false,
+    "vd": "string"
+  }
 ]
 ```
 
@@ -5081,28 +5081,119 @@ Stores sensor data in a service endpoint in the database.
 
 <a name="datamanager_putsrvdata_request" />
 
-__PutSServiceDataRequest__ input:
+__PutServiceDataRequest__ input:
 
 ```json
 
 [
-   {
-        "bn": "string",
-	"bt": 0.0,
-	"bu": "string",
-	"bver": 0
-   }, {
-        "n": "string",
-	"t": 0.0,
-	"u": "string",
-	"v": 0.0,
-	"vs": "string",
-	"vb": false,
-	"vd": "string"
-   }
+  {
+    "bn": "string",
+    "bt": 0.0,
+    "bu": "string",
+    "bver": 0
+  }, {
+    "n": "string",
+    "t": 0.0,
+    "u": "string",
+    "v": 0.0,
+    "vs": "string",
+    "vb": false,
+    "vd": "string"
+  }
 ]
 ```
 
+<a name="timemanager" />
+
+# TimeManager
+
+<a name="timemanager_sdd" />
+
+## System Design Description Overview
+
+The purpose of TimeManager supporting core system is to provide time and location based services.
+
+The TimeManager provides features for a local cloud systems to :
+* Fetch accurate and trusted time and location information,
+
+
+<a name="timemanager_sysd" />
+
+## System Design Overview
+
+<a name="timemanager_provided_services" />
+
+## Provided services
+
+The TimeManager provides the following services:
+* [Echo](#timemanager_endpoints_get_echo)
+* [Time](#timemanager_endpoints_time)
+
+<a name="timemanager_consumed_services" />
+
+## Consumed services
+
+The TimeManager consumes the following services:
+
+None currently, but will consume Orchestration later on.
+
+<a name="timemanager_usecases" />
+
+## Use cases
+
+The TimeManager has the following use cases:
+* [Fetch trusted time](documentation/timemanager/use_cases/TM_use_case_1.md)
+
+<a name="timemanager_endpoints" />
+
+## Endpoints
+
+Swagger API documentation is available on: `https://<host>:<port>` <br />
+The base URL for the requests: `http://<host>:<port>/timemanager`
+
+<a name="timemanager_endpoints_client" />
+
+### Client endpoint description<br />
+
+| Function | URL subpath | Method | Input | Output |
+| -------- | ----------- | ------ | ----- | ------ |
+| [Echo](#timemanager_endpoints_get_echo) | /echo | GET    | -    | OK     |
+| [Time](#timemanager_endpoints_get_time) | /time | GET    | -    | TimeResponse  |
+
+<a name="timemanager_endpoints_get_echo" />
+
+### Echo
+```
+GET /timemanager/echo
+```
+
+Returns a "Got it!" message with the purpose of testing the system availability.
+
+<a name="timemanager_endpoints_get_time" />
+
+### Get trusted time and location
+```
+GET /timemanager/time
+```
+
+Returns time stamps (UNIX in seconds and millseconds), time zone ("Europe/Budapest"), Daylist savings active (true/false) and if the time is trusted (true/false).
+
+<a name="timemanager_gettime_response" />
+
+__TimeResponse__ output:
+
+```json
+
+{
+  "epoch": 1627844812,
+  "epochMs": 1627844812102,
+  "tz": "string",
+  "dst": true,
+  "trusted": true
+}
+
+```
+
 # Gatekeeper 
 
 <a name="gatekeeper_sdd" />
diff --git a/certificates/testcloud1/timemanager.p12 b/certificates/testcloud1/timemanager.p12
new file mode 100644
index 000000000..625b3aa18
Binary files /dev/null and b/certificates/testcloud1/timemanager.p12 differ
diff --git a/certificates/testcloud2/timemanager.p12 b/certificates/testcloud2/timemanager.p12
new file mode 100644
index 000000000..52456f3a7
Binary files /dev/null and b/certificates/testcloud2/timemanager.p12 differ
diff --git a/core-common/src/deb/control/templates b/core-common/src/deb/control/templates
index da1e7e0a4..18e35b436 100644
--- a/core-common/src/deb/control/templates
+++ b/core-common/src/deb/control/templates
@@ -151,7 +151,12 @@ Description: MySQL password for Certificate Authority system (leave empty for ra
 Template: arrowhead-core-common/mysql_password_datamanager
 Type: password
 Default:
-Description: MySQL password for Datamanager system (leave empty for random).
+Description: MySQL password for DataManager system (leave empty for random).
+
+Template: arrowhead-core-common/mysql_password_timemanager
+Type: password
+Default:
+Description: MySQL password for TimeManager system (leave empty for random).
 
 Template: arrowhead-core-common/sr_host
 Type: string
diff --git a/core-common/src/main/java/eu/arrowhead/common/CommonConstants.java b/core-common/src/main/java/eu/arrowhead/common/CommonConstants.java
index 86c1d0c27..1f697c1bd 100644
--- a/core-common/src/main/java/eu/arrowhead/common/CommonConstants.java
+++ b/core-common/src/main/java/eu/arrowhead/common/CommonConstants.java
@@ -34,6 +34,7 @@ public class CommonConstants {
 	public static final String CORE_SYSTEM_CHOREOGRAPHER = "Choreographer";
 	public static final String CORE_SYSTEM_EVENT_HANDLER = "Event Handler";
 	public static final String CORE_SYSTEM_DATAMANAGER  = "DataManager";
+	public static final String CORE_SYSTEM_TIMEMANAGER  = "TimeManager";
 	public static final String CORE_SYSTEM_GATEKEEPER = "Gatekeeper";
 	public static final String CORE_SYSTEM_GATEWAY = "Gateway";
 	public static final String CORE_SYSTEM_ORCHESTRATOR = "Orchestrator";
@@ -77,6 +78,8 @@ public class CommonConstants {
 	public static final String CORE_SERVICE_DATAMANAGER_PROXY = "proxy";
 	public static final String CORE_SERVICE_DATAMANAGER_HISTORIAN = "historian";
 
+	public static final String CORE_SERVICE_TIMEMANAGER_TIME = "time";
+	
 	public static final String CORE_SERVICE_CONFIGURATION_CONF = "conf";
 	public static final String CORE_SERVICE_CONFIGURATION_RAWCONF = "confraw";
 
@@ -267,9 +270,12 @@ public class CommonConstants {
 	public static final String OP_DATAMANAGER_PROXY = "/proxy";
 	public static final String OP_DATAMANAGER_HISTORIAN = "/historian";
 
-	public static final String TRANSLATOR_URI = "/translator";
-	public static final String OP_TRANSLATOR_FIWARE_URI = "/v2";
-	public static final String OP_TRANSLATOR_PLUGIN_URI = "/plugin";
+	public static final String TIMEMANAGER_URI = "/timemanager";
+	public static final String OP_TIMEMANAGER_TIME = "/time";
+
+    public static final String TRANSLATOR_URI = "/translator";
+    public static final String OP_TRANSLATOR_FIWARE_URI = "/v2";
+    public static final String OP_TRANSLATOR_PLUGIN_URI = "/plugin";
 
 	public static final String SWAGGER_COMMON_PACKAGE = "eu.arrowhead.common.swagger";
 	public static final String SWAGGER_UI_URI = "/swagger-ui.html";
@@ -286,7 +292,8 @@ public class CommonConstants {
 	public static final List<CoreSystemService> PUBLIC_CORE_SYSTEM_SERVICES = List.of(CoreSystemService.ORCHESTRATION_SERVICE, CoreSystemService.AUTH_PUBLIC_KEY_SERVICE,
   			  																		  CoreSystemService.EVENT_PUBLISH_SERVICE, CoreSystemService.EVENT_SUBSCRIBE_SERVICE, CoreSystemService.EVENT_UNSUBSCRIBE_SERVICE, 
 																					  CoreSystemService.PROXY_SERVICE, CoreSystemService.HISTORIAN_SERVICE, CoreSystemService.CHOREOGRAPHER_SERVICE, CoreSystemService.TRANSLATOR_SERVICE,
-	       																			  CoreSystemService.CONFIGURATION_SERVICE, CoreSystemService.CONFIGURATION_RAW_SERVICE);
+	       																			  CoreSystemService.CONFIGURATION_SERVICE, CoreSystemService.CONFIGURATION_RAW_SERVICE, CoreSystemService.TIME_SERVICE);
+
 	
 	public static final String HTTP_CLIENT_CONNECTION_TIMEOUT = "http.client.connection.timeout";
 	public static final String $HTTP_CLIENT_CONNECTION_TIMEOUT_WD = "${" + HTTP_CLIENT_CONNECTION_TIMEOUT + ":" + Defaults.DEFAULT_CONNECTION_TIMEOUT + "}";
@@ -300,6 +307,8 @@ public class CommonConstants {
 	
 	public static final String SERVER_SSL_ENABLED = "server.ssl.enabled";
 	public static final String $SERVER_SSL_ENABLED_WD = "${" + SERVER_SSL_ENABLED + ":" + Defaults.DEFAULT_SSL_SERVER_ENABLED + "}";
+	public static final String WEBSOCKETS_ENABLED = "websockets.enabled";
+	public static final String $WEBSOCKETS_ENABLED_WD = "${" + WEBSOCKETS_ENABLED + ":" + Defaults.DEFAULT_WEBSOCKETS_ENABLED + "}";
 	public static final String KEYSTORE_TYPE = "server.ssl.key-store-type";
 	public static final String $KEYSTORE_TYPE = "${" + KEYSTORE_TYPE + "}";
 	public static final String KEYSTORE_PATH = "server.ssl.key-store";
diff --git a/core-common/src/main/java/eu/arrowhead/common/CoreCommonConstants.java b/core-common/src/main/java/eu/arrowhead/common/CoreCommonConstants.java
index fcf03c5bc..50068bd2a 100644
--- a/core-common/src/main/java/eu/arrowhead/common/CoreCommonConstants.java
+++ b/core-common/src/main/java/eu/arrowhead/common/CoreCommonConstants.java
@@ -73,7 +73,7 @@ public class CoreCommonConstants {
 	public static final String SWAGGER_HTTP_401_MESSAGE = "You are not authorized";
 	public static final String SWAGGER_HTTP_404_MESSAGE = "Not found";
 	public static final String SWAGGER_HTTP_409_MESSAGE = "Request caused a conflict";
-    public static final String SWAGGER_HTTP_415_MESSAGE = "MediaType not supported";
+	public static final String SWAGGER_HTTP_415_MESSAGE = "MediaType not supported";
 	public static final String SWAGGER_HTTP_500_MESSAGE = "Core service is not available";
 	
 	public static final String SWAGGER_TAG_MGMT = "Management";
@@ -100,23 +100,6 @@ public class CoreCommonConstants {
 	public static final String $URI_CRAWLER_INTERVAL_WD = "${" + URI_CRAWLER_INTERVAL + ":" + CoreDefaults.DEFAULT_URI_CRAWLER_INTERVAL + "}";
 	public static final String AUTH_TOKEN_TTL_IN_MINUTES = "auth_token_ttl_in_minutes";
 	public static final String $AUTH_TOKEN_TTL_IN_MINUTES_WD = "${" + AUTH_TOKEN_TTL_IN_MINUTES + ":" + CoreDefaults.DEFAULT_AUTH_TOKEN_TTL_IN_MINUTES + "}";
-
-	public static final String MQTT_BROKER_ENABLED = "mqtt.broker.enabled";
-	public static final String $MQTT_BROKER_ENABLED = "${" + MQTT_BROKER_ENABLED + ":false}";
-	public static final String MQTT_BROKER_ADDRESS = "mqtt.broker.address";
-	public static final String $MQTT_BROKER_ADDRESS = "${" + MQTT_BROKER_ADDRESS + ":0.0.0.0}";
-	public static final String MQTT_BROKER_PORT = "mqtt.broker.port";
-	public static final String $MQTT_BROKER_PORT = "${" + MQTT_BROKER_PORT + ":0}";
-	public static final String MQTT_BROKER_USERNAME = "mqtt.broker.username";
-	public static final String $MQTT_BROKER_USERNAME = "${" + MQTT_BROKER_USERNAME + ":}";
-	public static final String MQTT_BROKER_PASSWORD = "mqtt.broker.password";
-	public static final String $MQTT_BROKER_PASSWORD = "${" + MQTT_BROKER_PASSWORD + ":}";
-	public static final String MQTT_BROKER_CAFILE = "mqtt.broker.cafile";
-	public static final String $MQTT_BROKER_CAFILE = "${" + MQTT_BROKER_CAFILE + ":}";
-	public static final String MQTT_BROKER_CERTFILE = "mqtt.broker.certfile";
-	public static final String $MQTT_BROKER_CERTFILE = "${" + MQTT_BROKER_CERTFILE + ":}";
-	public static final String MQTT_BROKER_KEYFILE = "mqtt.broker.keyfile";
-	public static final String $MQTT_BROKER_KEYFILE = "${" + MQTT_BROKER_KEYFILE + ":}";
 	
 	public static final String REQUEST_PARAM_PAGE = "page";
 	public static final String REQUEST_PARAM_ITEM_PER_PAGE = "item_per_page";
@@ -147,8 +130,8 @@ public class CoreCommonConstants {
 	public static final String $SYSTEM_REGISTRY_PING_TIMEOUT_WD =
 			"${" + SYSTEM_REGISTRY_PING_TIMEOUT + ":" + CoreDefaults.DEFAULT_SYSTEM_REGISTRY_PING_TIMEOUT_MILLISECONDS + "}";
 
-    public static final String AUTHORIZATION_IS_EVENTHANDLER_PRESENT = "eventhandler_is_present";
-    public static final String $AUTHORIZATION_IS_EVENTHANDLER_PRESENT_WD = "${" + AUTHORIZATION_IS_EVENTHANDLER_PRESENT + ":" + CoreDefaults.DEFAULT_AUTHORIZATION_IS_EVENTHANDLER_PRESENT + "}";
+	public static final String AUTHORIZATION_IS_EVENTHANDLER_PRESENT = "eventhandler_is_present";
+	public static final String $AUTHORIZATION_IS_EVENTHANDLER_PRESENT_WD = "${" + AUTHORIZATION_IS_EVENTHANDLER_PRESENT + ":" + CoreDefaults.DEFAULT_AUTHORIZATION_IS_EVENTHANDLER_PRESENT + "}";
 	
 	public static final String ORCHESTRATOR_IS_GATEKEEPER_PRESENT = "gatekeeper_is_present";
 	public static final String $ORCHESTRATOR_IS_GATEKEEPER_PRESENT_WD = "${" + ORCHESTRATOR_IS_GATEKEEPER_PRESENT + ":" + CoreDefaults.DEFAULT_ORCHESTRATOR_IS_GATEKEEPER_PRESENT + "}";
@@ -250,13 +233,31 @@ public class CoreCommonConstants {
 	public static final String RELAY_TEST_LOG_MEASUREMENTS_IN_DB = "relay.test.log_measurements_in_db";
 	public static final String $RELAY_TEST_LOG_MEASUREMENTS_IN_DB_WD = "${" + RELAY_TEST_LOG_MEASUREMENTS_IN_DB + ":" + CoreDefaults.DEFAULT_RELAY_TEST_LOG_MEASUREMENTS_IN_DB + "}";
 	
-    public static final String CERTIFICATE_FORMAT = "X.509";
+	public static final String CERTIFICATE_FORMAT = "X.509";
 
 	// Translator-Fiware
-    public static final String FIWARE_SERVER_HOST = "fiware.server.host";
-    public static final String $FIWARE_SERVER_HOST = "${" + FIWARE_SERVER_HOST + ":}";
-    public static final String FIWARE_SERVER_PORT = "fiware.server.port";
-    public static final String $FIWARE_SERVER_PORT = "${" + FIWARE_SERVER_PORT + ":0}";
+	public static final String FIWARE_SERVER_HOST = "fiware.server.host";
+	public static final String $FIWARE_SERVER_HOST = "${" + FIWARE_SERVER_HOST + ":}";
+	public static final String FIWARE_SERVER_PORT = "fiware.server.port";
+	public static final String $FIWARE_SERVER_PORT = "${" + FIWARE_SERVER_PORT + ":0}";
+
+	// MQTT 
+	public static final String MQTT_BROKER_ENABLED = "mqtt.broker.enabled";
+	public static final String $MQTT_BROKER_ENABLED = "${" + MQTT_BROKER_ENABLED + ":false}";
+	public static final String MQTT_BROKER_ADDRESS = "mqtt.broker.address";
+	public static final String $MQTT_BROKER_ADDRESS = "${" + MQTT_BROKER_ADDRESS + ":0.0.0.0}";
+	public static final String MQTT_BROKER_PORT = "mqtt.broker.port";
+	public static final String $MQTT_BROKER_PORT = "${" + MQTT_BROKER_PORT + ":0}";
+	public static final String MQTT_BROKER_USERNAME = "mqtt.broker.username";
+	public static final String $MQTT_BROKER_USERNAME = "${" + MQTT_BROKER_USERNAME + ":}";
+	public static final String MQTT_BROKER_PASSWORD = "mqtt.broker.password";
+	public static final String $MQTT_BROKER_PASSWORD = "${" + MQTT_BROKER_PASSWORD + ":}";
+	public static final String MQTT_BROKER_CAFILE = "mqtt.broker.cafile";
+	public static final String $MQTT_BROKER_CAFILE = "${" + MQTT_BROKER_CAFILE + ":}";
+	public static final String MQTT_BROKER_CERTFILE = "mqtt.broker.certfile";
+	public static final String $MQTT_BROKER_CERTFILE = "${" + MQTT_BROKER_CERTFILE + ":}";
+	public static final String MQTT_BROKER_KEYFILE = "mqtt.broker.keyfile";
+	public static final String $MQTT_BROKER_KEYFILE = "${" + MQTT_BROKER_KEYFILE + ":}";
 
     //=================================================================================================
 	// assistant methods
diff --git a/core-common/src/main/java/eu/arrowhead/common/Defaults.java b/core-common/src/main/java/eu/arrowhead/common/Defaults.java
index abb30e70d..227bf83d2 100644
--- a/core-common/src/main/java/eu/arrowhead/common/Defaults.java
+++ b/core-common/src/main/java/eu/arrowhead/common/Defaults.java
@@ -20,6 +20,7 @@ public class Defaults {
 	// members
 	
 	public static final boolean DEFAULT_SSL_SERVER_ENABLED = true;
+	public static final boolean DEFAULT_WEBSOCKETS_ENABLED = false;
 	public static final boolean DEFAULT_DISABLE_HOSTNAME_VERIFIER = false;
 	public static final boolean DEFAULT_LOG_ALL_REQUEST_AND_RESPONSE = false;
 	public static final int DEFAULT_URI_CRAWLER_INTERVAL = 30;
@@ -37,6 +38,7 @@ public class Defaults {
 	public static final int DEFAULT_GATEWAY_PORT = 8453;
 	public static final int DEFAULT_EVENT_HANDLER_PORT = 8455;
 	public static final int DEFAULT_DATAMANAGER_PORT = 8461;
+	public static final int DEFAULT_TIMEMANAGER_PORT = 8463;
 	public static final int DEFAULT_CHOREOGRAPHER_PORT = 8457;
     	public static final int DEFAULT_CONFIGURATION_PORT = 8459;
 	public static final int DEFAULT_CERTIFICATE_AUTHORITY_PORT = 8448;
diff --git a/core-common/src/main/java/eu/arrowhead/common/SslUtil.java b/core-common/src/main/java/eu/arrowhead/common/SslUtil.java
new file mode 100644
index 000000000..351d500f5
--- /dev/null
+++ b/core-common/src/main/java/eu/arrowhead/common/SslUtil.java
@@ -0,0 +1,132 @@
+/********************************************************************************
+ * Copyright (c) 2019 AITIA
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *   AITIA - implementation
+ *   Arrowhead Consortia - conceptualization
+ ********************************************************************************/
+
+package eu.arrowhead.common;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Paths;
+import java.security.KeyManagementException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+ 
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+ 
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMDecryptorProvider;
+import org.bouncycastle.openssl.PEMEncryptedKeyPair;
+import org.bouncycastle.openssl.PEMKeyPair;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
+
+public class SslUtil
+{
+
+    //=================================================================================================
+    // members
+
+    private static final String BOUNCYCASTLE_IDENTIFIER = "BC";
+    private static final String CA_CERTIFICATE = "ca-certificate";
+    private static final String CERTIFICATE = "certificate";
+    private static final String PRIVATE_KEY = "private-key";
+    private static final String TLS_VERSION = "TLSv1.3";
+
+    private static final Logger logger = LogManager.getLogger(SslUtil.class);
+
+    //=================================================================================================
+    // methods
+
+    //-------------------------------------------------------------------------------------------------
+    public static SSLSocketFactory getSslSocketFactory(final String caCrtFile, final String crtFile, final String keyFile, final String password)
+              throws
+                     InvalidPathException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException,
+                     UnrecoverableKeyException, KeyManagementException, Exception {
+
+              PEMParser parser = null;
+              try {
+                     Security.addProvider(new BouncyCastleProvider());
+             
+                     // load CA certificate
+                     parser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
+                     final X509CertificateHolder caCert = (X509CertificateHolder) parser.readObject();
+                     parser.close();
+
+                     // load client certificate
+                     parser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
+                     final X509CertificateHolder cert = (X509CertificateHolder) parser.readObject();
+                     parser.close();
+
+                     // load client private key
+                     parser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))));
+                     Object obj = parser.readObject();
+                     parser.close();
+                     KeyPair key = null;
+                     JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BOUNCYCASTLE_IDENTIFIER);
+                     if (obj instanceof PEMEncryptedKeyPair) {
+                            PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
+                            converter = new JcaPEMKeyConverter().setProvider(BOUNCYCASTLE_IDENTIFIER);
+                            key = converter.getKeyPair(((PEMEncryptedKeyPair) obj).decryptKeyPair(decProv));
+                     } else {
+                            key = converter.getKeyPair((PEMKeyPair) obj);
+                     }
+            
+                     final JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
+                     certConverter.setProvider(BOUNCYCASTLE_IDENTIFIER);
+
+                     // CA certificate is used to authenticate server
+                     final KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
+                     caKs.load(null, null);
+                     caKs.setCertificateEntry(CA_CERTIFICATE, certConverter.getCertificate(caCert));
+                     final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                     tmf.init(caKs);
+
+                     // Client key and certificates are sent to server so it can authenticate us
+                     final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                     ks.load(null, null);
+                     ks.setCertificateEntry(CERTIFICATE, certConverter.getCertificate(cert));
+                     ks.setKeyEntry(PRIVATE_KEY, key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{certConverter.getCertificate(cert)});
+                     final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+                     kmf.init(ks, password.toCharArray());
+                     
+                     final SSLContext context = SSLContext.getInstance(TLS_VERSION);
+                     context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+                     return context.getSocketFactory();
+              } catch(Exception e) {
+                     logger.debug("Unhandled exception: " + e.toString());
+                     throw e;
+              } finally {
+                     if (parser != null) {
+                            parser.close();
+                     }
+              }
+       }
+}
\ No newline at end of file
diff --git a/core-common/src/main/java/eu/arrowhead/common/core/CoreSystem.java b/core-common/src/main/java/eu/arrowhead/common/core/CoreSystem.java
index dd3f90255..4fb065df7 100644
--- a/core-common/src/main/java/eu/arrowhead/common/core/CoreSystem.java
+++ b/core-common/src/main/java/eu/arrowhead/common/core/CoreSystem.java
@@ -71,6 +71,8 @@ public enum CoreSystem {
 															   CoreSystemService.EVENT_PUBLISH_AUTH_UPDATE_SERVICE)),
 
     DATAMANAGER(Defaults.DEFAULT_DATAMANAGER_PORT, List.of(CoreSystemService.PROXY_SERVICE, CoreSystemService.HISTORIAN_SERVICE)),
+
+	TIMEMANAGER(Defaults.DEFAULT_TIMEMANAGER_PORT, List.of(CoreSystemService.TIME_SERVICE)),
 	
 	GATEWAY(Defaults.DEFAULT_GATEWAY_PORT, List.of(CoreSystemService.GATEWAY_PUBLIC_KEY_SERVICE,
 												   CoreSystemService.GATEWAY_PROVIDER_SERVICE,
diff --git a/core-common/src/main/java/eu/arrowhead/common/core/CoreSystemService.java b/core-common/src/main/java/eu/arrowhead/common/core/CoreSystemService.java
index 0eccc858c..5a2fd068c 100644
--- a/core-common/src/main/java/eu/arrowhead/common/core/CoreSystemService.java
+++ b/core-common/src/main/java/eu/arrowhead/common/core/CoreSystemService.java
@@ -63,6 +63,9 @@ public enum CoreSystemService {
 	PROXY_SERVICE(CommonConstants.CORE_SERVICE_DATAMANAGER_PROXY, CommonConstants.DATAMANAGER_URI + CommonConstants.OP_DATAMANAGER_PROXY),
 	HISTORIAN_SERVICE(CommonConstants.CORE_SERVICE_DATAMANAGER_HISTORIAN, CommonConstants.DATAMANAGER_URI + CommonConstants.OP_DATAMANAGER_HISTORIAN),
 
+	// TimeManager services
+	TIME_SERVICE(CommonConstants.CORE_SERVICE_TIMEMANAGER_TIME, CommonConstants.TIMEMANAGER_URI + CommonConstants.OP_TIMEMANAGER_TIME),
+
 	// Translator services
 	TRANSLATOR_SERVICE(CommonConstants.CORE_SERVICE_TRANSLATOR, CommonConstants.TRANSLATOR_URI),
 	TRANSLATOR_FIWARE_SERVICE(CommonConstants.CORE_SERVICE_TRANSLATOR_FIWARE, CommonConstants.TRANSLATOR_URI + CommonConstants.OP_TRANSLATOR_FIWARE_URI),
diff --git a/core-common/src/main/java/eu/arrowhead/common/dto/shared/TimeManagerTimeResponseDTO.java b/core-common/src/main/java/eu/arrowhead/common/dto/shared/TimeManagerTimeResponseDTO.java
new file mode 100644
index 000000000..802f212a8
--- /dev/null
+++ b/core-common/src/main/java/eu/arrowhead/common/dto/shared/TimeManagerTimeResponseDTO.java
@@ -0,0 +1,98 @@
+/********************************************************************************
+ * Copyright (c) 2021 Lulea University of Technology
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *   Lulea University of Technology - implementation
+ *   Arrowhead Consortia - conceptualization
+ ********************************************************************************/
+
+package eu.arrowhead.common.dto.shared;
+
+import java.util.Date;
+import java.util.TimeZone;
+import java.io.Serializable;
+
+
+public class TimeManagerTimeResponseDTO implements Serializable {
+
+        //=================================================================================================
+        // members
+        
+        private static final long serialVersionUID = 1648756742138137282L;
+
+        private long epoch;
+        private long epochMs;
+        private String tz;
+        private boolean dst;
+        private boolean trusted;
+                
+        //=================================================================================================
+        // methods
+        
+        //-------------------------------------------------------------------------------------------------
+        public TimeManagerTimeResponseDTO() {
+        }
+
+        //-------------------------------------------------------------------------------------------------
+        public TimeManagerTimeResponseDTO(final String tz) {
+                this.tz = tz;
+                
+                Date date = new Date();
+                epochMs = date.getTime();
+                epoch = epochMs / 1000;
+
+                dst = TimeZone.getTimeZone(this.tz).inDaylightTime(date);
+                trusted = false;
+        }
+
+        public TimeManagerTimeResponseDTO(final String tz, final boolean trusted) {
+                this.tz = tz;
+                
+                Date date = new Date();
+                epochMs = date.getTime();
+                epoch = epochMs / 1000;
+
+                dst = TimeZone.getTimeZone(this.tz).inDaylightTime(date);
+                this.trusted = trusted;
+        }
+
+        //-------------------------------------------------------------------------------------------------
+        public TimeManagerTimeResponseDTO(final long epoch, final String tz, final boolean trusted) {
+                Date date = new Date(epoch*1000);
+                this.epoch = epoch;
+                this.epochMs = epoch * 1000;
+                this.tz = tz;
+
+                this.dst = TimeZone.getTimeZone(this.tz).inDaylightTime(date);
+                this.trusted = trusted;
+        }
+
+        //-------------------------------------------------------------------------------------------------
+        public TimeManagerTimeResponseDTO(final long epoch, final long epochMs, final String tz, final boolean dst, final boolean trusted) {
+                this.epoch = epoch;
+                this.epochMs = epochMs;
+                this.tz = tz;
+                this.dst = dst;
+                this.trusted = trusted;
+        }
+
+        //-------------------------------------------------------------------------------------------------
+        public long getEpoch() { return epoch; }
+        public long getEpochMs() { return epochMs; }
+        public String getTz() { return tz; }
+        public boolean getDst() { return dst; }
+        public boolean getTrusted() {return trusted; }
+
+        //-------------------------------------------------------------------------------------------------
+        public void setEpoch(long epoch) { this.epoch = epoch; }
+        public void setEpochMs(long epochMs) { this.epochMs = epochMs; }
+        public void setTz(String tz) { this.tz = tz; }
+        public void setDst(boolean dst) { this.dst = dst; }
+        public void setTrusted(boolean trusted) { this.trusted = trusted; }
+}
diff --git a/datamanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/datamanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json
index 20f805510..e1e885229 100644
--- a/datamanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ b/datamanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -23,5 +23,10 @@
     "name": "core_system_name",
     "type": "java.lang.String",
     "description": "A description for 'core_system_name'"
+  },
+  {
+    "name": "websockets.enabled",
+    "type": "java.lang.Boolean",
+    "description": "Enables WebSocket support"
   }
 ]}
\ No newline at end of file
diff --git a/documentation/timemanager/use_cases/TM_use_case_1.md b/documentation/timemanager/use_cases/TM_use_case_1.md
new file mode 100644
index 000000000..8edcbc933
--- /dev/null
+++ b/documentation/timemanager/use_cases/TM_use_case_1.md
@@ -0,0 +1,7 @@
+| Name | Description |
+| ---- | --------- |
+| ID | Time-Get |
+| Brief Description | A Consumer fetches time information from the Time service |
+| Primary Actors | Consumer, TimeManager system |
+| Preconditions | -  None|
+| Main Flow | - The Consumer performs a request to the TimeManager's Time service. <br/>- The Time responds with time stamps, time zone information etc.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9f62b1cff..2dc8c89ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
 	    <module>orchestrator</module>
 	    <module>eventhandler</module>
 	    <module>datamanager</module>
+	    <module>timemanager</module>
 	    <module>relay-library</module>
 	    <module>gatekeeper</module>
 	    <module>gateway</module>
@@ -65,6 +66,7 @@
   		<activemq.client.version>5.15.9</activemq.client.version>
 		<bouncy.castle.version>1.64</bouncy.castle.version>
   		<jna.version>5.5.0</jna.version>
+		<paho.version>1.2.0</paho.version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 	</properties>
 
@@ -116,8 +118,8 @@
 			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
 		<dependency>
-        	<groupId>org.springframework.boot</groupId>
-        	<artifactId>spring-boot-starter-websocket</artifactId>
+        		<groupId>org.springframework.boot</groupId>
+        		<artifactId>spring-boot-starter-websocket</artifactId>
         	</dependency>
 		<dependency>
 		    <groupId>org.springframework.boot</groupId>
@@ -204,23 +206,36 @@
 		</dependency>
 -->
 		
-	<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
-	<dependency>
+		<dependency>
       		<groupId>com.google.code.gson</groupId>
       		<artifactId>gson</artifactId>
       		<version>2.8.6</version>
-	</dependency>
+		</dependency>
+
+		<dependency>
+			<groupId>org.eclipse.paho</groupId>
+			<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+			<version>${paho.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-net</groupId>
+			<artifactId>commons-net</artifactId>
+			<version>3.8.0</version>
+		</dependency>
 
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.security</groupId>
 			<artifactId>spring-security-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+
 	</dependencies>
 
 	<build>
diff --git a/scripts/create_arrowhead_tables.sql b/scripts/create_arrowhead_tables.sql
index c2c1c153e..e8ad4c3e9 100644
--- a/scripts/create_arrowhead_tables.sql
+++ b/scripts/create_arrowhead_tables.sql
@@ -351,6 +351,8 @@ CREATE TABLE IF NOT EXISTS `dmhist_entries` (
   CONSTRAINT `message_id_fk` FOREIGN KEY(`mid`) REFERENCES `dmhist_messages`(`id`) ON DELETE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
+-- TimeManager
+
 -- Choreographer
 
 CREATE TABLE IF NOT EXISTS `choreographer_plan` (
diff --git a/scripts/create_empty_arrowhead_db.sql b/scripts/create_empty_arrowhead_db.sql
index 89af1e582..484149d9f 100644
--- a/scripts/create_empty_arrowhead_db.sql
+++ b/scripts/create_empty_arrowhead_db.sql
@@ -47,6 +47,11 @@ CREATE USER IF NOT EXISTS 'datamanager'@'localhost' IDENTIFIED BY 'gRLjXbqu0YwYh
 CREATE USER IF NOT EXISTS 'datamanager'@'%' IDENTIFIED BY 'gRLjXbqu0YwYhfK';
 source datamanager_privileges.sql
 
+-- TimeManager
+CREATE USER IF NOT EXISTS 'timemanager'@'localhost' IDENTIFIED BY 'xyp2XEAu5Tbc41g';
+CREATE USER IF NOT EXISTS 'timemanager'@'%' IDENTIFIED BY 'xyp2XEAu5Tbc41g';
+source timemanager_privileges.sql
+
 -- Choreographer
 CREATE USER IF NOT EXISTS 'choreographer'@'localhost' IDENTIFIED BY 'Qa5yx4oBp4Y9RLX';
 CREATE USER IF NOT EXISTS 'choreographer'@'%' IDENTIFIED BY 'Qa5yx4oBp4Y9RLX';
diff --git a/scripts/start_coresystems.bat b/scripts/start_coresystems.bat
index 8ba12e21b..9bf8c4a36 100644
--- a/scripts/start_coresystems.bat
+++ b/scripts/start_coresystems.bat
@@ -29,6 +29,10 @@ cd ..\..\datamanager\target
 START "" /B "cmd /c javaw -jar arrowhead-datamanager-%version%.jar > sout_datamanager.log 2>&1"
 echo DataManager started
 
+cd ..\..\timemanager\target
+START "" /B "cmd /c javaw -jar arrowhead-timemanager-%version%.jar > sout_timemanager.log 2>&1"
+echo TimeManager started
+
 cd ..\..\gatekeeper\target
 START "" /B "cmd /c javaw -jar arrowhead-gatekeeper-%version%.jar > sout_gk.log 2>&1"
 echo Gatekeeper started
@@ -42,7 +46,7 @@ START "" /B "cmd /c javaw -jar arrowhead-choreographer-%version%.jar > sout_chor
 echo Choreographer started
 
 cd ..\..\configuration\target
-START "" /B "cmd /c javaw -jar arrowhead-configuration-4.2.0.jar > sout_configuration.log 2>&1"
+START "" /B "cmd /c javaw -jar arrowhead-configuration-%version%.jar > sout_configuration.log 2>&1"
 echo Configuration started
 
 cd ..\..\certificate-authority\target
diff --git a/scripts/start_coresystems.sh b/scripts/start_coresystems.sh
index ca30780e2..b0a43ca47 100644
--- a/scripts/start_coresystems.sh
+++ b/scripts/start_coresystems.sh
@@ -28,6 +28,10 @@ cd ../../datamanager/target
 nohup java -jar $(find . -maxdepth 1 -name arrowhead-datamanager-\*.jar | sort | tail -n1) &> sout_datamanager.log &
 echo DataManager started
 
+cd ../../timemanager/target
+nohup java -jar $(find . -maxdepth 1 -name arrowhead-timemanager-\*.jar | sort | tail -n1) &> sout_timemanager.log &
+echo TimeManager started
+
 cd ../../gatekeeper/target
 nohup java -jar $(find . -maxdepth 1 -name arrowhead-gatekeeper-\*.jar | sort | tail -n1) &> sout_gk.log &
 echo Gatekeeper started
diff --git a/scripts/stop_coresystems.bat b/scripts/stop_coresystems.bat
index 3f914d66d..aaaca607e 100644
--- a/scripts/stop_coresystems.bat
+++ b/scripts/stop_coresystems.bat
@@ -10,6 +10,7 @@ FOR /F "tokens=1" %%p in ('"jps -v | find "orchestrator""') DO taskkill /pid %%p
 FOR /F "tokens=1" %%p in ('"jps -v | find "gatekeeper""') DO taskkill /pid %%p > NUL 2>&1
 FOR /F "tokens=1" %%p in ('"jps -v | find "eventhandler""') DO taskkill /pid %%p > NUL 2>&1
 FOR /F "tokens=1" %%p in ('"jps -v | find "datamanager""') DO taskkill /pid %%p > NUL 2>&1
+FOR /F "tokens=1" %%p in ('"jps -v | find "timemanager""') DO taskkill /pid %%p > NUL 2>&1
 FOR /F "tokens=1" %%p in ('"jps -v | find "gateway""') DO taskkill /pid %%p > NUL 2>&1
 FOR /F "tokens=1" %%p in ('"jps -v | find "authorization""') DO taskkill /pid %%p > NUL 2>&1
 FOR /F "tokens=1" %%p in ('"jps -v | find "certificate""') DO taskkill /pid %%p > NUL 2>&1
@@ -30,6 +31,7 @@ IF "%STILL_THERE%"=="""" (
   FOR /F "tokens=1" %%p in ('"jps -v | find "gatekeeper""') DO taskkill /F /pid %%p
   FOR /F "tokens=1" %%p in ('"jps -v | find "eventhandler""') DO taskkill /F /pid %%p
   FOR /F "tokens=1" %%p in ('"jps -v | find "datamanager""') DO taskkill /F /pid %%p
+  FOR /F "tokens=1" %%p in ('"jps -v | find "timemanager""') DO taskkill /F /pid %%p
   FOR /F "tokens=1" %%p in ('"jps -v | find "gateway""') DO taskkill /F /pid %%p
   FOR /F "tokens=1" %%p in ('"jps -v | find "authorization""') DO taskkill /F /pid %%p
   FOR /F "tokens=1" %%p in ('"jps -v | find "certificate""') DO taskkill /F /pid %%p
diff --git a/scripts/stop_coresystems.sh b/scripts/stop_coresystems.sh
index 8b75e0c94..ca030b888 100644
--- a/scripts/stop_coresystems.sh
+++ b/scripts/stop_coresystems.sh
@@ -8,6 +8,7 @@ pkill -f gatekeeper
 pkill -f authorization
 pkill -f eventhandler
 pkill -f datamanager
+pkill -f timemanager
 pkill -f gateway
 pkill -f certificate-authority
 sleep 5s
@@ -23,6 +24,7 @@ then
   kill -KILL $(ps aux | grep 'authorization' | awk '{print $2}')
   kill -KILL $(ps aux | grep 'eventhandler' | awk '{print $2}')
   kill -KILL $(ps aux | grep 'datamanager' | awk '{print $2}')
+  kill -KILL $(ps aux | grep 'timemanager' | awk '{print $2}')
   kill -KILL $(ps aux | grep 'gateway' | awk '{print $2}')
   kill -KILL $(ps aux | grep 'certificate-authority' | awk '{print $2}')
   kill -KILL $(ps aux | grep 'serviceregistry' | awk '{print $2}')
diff --git a/scripts/timemanager_privileges.sql b/scripts/timemanager_privileges.sql
new file mode 100644
index 000000000..aadf90563
--- /dev/null
+++ b/scripts/timemanager_privileges.sql
@@ -0,0 +1,9 @@
+USE `arrowhead`;
+
+REVOKE ALL, GRANT OPTION FROM 'timemanager'@'localhost';
+
+GRANT ALL PRIVILEGES ON `arrowhead`.`logs` TO 'timemanager'@'localhost';
+
+GRANT ALL PRIVILEGES ON `arrowhead`.`logs` TO 'timemanager'@'%';
+
+FLUSH PRIVILEGES;
diff --git a/timemanager/documentation/Arrowhead Time Service IDD.pdf b/timemanager/documentation/Arrowhead Time Service IDD.pdf
new file mode 100644
index 000000000..579ef6a72
Binary files /dev/null and b/timemanager/documentation/Arrowhead Time Service IDD.pdf differ
diff --git a/timemanager/documentation/Arrowhead Time Service SD.pdf b/timemanager/documentation/Arrowhead Time Service SD.pdf
new file mode 100644
index 000000000..787c27a40
Binary files /dev/null and b/timemanager/documentation/Arrowhead Time Service SD.pdf differ
diff --git a/timemanager/documentation/Arrowhead TimeManager SysD.pdf b/timemanager/documentation/Arrowhead TimeManager SysD.pdf
new file mode 100644
index 000000000..18bc7311f
Binary files /dev/null and b/timemanager/documentation/Arrowhead TimeManager SysD.pdf differ
diff --git a/timemanager/documentation/Readme.txt b/timemanager/documentation/Readme.txt
new file mode 100644
index 000000000..f87ad5f98
--- /dev/null
+++ b/timemanager/documentation/Readme.txt
@@ -0,0 +1,6 @@
+File list:
+
+Arrowhead TimeManager SysD.pdf - TimeManager System design 
+Arrowhead Time Service IDD.pdf - Time Service Interface design description
+Arrowhead Time Service SD.pdf - Time Service description
+Readme.txt - This file
diff --git a/timemanager/pom.xml b/timemanager/pom.xml
new file mode 100644
index 000000000..dd1d72e0a
--- /dev/null
+++ b/timemanager/pom.xml
@@ -0,0 +1,140 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+  	<parent>
+    	<groupId>eu.arrowhead</groupId>
+    	<artifactId>core</artifactId>
+    	<version>${revision}</version>
+  	</parent>
+  	
+  	<artifactId>arrowhead-timemanager</artifactId>
+  	<packaging>jar</packaging>
+	<name>Arrowhead TimeManager</name>
+  	<description>Arrowhead TimeManager core service</description>
+  	
+  	<dependencies>
+	    <dependency>
+	      	<groupId>eu.arrowhead</groupId>
+	      	<artifactId>arrowhead-core-common</artifactId>
+	      	<version>${revision}</version>
+	    </dependency>
+		<dependency>
+			<groupId>org.shredzone.commons</groupId>
+			<artifactId>commons-suncalc</artifactId>
+			<version>3.5</version>
+		</dependency>
+  	</dependencies>
+  	
+  	<build>
+	 	<plugins>
+	   		<plugin>
+	 			<artifactId>maven-resources-plugin</artifactId>
+	        	<version>${mvn.resources.version}</version>
+	        	<executions>
+	          		<execution>
+	            		<id>copy-resources</id>
+	            		<!-- here the phase you need -->
+	            		<phase>validate</phase>
+		            	<goals>
+		              		<goal>copy-resources</goal>
+		            	</goals>
+		            	<configuration>
+		              		<outputDirectory>${basedir}/target</outputDirectory>
+		              		<resources>
+		                		<resource>
+		                  			<directory>src/main/resources</directory>
+		                  			<includes>
+		                  				<include>application.properties</include>
+		                  				<include>log4j2.xml</include>
+		                  			</includes>
+		                		</resource>
+		              		</resources>
+		            	</configuration>
+	          		</execution>
+	        	</executions>
+	      	</plugin>
+	      	
+	      	<plugin>
+				<artifactId>jdeb</artifactId>
+				<groupId>org.vafer</groupId>
+				<version>1.8</version>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<goals>
+							<goal>jdeb</goal>
+						</goals>
+						<configuration>
+							<snapshotExpand>true</snapshotExpand>
+							<snapshotTemplate>[YYMMddHHmm].${git.commit.id.abbrev}</snapshotTemplate>
+							<deb>target/${project.artifactId}_${revision}.deb</deb>
+							<verbose>true</verbose>
+							<controlDir>${basedir}/src/deb/control</controlDir>
+							<dataSet>
+				                <data>
+		                  			<type>file</type>
+		                  			<src>${project.build.directory}/${project.build.finalName}.jar</src>
+		                  			<mapper>
+		                    			<type>perm</type>
+		                    			<prefix>/usr/share/arrowhead/timemanager</prefix>
+		                    			<filemode>755</filemode>
+		                  			</mapper>
+	                			</data>
+	                			
+	                			<data>
+		                  			<type>link</type>
+		                  			<linkName>/usr/share/arrowhead/timemanager/${project.artifactId}.jar</linkName>
+		                  			<linkTarget>/usr/share/arrowhead/timemanager/${project.build.finalName}.jar</linkTarget>
+	                			</data>
+	                			
+	                			<data>
+	                				<type>file</type>
+	                				<src>${project.build.directory}/log4j2.xml</src>
+	                				<mapper>
+	                					<type>perm</type>
+	                					<prefix>/etc/arrowhead/systems/timemanager</prefix>
+	                					<filemode>644</filemode>
+	                				</mapper>
+	                			</data>
+	                			
+	                			<data>
+	                				<type>file</type>
+	                				<src>${project.build.directory}/application.properties</src>
+	                				<mapper>
+	                					<type>perm</type>
+	                					<prefix>/etc/arrowhead/systems/timemanager</prefix>
+	                					<filemode>644</filemode>
+	                				</mapper>
+	                			</data>
+	                			
+	                			<data>
+	                				<type>link</type>
+	                				<linkName>/usr/share/arrowhead/timemanager/application.properties</linkName>
+	                				<linkTarget>/etc/arrowhead/systems/timemanager/application.properties</linkTarget>
+	                			</data>
+	                			
+	                			<data>
+	                				<type>file</type>
+	                				<src>${project.basedir}/src/deb/arrowhead-timemanager.service</src>
+	                				<mapper>
+	                					<type>perm</type>
+	                					<prefix>/etc/systemd/system</prefix>
+	                					<filemode>644</filemode>
+	                				</mapper>
+	                			</data>
+	                			
+	                			<data>
+	                				<type>file</type>
+	                				<src>${project.basedir}/../scripts/timemanager_privileges.sql</src>
+	                				<mapper>
+	                					<type>perm</type>
+	                					<prefix>/usr/share/arrowhead/conf</prefix>
+	                				</mapper>
+	                			</data>
+	         		     	</dataSet>
+	            		</configuration>
+          			</execution>
+        		</executions>
+      		</plugin>
+	 	</plugins>
+	</build>
+</project>
diff --git a/timemanager/src/deb/arrowhead-timemanager.service b/timemanager/src/deb/arrowhead-timemanager.service
new file mode 100644
index 000000000..884d05775
--- /dev/null
+++ b/timemanager/src/deb/arrowhead-timemanager.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=arrowhead-timemanager
+After=network.target mysql.target
+
+[Service]
+WorkingDirectory=/etc/arrowhead/systems/timemanager
+ExecStart=/usr/bin/java -Dlog4j.configurationFile=file:/etc/arrowhead/systems/timemanager/log4j2.xml -jar /usr/share/arrowhead/timemanager/arrowhead-timemanager.jar
+TimeoutStopSec=5
+Type=simple
+User=arrowhead
+Group=arrowhead
+
+[Install]
+WantedBy=default.target
diff --git a/timemanager/src/deb/control/config b/timemanager/src/deb/control/config
new file mode 100644
index 000000000..1fc73f0e4
--- /dev/null
+++ b/timemanager/src/deb/control/config
@@ -0,0 +1,20 @@
+#!/bin/bash -e
+
+. /usr/share/debconf/confmodule
+
+if logname 2>/dev/null; then
+  USER=$(logname)
+  HOME=$(eval echo "~$USER")
+else
+  USER="root"
+  HOME="/root"
+fi
+
+# Get installation type
+db_input high arrowhead-core-common/db_host || true
+db_input high arrowhead-core-common/mysql_password_timemanager || true
+db_input high arrowhead-core-common/sr_host || true
+
+# Run dialogs
+db_go || true
+
diff --git a/timemanager/src/deb/control/control b/timemanager/src/deb/control/control
new file mode 100644
index 000000000..eba172e14
--- /dev/null
+++ b/timemanager/src/deb/control/control
@@ -0,0 +1,10 @@
+Package: arrowhead-timemanager
+Version: [[version]]
+Section: contrib/java
+Priority: optional
+Architecture: all
+Maintainer: Jens Eliasson <jens.eliasson@thingwave.eu>
+Homepage: http://www.arrowhead.eu
+Description: Arrowhead TimeManager System
+Distribution: development
+Depends: java-runtime-headless, virtual-mysql-server, arrowhead-core-common
diff --git a/timemanager/src/deb/control/postinst b/timemanager/src/deb/control/postinst
new file mode 100644
index 000000000..d4d6413a6
--- /dev/null
+++ b/timemanager/src/deb/control/postinst
@@ -0,0 +1,95 @@
+#!/bin/bash
+# postinst script for arrowhead-timemanager
+#
+# see: dh_installdeb(1)
+
+set -e
+
+. /usr/share/debconf/confmodule
+
+SYSTEM_NAME="timemanager"
+PKG_NAME="arrowhead-timemanager"
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see https://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+case "$1" in
+  configure)
+    . /usr/share/arrowhead/conf/ahconf.sh
+    SYSTEM_DIR="${AH_SYSTEMS_DIR}/${SYSTEM_NAME}"
+
+    db_get arrowhead-core-common/mysql_password_timemanager; system_passwd=$RET || true
+    db_unregister arrowhead-core-common/mysql_password_timemanager
+
+    # Generate password (if required)
+    if [ -z "${system_passwd}" ]; then
+      system_passwd="$(openssl rand -base64 12)"
+    fi  
+
+    echo "Configuring MySQL database..." >&2
+    ah_db_tables_and_user ${SYSTEM_NAME} ${SYSTEM_NAME}_privileges.sql ${system_passwd}
+
+    if [ ! -d "${SYSTEM_DIR}" ]; then
+      mkdir -p ${SYSTEM_DIR}
+    fi
+
+    ah_cert_signed_system ${SYSTEM_NAME}
+
+    # modify log config and application.properties
+
+    ah_transform_log_file ${SYSTEM_DIR}
+
+    db_get arrowhead-core-common/sr_host: sr_host=$RET || true
+
+    if [ -z ${sr_host} ]; then
+      sr_host=${OWN_IP}
+    fi
+
+    db_get arrowhead-core-common/db_host; db_host=$RET || true
+
+    mv ${SYSTEM_DIR}/application.properties ${SYSTEM_DIR}/application.properties.orig
+    cat ${SYSTEM_DIR}/application.properties.orig | \
+      sed -r -e "\#^.*spring\.datasource\.url=#s#.*\$#spring.datasource.url=jdbc:mysql://"${db_host}":3306/arrowhead?serverTimezone=Europe/Budapest#"  \
+      -e "\#^.*spring\.datasource\.password=#s#.*\$#spring.datasource.password=${system_passwd}#" \
+      -e "\#^.*server\.address=#s#.*\$#server.address=${OWN_IP}#" \
+      -e "\#^.*sr_address=#s#.*\$#sr_address=${sr_host}#" \
+      -e "\#^.*server\.ssl\.key-store=#s#.*\$#server.ssl.key-store=file:${SYSTEM_DIR}/${SYSTEM_NAME}.p12#" \
+      -e "\#^.*server\.ssl\.key-store-password=#s#.*\$#server.ssl.key-store-password=${AH_PASS_CERT}#" \
+      -e "\#^.*server\.ssl\.key-password=#s#.*\$#server.ssl.key-password=${AH_PASS_CERT}#" \
+      -e "\#^.*server\.ssl\.trust-store=#s#.*\$#server.ssl.trust-store=file:${AH_CONF_DIR}/truststore.p12#" \
+      -e "\#^.*server\.ssl\.trust-store-password=#s#.*\$#server.ssl.trust-store-password=${AH_PASS_CERT}#" > ${SYSTEM_DIR}/application.properties
+
+    rm ${SYSTEM_DIR}/application.properties.orig
+    chown arrowhead:arrowhead ${SYSTEM_DIR}/application.properties
+    chmod 640 ${SYSTEM_DIR}/application.properties
+
+    echo "Starting ${PKG_NAME}..." >&2
+    systemctl daemon-reload
+    systemctl enable ${PKG_NAME}.service
+    systemctl start ${PKG_NAME}.service
+    ;;
+
+   abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+  *)
+    echo "postinst called with unknown argument \`$1'" >&2
+    exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/timemanager/src/deb/control/postrm b/timemanager/src/deb/control/postrm
new file mode 100644
index 000000000..8cc4b3481
--- /dev/null
+++ b/timemanager/src/deb/control/postrm
@@ -0,0 +1,55 @@
+#!/bin/bash
+# postrm script for arrowhead-timemanager
+#
+# see: dh_installdeb(1)
+
+set -e
+
+. /usr/share/debconf/confmodule
+
+SYSTEM_NAME="timemanager"
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <overwriter>
+#          <overwriter-version>
+# for details, see https://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+  purge)
+    AH_CONF_DIR="/etc/arrowhead"
+    AH_SYSTEMS_DIR="${AH_CONF_DIR}/systems"
+    SYSTEM_DIR="${AH_SYSTEMS_DIR}/${SYSTEM_NAME}"
+
+    rm -f \
+      /var/log/arrowhead/${SYSTEM_NAME}*.log \
+      ${SYSTEM_DIR}/log4j2.xml \
+      ${SYSTEM_DIR}/application.properties \
+      ${SYSTEM_DIR}/${SYSTEM_NAME}.p12 \
+
+    rmdir ${SYSTEM_DIR} 2>/dev/null || true
+    db_purge
+    ;;
+  remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+    ;;
+
+  *)
+    echo "postrm called with unknown argument \`$1'" >&2
+    exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/timemanager/src/deb/control/preinst b/timemanager/src/deb/control/preinst
new file mode 100644
index 000000000..9eacdd1fa
--- /dev/null
+++ b/timemanager/src/deb/control/preinst
@@ -0,0 +1,35 @@
+#!/bin/bash
+# preinst script for arrowhead-timemanager
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <new-preinst> `install'
+#        * <new-preinst> `install' <old-version>
+#        * <new-preinst> `upgrade' <old-version>
+#        * <old-preinst> `abort-upgrade' <new-version>
+# for details, see https://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+  install|upgrade)
+    ;;
+
+  abort-upgrade)
+    ;;
+
+  *)
+    echo "preinst called with unknown argument \`$1'" >&2
+    exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/timemanager/src/deb/control/prerm b/timemanager/src/deb/control/prerm
new file mode 100644
index 000000000..1e3a090c1
--- /dev/null
+++ b/timemanager/src/deb/control/prerm
@@ -0,0 +1,45 @@
+#!/bin/bash
+# prerm script for arrowhead-timemanager
+#
+# see: dh_installdeb(1)
+
+set -e
+
+PKG_NAME="arrowhead-timemanager"
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see https://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+  remove)
+    systemctl stop ${PKG_NAME}.service
+    systemctl disable ${PKG_NAME}.service
+    ;;
+
+  upgrade|deconfigure)
+    ;;
+
+  failed-upgrade)
+    ;;
+
+  *)
+    echo "prerm called with unknown argument \`$1'" >&2
+    exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerApplicationInitListener.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerApplicationInitListener.java
new file mode 100644
index 000000000..bbccbac9b
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerApplicationInitListener.java
@@ -0,0 +1,37 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager;
+
+import eu.arrowhead.common.ApplicationInitListener;
+import eu.arrowhead.common.core.CoreSystemService;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import java.util.Base64;
+
+@Component
+public class TimeManagerApplicationInitListener extends ApplicationInitListener {
+
+    //=================================================================================================
+    // members
+
+    //-------------------------------------------------------------------------------------------------
+    @Override
+    protected void customInit(final ContextRefreshedEvent event) {
+        if (sslProperties.isSslEnabled()) {
+            logger.debug("AuthInfo: {}", Base64.getEncoder().encodeToString(publicKey.getEncoded()));
+        }
+    }
+
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerController.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerController.java
new file mode 100644
index 000000000..cba7acdd9
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerController.java
@@ -0,0 +1,104 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Vector;
+import java.util.Iterator;
+
+import org.apache.http.HttpStatus;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.CoreCommonConstants;
+import eu.arrowhead.common.dto.shared.TimeManagerTimeResponseDTO;
+import eu.arrowhead.core.timemanager.service.TimeManagerDriver;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+
+@Api(tags = { CoreCommonConstants.SWAGGER_TAG_ALL })
+@RestController
+@RequestMapping(CommonConstants.TIMEMANAGER_URI)
+public class TimeManagerController {
+
+	private static final String TIME_TZ = "${time.timezone}";
+
+	private final Logger logger = LogManager.getLogger(TimeManagerController.class);
+
+	@Value(TIME_TZ)
+    private String serverTimeZone;
+
+	//=================================================================================================
+	// members
+	
+	private static final String OP_NOT_VALID_ERROR_MESSAGE = " Illegal operation. ";
+	private static final String NOT_FOUND_ERROR_MESSAGE = " Resource not found. ";
+	
+	@Autowired
+	private TimeManagerDriver timeManagerDriver;
+
+	//@Autowired
+	//private TimeManagerDBService timeManagerDBService;
+	
+	//=================================================================================================
+	// methods
+	
+	//-------------------------------------------------------------------------------------------------
+	@ApiOperation(value = "Return an echo message with the purpose of testing the core service availability", response = String.class, tags = { CoreCommonConstants.SWAGGER_TAG_CLIENT })
+	@ApiResponses (value = {
+			@ApiResponse(code = HttpStatus.SC_OK, message = CoreCommonConstants.SWAGGER_HTTP_200_MESSAGE),
+			@ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = CoreCommonConstants.SWAGGER_HTTP_401_MESSAGE)
+	})
+	@GetMapping(path = CommonConstants.ECHO_URI)
+	@ResponseBody public String echoService() {
+		return "Got it!";
+	}
+	
+	//-------------------------------------------------------------------------------------------------
+	@ApiOperation(value = "Interface to the Time service", response = TimeManagerTimeResponseDTO.class, tags = { CoreCommonConstants.SWAGGER_TAG_CLIENT })
+	@ApiResponses (value = {
+			@ApiResponse(code = HttpStatus.SC_OK, message = CoreCommonConstants.SWAGGER_HTTP_200_MESSAGE),
+			@ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = CoreCommonConstants.SWAGGER_HTTP_401_MESSAGE),
+			@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = CoreCommonConstants.SWAGGER_HTTP_500_MESSAGE)
+	})
+	@GetMapping(path= CommonConstants.OP_TIMEMANAGER_TIME, produces = MediaType.APPLICATION_JSON_VALUE)
+	@ResponseBody public TimeManagerTimeResponseDTO timeGet(
+			) {
+		logger.debug("timeGet");
+
+        TimeManagerTimeResponseDTO resp = new TimeManagerTimeResponseDTO(serverTimeZone, timeManagerDriver.isTimeTrusted());
+		return resp;
+	}
+
+	
+	//=================================================================================================
+	// assistant methods
+	
+	
+	//=================================================================================================
+
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerMain.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerMain.java
new file mode 100644
index 000000000..cfdf728fb
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerMain.java
@@ -0,0 +1,40 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.CoreCommonConstants;
+import eu.arrowhead.common.database.repository.RefreshableRepositoryImpl;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@SpringBootApplication(scanBasePackages = CommonConstants.BASE_PACKAGE)
+@EntityScan(CoreCommonConstants.DATABASE_ENTITY_PACKAGE)
+@EnableJpaRepositories(basePackages = CoreCommonConstants.DATABASE_REPOSITORY_PACKAGE, repositoryBaseClass = RefreshableRepositoryImpl.class)
+@EnableSwagger2
+public class TimeManagerMain
+{
+
+    //=================================================================================================
+    // methods
+
+    //-------------------------------------------------------------------------------------------------
+    public static void main(final String[] args) {
+        SpringApplication.run(TimeManagerMain.class, args);
+    }
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerWSConfig.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerWSConfig.java
new file mode 100644
index 000000000..4a0c31042
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeManagerWSConfig.java
@@ -0,0 +1,115 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager;
+
+import java.util.Map;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import eu.arrowhead.common.SecurityUtilities;
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.core.timemanager.TimeWSHandler;
+import eu.arrowhead.core.timemanager.service.TimeManagerDriver;
+
+//import eu.arrowhead.core.datamanager.security.DatamanagerACLFilter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.http.server.ServletServerHttpRequest;
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+ 
+@Configuration
+@EnableWebSocket
+public class TimeManagerWSConfig implements WebSocketConfigurer {
+    
+    //=================================================================================================
+    // members
+        
+    private static final String SYSTEM_REF = "systemId";
+    private static final String SERVICE_REF = "serviceId";
+
+    private final Logger logger = LogManager.getLogger(TimeManagerWSConfig.class);
+
+    @Value(CommonConstants.$SERVER_SSL_ENABLED_WD)
+    private boolean sslEnabled;
+
+    @Value(CommonConstants.$WEBSOCKETS_ENABLED_WD)
+    private boolean websocketsEnabled;
+
+    @Autowired
+    private TimeWSHandler timeWSHandler;
+
+    @Autowired
+    private TimeManagerDriver timeManagerDriver;
+
+    @Override
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
+	    if (websocketsEnabled) {
+            logger.info("WebSocket support enabled");
+            webSocketHandlerRegistry.addHandler(timeWSHandler, CommonConstants.TIMEMANAGER_URI + CommonConstants.OP_TIMEMANAGER_TIME + "/ws").addInterceptors(auctionInterceptor());
+	    } else {
+            logger.info("WebSocket support disabled");
+        }
+    }
+
+    @Bean
+    public HandshakeInterceptor auctionInterceptor() {
+        return new HandshakeInterceptor() {
+            public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, 
+                WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
+
+                String path = request.getURI().getPath();
+                final String serviceId = path.substring(path.lastIndexOf('/') + 1);
+		        path = path.substring(0, path.lastIndexOf('/'));
+                final String systemId = path.substring(path.lastIndexOf('/') + 1);
+                String CN = null;
+
+                if(sslEnabled) {  
+                    if (request instanceof org.springframework.http.server.ServletServerHttpRequest) {
+                        CN = SecurityUtilities.getCertificateCNFromServerRequest((ServletServerHttpRequest)request);
+                        if(CN == null) {
+                            logger.info("No valid client certificate found");
+                            return false;
+                        }
+                        attributes.put(CommonConstants.COMMON_NAME_FIELD_NAME, CN);
+                    } else {
+                        return false;
+                    }
+                }
+
+                // Add to the websocket session
+                attributes.put(SYSTEM_REF, systemId);
+                attributes.put(SERVICE_REF, serviceId);
+                
+                return true;
+            }
+
+            public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
+                // tbd
+            }
+
+        };
+    }
+}
+
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeWSHandler.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeWSHandler.java
new file mode 100644
index 000000000..eea78f7ad
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/TimeWSHandler.java
@@ -0,0 +1,88 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager;
+
+import java.nio.charset.StandardCharsets;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.Utilities;
+import eu.arrowhead.common.dto.shared.TimeManagerTimeResponseDTO;
+import eu.arrowhead.core.timemanager.service.TimeManagerDriver;
+
+
+@Component
+@EnableScheduling
+public class TimeWSHandler extends TextWebSocketHandler {
+ 
+    //=================================================================================================
+    // members
+
+    private final Logger logger = LogManager.getLogger(TimeWSHandler.class);
+    
+    private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
+ 
+    @Value("${server.ssl.enabled}")
+    private boolean sslEnabled;
+
+    @Value("${time.timezone}")
+    private String serverTimeZone;
+
+    @Autowired
+    TimeManagerDriver timeManagerDriver;
+
+    //=================================================================================================
+    // methods
+
+    @Override
+    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
+        sessions.add(session);
+        super.afterConnectionEstablished(session);
+    }
+ 
+    @Override
+    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
+        sessions.remove(session);
+        super.afterConnectionClosed(session, status);
+    }
+ 
+    @Scheduled(fixedDelay = 1000 * 30, initialDelay = 1000)
+    public void sendOutTimeMessages() {
+        sessions.forEach(webSocketSession -> {
+            try {
+                TimeManagerTimeResponseDTO response = new TimeManagerTimeResponseDTO(serverTimeZone, timeManagerDriver.isTimeTrusted());
+                TextMessage msg = new TextMessage(Utilities.toJson(response).getBytes(StandardCharsets.UTF_8));
+                webSocketSession.sendMessage(msg);
+            } catch (IOException e) {
+                logger.error("Error occurred.", e);
+            }
+        });
+        
+    }
+}
+
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/database/service/TimeManagerDBService.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/database/service/TimeManagerDBService.java
new file mode 100644
index 000000000..e86e77118
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/database/service/TimeManagerDBService.java
@@ -0,0 +1,76 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager.database.service;
+
+import java.util.Optional;
+import java.util.List;
+import java.util.ArrayList; 
+import java.util.Iterator; 
+import java.util.Vector;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.CoreCommonConstants;
+import eu.arrowhead.common.Utilities;
+import eu.arrowhead.common.dto.internal.DTOConverter;
+import eu.arrowhead.common.exception.ArrowheadException;
+import eu.arrowhead.common.exception.InvalidParameterException;
+
+import java.sql.DriverManager;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Array;
+import java.sql.SQLException;
+
+
+@Service
+public class TimeManagerDBService {
+	//=================================================================================================
+	// members
+
+    public static final int MAX_ALLOWED_TIME_DIFF  = 1000; //milliseconds
+	
+	@Value("${spring.datasource.url}")
+	private String url;
+	@Value("${spring.datasource.username}")
+	private String user;
+	@Value("${spring.datasource.password}")
+	private String password;
+
+	private static final Logger logger = LogManager.getLogger(TimeManagerDBService.class);
+	
+	//=================================================================================================
+	// methods
+
+	//-------------------------------------------------------------------------------------------------
+	private Connection getConnection() throws SQLException {
+	  return DriverManager.getConnection(url, user, password);
+	}
+
+
+	//-------------------------------------------------------------------------------------------------
+	private void closeConnection(final Connection conn) throws SQLException {
+	  conn.close();
+	}
+
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/security/TimeManagerAccessControlFilter.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/security/TimeManagerAccessControlFilter.java
new file mode 100644
index 000000000..58d4c058b
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/security/TimeManagerAccessControlFilter.java
@@ -0,0 +1,55 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager.security;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.CoreCommonConstants;
+import eu.arrowhead.common.SecurityUtilities;
+import eu.arrowhead.common.dto.shared.CertificateType;
+import eu.arrowhead.common.security.CoreSystemAccessControlFilter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+
+import eu.arrowhead.common.Utilities;
+import eu.arrowhead.common.exception.AuthException;
+
+import java.util.Map;
+
+@Component
+@ConditionalOnProperty(name = CommonConstants.SERVER_SSL_ENABLED, matchIfMissing = true) 
+public class TimeManagerAccessControlFilter extends CoreSystemAccessControlFilter {
+	
+	//=================================================================================================
+        // members
+        
+	//=================================================================================================
+	// assistant methods
+
+	//-------------------------------------------------------------------------------------------------
+	@Override
+	protected void checkClientAuthorized(final String clientCN, final String method, final String requestTarget, final String requestJSON, final Map<String,String[]> queryParams) {
+		super.checkClientAuthorized(clientCN, method, requestTarget, requestJSON, queryParams);
+
+		if (requestTarget.endsWith(CommonConstants.ECHO_URI)) {
+                        // Everybody in the local cloud can test the server => no further check is necessary
+                        return;
+		} 
+
+	}
+
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/security/TimemanagerSecurityConfig.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/security/TimemanagerSecurityConfig.java
new file mode 100644
index 000000000..fda7740c1
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/security/TimemanagerSecurityConfig.java
@@ -0,0 +1,24 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager.security;
+
+import eu.arrowhead.common.security.DefaultSecurityConfig;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+
+@Configuration
+@EnableWebSecurity
+public class TimemanagerSecurityConfig extends DefaultSecurityConfig {
+
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/service/TimeManagerDriver.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/service/TimeManagerDriver.java
new file mode 100644
index 000000000..e335283ab
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/service/TimeManagerDriver.java
@@ -0,0 +1,122 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+
+package eu.arrowhead.core.timemanager.service;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.annotation.Resource;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+import org.springframework.web.util.UriComponents;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.CoreCommonConstants;
+import eu.arrowhead.common.Utilities;
+import eu.arrowhead.common.core.CoreSystemService;
+import eu.arrowhead.common.exception.ArrowheadException;
+import eu.arrowhead.common.exception.BadPayloadException;
+import eu.arrowhead.common.exception.InvalidParameterException;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.SocketException;
+import org.apache.commons.net.ntp.NTPUDPClient;
+import org.apache.commons.net.ntp.TimeInfo;
+
+
+@Component
+@EnableScheduling
+public class TimeManagerDriver {
+
+	//=================================================================================================
+	// members
+
+	private static final String NTP_SERVER_LIST = "${ntp.server.list}";
+	private static final String TIME_OFFSET_THRESHOLD = "${time.offset.threshold}";
+
+	private static final int TIME_CHECK_INTERVAL = 1000 * 60;
+	private static final int TIME_CHECK_INITIAL = 1000 * 1;
+
+	private final Logger logger = LogManager.getLogger(TimeManagerDriver.class);
+
+	@Value(NTP_SERVER_LIST)
+    private String serverList;
+
+	@Value(TIME_OFFSET_THRESHOLD)
+	private long timeOffsetThreshold; 
+
+	private AtomicBoolean isTimeTrusted = new AtomicBoolean(true);
+
+	//=================================================================================================
+	// methods
+
+	//-------------------------------------------------------------------------------------------------
+	public boolean isTimeTrusted() {
+		return isTimeTrusted.get();
+	}
+
+	//-------------------------------------------------------------------------------------------------
+	@Scheduled(fixedDelay = TIME_CHECK_INTERVAL, initialDelay = TIME_CHECK_INITIAL)
+    public void checkExternalTimeServer() {
+		logger.debug("Checking external time!");
+		  
+		try {
+			final NTPUDPClient client = new NTPUDPClient();
+			client.setDefaultTimeout(10000);
+			client.open();
+			final InetAddress hostAddr = InetAddress.getByName(serverList);
+			final TimeInfo info = client.getTime(hostAddr);
+			client.close();
+			if (info == null) {
+				isTimeTrusted.set(false);
+				logger.debug("Couldn't get a response, something is wrong!");
+				return;
+			}
+			info.computeDetails();
+ 
+			if (info.getOffset() == null || info.getDelay() == null) {
+				isTimeTrusted.set(false);
+				logger.debug("Response details are wrong!");
+				return;
+			}
+
+			final Long offsetMillis = info.getOffset();
+			final Long delayMillis = info.getDelay();
+			final long offset = offsetMillis.longValue();
+			logger.debug("Roundtrip delay(ms)=" + delayMillis + ", clock offset(ms)=" + offsetMillis);
+
+			if (offset < timeOffsetThreshold) {
+				isTimeTrusted.set(true);
+		  	} else {
+			  logger.debug("Time offset too large, something is wrong!");
+			  isTimeTrusted.set(false);
+		  	}
+		} catch (final Exception e) {
+			logger.debug("Exception occured: " + e.toString());
+			isTimeTrusted.set(false);
+			return;
+		}
+	  }
+	//=================================================================================================
+
+}
diff --git a/timemanager/src/main/java/eu/arrowhead/core/timemanager/swagger/TimeManagerSwaggerConfig.java b/timemanager/src/main/java/eu/arrowhead/core/timemanager/swagger/TimeManagerSwaggerConfig.java
new file mode 100644
index 000000000..8640846e6
--- /dev/null
+++ b/timemanager/src/main/java/eu/arrowhead/core/timemanager/swagger/TimeManagerSwaggerConfig.java
@@ -0,0 +1,41 @@
+/********************************************************************************
+ * Copyright (c) 2021 {Lulea University of Technology}
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 
+ *
+ * Contributors: 
+ *   {Lulea University of Technology} - implementation
+ *   Arrowhead Consortia - conceptualization 
+ ********************************************************************************/
+package eu.arrowhead.core.timemanager.swagger;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import eu.arrowhead.common.CommonConstants;
+import eu.arrowhead.common.swagger.DefaultSwaggerConfig;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@EnableSwagger2
+@Configuration
+public class TimemanagerSwaggerConfig extends DefaultSwaggerConfig {
+	
+	//=================================================================================================
+	// methods
+
+	//-------------------------------------------------------------------------------------------------
+	public TimemanagerSwaggerConfig() {
+		super(CommonConstants.CORE_SYSTEM_TIMEMANAGER);
+	}
+	
+	//-------------------------------------------------------------------------------------------------
+	@Bean
+	public Docket customizeSwagger() {
+		return configureSwaggerForCoreSystem(this.getClass().getPackageName());
+	}
+}
diff --git a/timemanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/timemanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json
new file mode 100644
index 000000000..5b665b9a5
--- /dev/null
+++ b/timemanager/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -0,0 +1,47 @@
+{"properties": [
+  {
+    "name": "sr_address",
+    "type": "java.lang.String",
+    "description": "A description for 'sr_address'"
+  },
+  {
+    "name": "sr_port",
+    "type": "java.lang.Integer",
+    "description": "A description for 'sr_port'"
+  },
+  {
+    "name": "disable.hostname.verifier",
+    "type": "java.lang.Boolean",
+    "description": "A description for 'disable.hostname.verifier'"
+  },
+  {
+    "name": "log_all_request_and_response",
+    "type": "java.lang.Boolean",
+    "description": "A description for 'log_all_request_and_response'"
+  },
+  {
+    "name": "core_system_name",
+    "type": "java.lang.String",
+    "description": "A description for 'core_system_name'"
+  },
+  {
+    "name": "time.timezone",
+    "type": "java.lang.String",
+    "description": "The Local cloud time zone"
+  },
+  {
+    "name": "ntp.server.list",
+    "type": "java.lang.String",
+    "description": "The NTP server to use"
+  },
+  {
+    "name": "time.offset.threshold",
+    "type": "java.lang.Integer",
+    "description": "The maximum allowed time difference for a trusted NTP server"
+  },
+  {
+    "name": "websockets.enabled",
+    "type": "java.lang.Boolean",
+    "description": "Enables WebSocket support"
+  }
+]}
\ No newline at end of file
diff --git a/timemanager/src/main/resources/application.properties b/timemanager/src/main/resources/application.properties
new file mode 100644
index 000000000..06c74b30f
--- /dev/null
+++ b/timemanager/src/main/resources/application.properties
@@ -0,0 +1,66 @@
+############################################
+###       APPLICATION PARAMETERS         ###
+############################################
+
+# Database connection (mandatory)
+# Change the server timezone if neccessary
+spring.datasource.url=jdbc:mysql://127.0.0.1:3306/arrowhead?serverTimezone=Europe/Budapest  
+spring.datasource.username=timemanager
+spring.datasource.password=xyp2XEAu5Tbc41g
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
+# use true only for debugging
+spring.jpa.show-sql=false  
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.hibernate.ddl-auto=none
+
+# Parameters of TimeManager web-server
+server.address=0.0.0.0
+server.port=8463
+domain.name=127.0.0.1
+domain.port=8463
+
+# Websockets
+websockets.enabled=true
+
+############################################
+###       CUSTOM PARAMETERS              ###
+############################################
+
+# Name of the core system
+core_system_name=TIMEMANAGER
+
+# Show all request/response in debug log
+log_all_request_and_response=false
+
+# Service Registry web-server parameters (to register the TimeManager services)
+sr_address=127.0.0.1
+sr_port=8443
+
+time.timezone=Europe/Budapest
+ntp.server.list=pool.ntp.org
+time.offset.threshold=5000
+
+############################################
+###           SECURE MODE                ###
+############################################
+
+# configure secure mode
+
+# Set this to false to disable https mode
+server.ssl.enabled=true
+
+server.ssl.key-store-type=PKCS12
+server.ssl.key-store=classpath:certificates/timemanager.p12
+server.ssl.key-store-password=123456
+server.ssl.key-alias=timemanager
+server.ssl.key-password=123456
+server.ssl.client-auth=need
+server.ssl.trust-store-type=PKCS12
+server.ssl.trust-store=classpath:certificates/truststore.p12
+server.ssl.trust-store-password=123456
+
+#If true, http client does not check whether the hostname is match one of the server's SAN in its certificate
+#Just for testing, DO NOT USE this feature in production environment 
+disable.hostname.verifier=false
diff --git a/timemanager/src/main/resources/certificates/timemanager.p12 b/timemanager/src/main/resources/certificates/timemanager.p12
new file mode 100644
index 000000000..52456f3a7
Binary files /dev/null and b/timemanager/src/main/resources/certificates/timemanager.p12 differ
diff --git a/timemanager/src/main/resources/certificates/truststore.p12 b/timemanager/src/main/resources/certificates/truststore.p12
new file mode 100644
index 000000000..57c1c5f43
Binary files /dev/null and b/timemanager/src/main/resources/certificates/truststore.p12 differ
diff --git a/timemanager/src/main/resources/log4j2.xml b/timemanager/src/main/resources/log4j2.xml
new file mode 100644
index 000000000..4072dc607
--- /dev/null
+++ b/timemanager/src/main/resources/log4j2.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN" monitorInterval="30">
+    <Properties>
+        <Property name="LOG_PATTERN">
+            %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
+        </Property>
+		<Property name="JDBC_LEVEL">INFO</Property>
+		<Property name="CONSOLE_FILE_LEVEL">INFO</Property>
+		<Property name="LOG_DIR">.</Property>
+    </Properties>
+    <Appenders>
+        <Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
+            <PatternLayout pattern="${LOG_PATTERN}"/>
+        </Console>
+		<RollingFile name="FileAppender" fileName="${LOG_DIR}/timemanager.log" filePattern="${LOG_DIR}/timemanager-%d{yyyy-MM-dd}-%i.log">
+	    	<PatternLayout>
+	        	<Pattern>${LOG_PATTERN}</Pattern>
+	    	</PatternLayout>
+	    	<Policies>
+	        	<SizeBasedTriggeringPolicy size="100MB" />
+	    	</Policies>
+	    	<DefaultRolloverStrategy max="10" />
+		</RollingFile>
+		<JDBC name="MySQLDatabase" tableName="logs">
+         	<ConnectionFactory class="eu.arrowhead.common.log4j2.JDBCConnectionFactoryForLog4J2" method="getConnection" />
+         	<Column name="log_id" pattern="%u" />
+         	<Column name="entry_date" isEventTimestamp="true" />
+         	<Column name="logger" pattern="%logger" />
+         	<Column name="log_level" pattern="%level" />
+         	<Column name="message" pattern="%m" />
+         	<Column name="exception" pattern="%throwable " />
+			<ThresholdFilter level="${JDBC_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
+      	</JDBC>
+    </Appenders>
+    <Loggers>
+		<Root level="WARN">
+            <AppenderRef ref="ConsoleAppender" /> <!-- comment out this one in production environment -->
+            <AppenderRef ref="FileAppender" />
+        </Root>
+		<AsyncLogger name="eu.arrowhead" level="${JDBC_LEVEL}" additivity="true">
+            <AppenderRef ref="MySQLDatabase" />			
+    	</AsyncLogger>
+		<Logger name="eu.arrowhead.common" level="${CONSOLE_FILE_LEVEL}" additivity="true"></Logger>
+		<Logger name="eu.arrowhead.core" level="${CONSOLE_FILE_LEVEL}" additivity="true"></Logger>		
+    </Loggers>
+</Configuration>
diff --git a/timemanager/src/main/resources/swagger/swagger-ui.html b/timemanager/src/main/resources/swagger/swagger-ui.html
new file mode 100644
index 000000000..a7b2aa321
--- /dev/null
+++ b/timemanager/src/main/resources/swagger/swagger-ui.html
@@ -0,0 +1,75 @@
+<!-- HTML for static distribution bundle build -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>TimeManager</title>
+  <link rel="stylesheet" type="text/css" href="webjars/springfox-swagger-ui/springfox.css?v=2.9.2" >
+  <link rel="stylesheet" type="text/css" href="webjars/springfox-swagger-ui/swagger-ui.css?v=2.9.2" >
+  <link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/favicon-32x32.png?v=2.9.2" sizes="32x32" />
+  <link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/favicon-16x16.png?v=2.9.2" sizes="16x16" />
+  <style>
+    html
+    {
+      box-sizing: border-box;
+      overflow: -moz-scrollbars-vertical;
+      overflow-y: scroll;
+    }
+    *,
+    *:before,
+    *:after
+    {
+      box-sizing: inherit;
+    }
+
+    body {
+      margin:0;
+      background: #fafafa;
+    }
+  </style>
+</head>
+
+<body>
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
+  <defs>
+    <symbol viewBox="0 0 20 20" id="unlocked">
+      <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
+    </symbol>
+
+    <symbol viewBox="0 0 20 20" id="locked">
+      <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
+    </symbol>
+
+    <symbol viewBox="0 0 20 20" id="close">
+      <path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
+    </symbol>
+
+    <symbol viewBox="0 0 20 20" id="large-arrow">
+      <path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
+    </symbol>
+
+    <symbol viewBox="0 0 20 20" id="large-arrow-down">
+      <path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
+    </symbol>
+
+
+    <symbol viewBox="0 0 24 24" id="jump-to">
+      <path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
+    </symbol>
+
+    <symbol viewBox="0 0 24 24" id="expand">
+      <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
+    </symbol>
+
+  </defs>
+</svg>
+
+<div id="swagger-ui"></div>
+
+<script src="webjars/springfox-swagger-ui/swagger-ui-bundle.js?v=2.9.2"> </script>
+<script src="webjars/springfox-swagger-ui/swagger-ui-standalone-preset.js?v=2.9.2"> </script>
+<script src="webjars/springfox-swagger-ui/springfox.js?v=2.9.2"> </script>
+</body>
+
+</html>
diff --git a/timemanager/src/test/java/eu/arrowhead/core/timemanager/StandaloneModeInTimeManagerTests.java b/timemanager/src/test/java/eu/arrowhead/core/timemanager/StandaloneModeInTimeManagerTests.java
new file mode 100644
index 000000000..768199a6d
--- /dev/null
+++ b/timemanager/src/test/java/eu/arrowhead/core/timemanager/StandaloneModeInTimeManagerTests.java
@@ -0,0 +1,9 @@
+package eu.arrowhead.core.timemanager;
+
+import eu.arrowhead.common.testhelper.StandaloneModeInTests;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StandaloneModeInTimeManagerTests extends StandaloneModeInTests {
+
+}
diff --git a/timemanager/src/test/java/eu/arrowhead/core/timemanager/TimeManagerControllerSystemTest.java b/timemanager/src/test/java/eu/arrowhead/core/timemanager/TimeManagerControllerSystemTest.java
new file mode 100644
index 000000000..2b1ff53b3
--- /dev/null
+++ b/timemanager/src/test/java/eu/arrowhead/core/timemanager/TimeManagerControllerSystemTest.java
@@ -0,0 +1,98 @@
+package eu.arrowhead.core.timemanager;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.arrowhead.common.exception.InvalidParameterException;
+import eu.arrowhead.core.timemanager.database.service.TimeManagerDBService;
+import eu.arrowhead.common.dto.shared.TimeManagerTimeResponseDTO;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@ContextConfiguration(classes = {TimeManagerTestContext.class})
+public class TimeManagerControllerSystemTest {
+
+    //=================================================================================================
+    // test data
+
+    //=================================================================================================
+    // members
+
+    @Autowired
+    private WebApplicationContext wac;
+
+    private MockMvc mockMvc;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @MockBean(name = "mockTimeManagerDBService")
+    private TimeManagerDBService timeManagerDBService;
+
+    private static final String TIMEMANAGER_ECHO_URI  = "/timemanager/echo";
+    private static final String TIMEMANAGER_TIME_URI  = "/timemanager/time";
+
+    //=================================================================================================
+    // methods
+
+    //-------------------------------------------------------------------------------------------------
+    @Before
+    public void setup() {
+        reset(timeManagerDBService);
+        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+    }
+
+    //=================================================================================================
+    // Tests of Echo service
+
+    @Test
+    public void echoTM() throws Exception {
+        final MvcResult response = this.mockMvc.perform(get(TIMEMANAGER_ECHO_URI)
+                                               .accept(MediaType.APPLICATION_JSON))
+                                               .andExpect(status().isOk())
+                                               .andReturn();
+        assertEquals("Got it!", response.getResponse().getContentAsString());
+    }
+
+    @Test
+    public void testTime() throws Exception {
+        final MvcResult response = this.mockMvc.perform(get(TIMEMANAGER_TIME_URI)
+                                               .accept(MediaType.APPLICATION_JSON))
+                                               .andExpect(status().isOk())
+                                               .andReturn();
+        final TimeManagerTimeResponseDTO responseBody = objectMapper.readValue(response.getResponse().getContentAsString(), TimeManagerTimeResponseDTO.class);
+        assertNotEquals(0, responseBody.getEpoch());
+    }
+
+}
diff --git a/timemanager/src/test/java/eu/arrowhead/core/timemanager/TimeManagerTestContext.java b/timemanager/src/test/java/eu/arrowhead/core/timemanager/TimeManagerTestContext.java
new file mode 100644
index 000000000..60946f7c3
--- /dev/null
+++ b/timemanager/src/test/java/eu/arrowhead/core/timemanager/TimeManagerTestContext.java
@@ -0,0 +1,32 @@
+package eu.arrowhead.core.timemanager;
+
+import eu.arrowhead.common.CommonConstants;
+import org.mockito.Mockito;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.context.annotation.Primary;
+
+@Configuration
+@ComponentScan(basePackages = CommonConstants.BASE_PACKAGE,
+        excludeFilters = {
+                @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*database.*"),
+                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = TimeManagerMain.class),
+        })
+@SpringBootApplication()
+public class TimeManagerTestContext {
+
+    //=================================================================================================
+    // methods
+
+    public TimeManagerTestContext() {
+    }
+
+    //-------------------------------------------------------------------------------------------------
+
+}
