Merge branch 'develop' into DLAB-1594-2
diff --git a/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py b/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py
index 3864229..0c761a5 100644
--- a/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py
+++ b/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py
@@ -1186,7 +1186,7 @@
                 'https://repo1.maven.org/maven2/org/jfree/jfreechart/{0}/jfreechart-{0}.jar'.format('1.0.19'),
                 'https://repo1.maven.org/maven2/org/jfree/jcommon/{0}/jcommon-{0}.jar'.format('1.0.24'),
                 '--no-check-certificate https://brunelvis.org/jar/spark-kernel-brunel-all-{0}.jar'.format('2.3'),
-                'http://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree-pip/toree-0.2.0.tar.gz',
+                'http://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree-pip/toree-0.3.0.tar.gz',
                 'https://download2.rstudio.org/server/trusty/amd64/rstudio-server-{}-amd64.deb'.format(
                     configuration['notebook_rstudio_version']),
                 'http://us.download.nvidia.com/XFree86/Linux-x86_64/{0}/NVIDIA-Linux-x86_64-{0}.run'.format(
@@ -1222,10 +1222,10 @@
                     configuration['notebook_livy_version']),
                 'https://dl.bintray.com/spark-packages/maven/tapanalyticstoolkit/spark-tensorflow-connector/'
                 '1.0.0-s_2.11/spark-tensorflow-connector-1.0.0-s_2.11.jar',
-                'https://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree/'
-                'toree-0.2.0-incubating-bin.tar.gz',
-                'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.2.0-incubating/'
-                'toree-assembly-0.2.0-incubating.jar',
+                'https://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree/'
+                'toree-0.3.0-incubating-bin.tar.gz',
+                'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.3.0-incubating/'
+                'toree-assembly-0.3.0-incubating.jar',
                 'https://cran.r-project.org/src/contrib/Archive/keras/keras_{}.tar.gz'.format(
                     configuration['notebook_keras_version'])
             ]
diff --git a/infrastructure-provisioning/scripts/jenkins/sonar.py b/infrastructure-provisioning/scripts/jenkins/sonar.py
new file mode 100644
index 0000000..207ffef
--- /dev/null
+++ b/infrastructure-provisioning/scripts/jenkins/sonar.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+import requests
+import sys
+import time
+import urllib
+
+time.sleep(30)  # wait for new code to be analyzed by SonarQube
+
+PROJECT_KEY = urllib.quote(sys.argv[1])
+TOKEN = sys.argv[2]
+
+
+def get_sonarqube_status():
+    response = requests.get('http://localhost:9000/sonar/api/qualitygates/project_status?projectKey=' + PROJECT_KEY,
+                            auth=(TOKEN, '')).json()
+    return response['projectStatus']['status']
+
+
+print(get_sonarqube_status())
diff --git a/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py b/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py
index e5aacb8..2089613 100644
--- a/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py
+++ b/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py
@@ -53,6 +53,7 @@
 caffe2_version = os.environ['notebook_caffe2_version']
 cmake_version = os.environ['notebook_cmake_version']
 cntk_version = os.environ['notebook_cntk_version']
+cntk2_version = os.environ['notebook_cntk2_version']
 mxnet_version = os.environ['notebook_mxnet_version']
 python3_version = "3.4"
 scala_link = "http://www.scala-lang.org/files/archive/"
@@ -173,10 +174,10 @@
     if os.environ['application'] == 'deeplearning':
         print("Installing Caffe2")
         install_caffe2(args.os_user, caffe2_version, cmake_version)
-        print("Installing Torch")
-        install_torch(args.os_user)
+        #print("Installing Torch")
+        #install_torch(args.os_user)
         print("Install CNTK Python library")
-        install_cntk(args.os_user, cntk_version)
+        install_cntk(args.os_user, cntk2_version, cntk_version)
         print("Installing MXNET")
         install_mxnet(args.os_user, mxnet_version)
 
@@ -202,3 +203,25 @@
     if os.environ['application'] == 'zeppelin' and os.environ['notebook_r_enabled'] == 'true':
         print("Install additional R packages")
         install_r_packages(args.os_user)
+
+    # INSTALL LIVY
+    if not exists('/home/{0}/.ensure_dir/livy_ensured'.format(args.os_user)):
+        livy_version = '0.7.0'
+        sudo(
+            'wget -nv --timeout=30 --tries=5 --retry-connrefused https://archive.apache.org/dist/incubator/livy/{0}-incubating/apache-livy-{0}-incubating-bin.zip -P /tmp/'.format(
+                livy_version))
+        sudo('unzip -q /tmp/apache-livy-{}-incubating-bin.zip -d /tmp/'.format(livy_version))
+        sudo('mv /tmp/apache-livy-{}-incubating-bin /opt/livy'.format(livy_version))
+        sudo('mkdir /var/log/livy')
+        put('~/templates/livy-env.sh', '/tmp/livy-env.sh')
+        sudo('mv /tmp/livy-env.sh /opt/livy/conf/livy-env.sh')
+        sudo('chown -R -L {0}:{0} /opt/livy/'.format(args.os_user))
+        sudo('chown -R {0}:{0} /var/log/livy'.format(args.os_user))
+        put('~/templates/livy.service', '/tmp/livy.service')
+        sudo("sed -i 's|OS_USER|{}|' /tmp/livy.service".format(args.os_user))
+        sudo('mv /tmp/livy.service /etc/systemd/system/livy.service')
+        sudo('systemctl daemon-reload')
+        sudo('systemctl enable livy.service')
+        sudo('systemctl start livy.service')
+        sudo('touch /home/{0}/.ensure_dir/livy_ensured'.format(args.os_user))
+
diff --git a/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py b/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py
index 741ca18..b2e93d0 100644
--- a/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py
+++ b/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py
@@ -56,14 +56,15 @@
 caffe2_version = os.environ['notebook_caffe2_version']
 cmake_version = os.environ['notebook_cmake_version']
 cntk_version = os.environ['notebook_cntk_version']
+cntk2_version = os.environ['notebook_cntk2_version']
 mxnet_version = os.environ['notebook_mxnet_version']
-keras_version = '2.0.8'
+keras_version = os.environ['notebook_keras_version']
 theano_version = os.environ['notebook_theano_version']
-tensorflow_version = '1.4.0'
-cuda_version = '8.0'
-cuda_file_name = 'cuda_8.0.44_linux-run'
-cudnn_version = '6.0'
-cudnn_file_name = 'cudnn-8.0-linux-x64-v6.0.tgz'
+tensorflow_version = os.environ['notebook_tensorflow_version']
+cuda_version = os.environ['notebook_cuda_version']
+cuda_file_name = os.environ['notebook_cuda_file_name']
+cudnn_version = os.environ['notebook_cudnn_version']
+cudnn_file_name = os.environ['notebook_cudnn_file_name']
 
 if args.region == 'cn-north-1':
     spark_link = "http://mirrors.hust.edu.cn/apache/spark/spark-" + spark_version + "/spark-" + spark_version + \
@@ -83,6 +84,9 @@
     if not exists('/home/{}/.ensure_dir/itorch_ensured'.format(os_user)):
         run('git clone https://github.com/facebook/iTorch.git')
         with cd('/home/{}/iTorch/'.format(os_user)):
+            run('luarocks install luacrypto')
+            run('luarocks install uuid')
+            run('luarocks install lzmq')
             run('luarocks make')
         sudo('cp -rf /home/{0}/.ipython/kernels/itorch/ /home/{0}/.local/share/jupyter/kernels/'.format(os_user))
         sudo('chown -R {0}:{0} /home/{0}/.local/share/jupyter/'.format(os_user))
@@ -125,10 +129,10 @@
     install_keras(args.os_user, keras_version)
     print("Installing Caffe2")
     install_caffe2(args.os_user, caffe2_version, cmake_version)
-    print("Installing Torch")
-    install_torch(args.os_user)
+    #print("Installing Torch")
+    #install_torch(args.os_user)
     print("Install CNTK Python library")
-    install_cntk(args.os_user, cntk_version)
+    install_cntk(args.os_user,cntk2_version, cntk_version)
     print("Installing MXNET")
     install_mxnet(args.os_user, mxnet_version)
 
@@ -149,8 +153,8 @@
     ensure_pyspark_local_kernel(args.os_user, pyspark_local_path_dir, templates_dir, spark_version)
     print("Install py3spark local kernel for Jupyter")
     ensure_py3spark_local_kernel(args.os_user, py3spark_local_path_dir, templates_dir, spark_version)
-    print("Installing ITorch kernel for Jupyter")
-    install_itorch(args.os_user)
+    #print("Installing ITorch kernel for Jupyter")
+    #install_itorch(args.os_user)
 
     # INSTALL UNGIT
     print("Install nodejs")
@@ -169,7 +173,7 @@
     ensure_additional_python_libs(args.os_user)
     print("Install Matplotlib")
     ensure_matplot(args.os_user)
-    
+
     #POST INSTALLATION PROCESS
     print("Updating pyOpenSSL library")
     update_pyopenssl_lib(args.os_user)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/conf/dlab.ini b/infrastructure-provisioning/src/general/conf/dlab.ini
index 98b621d..e11158e 100644
--- a/infrastructure-provisioning/src/general/conf/dlab.ini
+++ b/infrastructure-provisioning/src/general/conf/dlab.ini
@@ -62,7 +62,7 @@
 network_type = public
 ### Additional tags in format 'Key1:Value1;Key2:Value2'
 # additional_tags =
-pip_version = 9.0.3
+pip_version = 20.1
 ### Billing tag key
 billing_tag_key = product
 ### Billing tag value
@@ -119,7 +119,7 @@
 ### Amazon zone letter for ssn, edge and notebook subnet provisioning
 # zone =
 ### Amazon ami name based on debian conf_os_family for all dlab instances
-debian_image_name = ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20190212
+debian_image_name = ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20200112
 ### Amazon ami name based on RedHat conf_os_family for all dlab instances
 redhat_image_name = RHEL-7.4_HVM-20180103-x86_64-2-Hourly2-GP2
 ### Amazon account ID
@@ -151,7 +151,7 @@
 ### Slave node size for Data Engine
 # dataengine_slave_size =
 ### Azure image name based on debian conf_os_family for all dlab instances
-debian_image_name = Canonical_UbuntuServer_16.04-LTS
+debian_image_name = Canonical_UbuntuServer_18.04-LTS
 ### Azure image name based on RedHat conf_os_family for all dlab instances
 redhat_image_name = RedHat_RHEL_7.3
 ### Azure AD user name
@@ -189,7 +189,7 @@
 ### GCP zone name for whole dlab provisioning
 zone = us-west1-a
 ### GCP ami name based on debian conf_os_family for all dlab instances
-debian_image_name = /projects/ubuntu-os-cloud/global/images/ubuntu-1604-xenial-v20190807
+debian_image_name = /projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20200317
 ### GCP ami name based on RedHat conf_os_family for all dlab instances
 redhat_image_name =
 ### Prefix of the private subnet
@@ -223,6 +223,8 @@
 # user_name =
 ### Elastic IP which will be associated with Edge node
 # elastic_ip =
+### Edge node is NAT
+is_nat = true
 
 #--- [notebook] section contains all parameters that are using for all notebooks provisioning ---#
 [notebook]
@@ -237,7 +239,7 @@
 ### Version of Jupyter to be installed on notebook
 jupyter_version = 6.0.2
 ### Version of TensorFlow to be installed on notebook
-tensorflow_version = 1.8.0
+tensorflow_version = 2.1.0
 ### Version of Zeppelin to be installed on notebook
 zeppelin_version = 0.8.2
 ### Version of Rstudio to be installed on notebook
@@ -251,30 +253,34 @@
 ### R China mirror
 r_mirror = http://mirror.lzu.edu.cn/CRAN/
 ### NVidia driver version for Tensor/DeepLearning notebooks
-nvidia_version = 418.43
+nvidia_version = 418.126.02
 ### Caffe library version for DeepLearning notebook
 caffe_version = 1.0
 ### Caffe2 library version for DeepLearning notebook
-caffe2_version = 0.4.0
+caffe2_version = 1.5
+### Pytorch branch used during caffe2 installation for DeepLearning notebook
+pytorch_branch = release/1.5
 ### Cmake version for DeepLearning notebook
-cmake_version = 3.11.3
-### CNTK library version for DeepLearning notebook
+cmake_version = 3.15.5
+### CNTK library version for DeepLearning notebook for python2
 ### All releases 2.4+ officially only support Ubuntu 16.04.
-cntk_version = 2.3.1
-### MXNet library version for DeepLearning notebook
-mxnet_version = 1.3.1
+cntk2_version = 2.3.1
+### CNTK library version for DeepLearning notebook for python3
+cntk_version = 2.7
+### MXNet library version for DeepLearning notebook for python
+mxnet_version = 1.6.0
 ### Keras library version for Tensor/DeepLearning notebook
 keras_version = 2.1.6
 ### Theano library version for Tensor/DeepLearning notebook
 theano_version = 1.0.3
 ### Version of CUDA
-cuda_version = 9.0
+cuda_version = 10.1
 ### Name of CUDA file
-cuda_file_name = cuda_9.0.176_384.81_linux-run
+cuda_file_name = cuda_10.1.243_418.87.00_linux.run
 ### Version of CUDNN
-cudnn_version = 7.1.4
+cudnn_version = 7.6.5
 ### Name of CUDNN file
-cudnn_file_name = cudnn-9.0-linux-x64-v7.1.tgz
+cudnn_file_name = cudnn-10.1-linux-x64-v7.6.5.32.tgz
 ### R enabled on Jupyter/Zeppelin notebook
 r_enabled = true
 ### Temporary fixed python libraries due to dependencies
@@ -283,7 +289,9 @@
 ### Version of ungit if previous needed. Use latest as default.
 ungit_version = 1.4.36
 ### Numpy version
-numpy_version = 1.14.3
+numpy_version = 1.18.3
+### Numpy version for python 2
+numpy2_version = 1.16.6
 ### Apache Ivy version
 ivy_version = 2.4.0
 ### Matplotlib version
@@ -294,6 +302,8 @@
 superset_version = 0.35.1
 ### GCS-connector version
 gcs_connector_version = 2.0.1
+### Setuptools version
+setuptools_version = 41.0.0
 
 #--- [emr] section contains all parameters that are using for emr provisioning ---#
 [emr]
@@ -364,4 +374,4 @@
 #--- [reverse_proxy] reverse proxy settings ---#
 [reverse_proxy]
 ### Nginx version
-nginx_version = 1.15.1
+nginx_version = 1.15.1
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/files/aws/base_Dockerfile b/infrastructure-provisioning/src/general/files/aws/base_Dockerfile
index 48f5e2d..e298f18 100644
--- a/infrastructure-provisioning/src/general/files/aws/base_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/base_Dockerfile
@@ -19,7 +19,7 @@
 #
 # ******************************************************************************
 
-FROM ubuntu:16.04
+FROM ubuntu:18.04
 ARG OS
 ARG SRC_PATH
 
@@ -30,7 +30,7 @@
     apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
 
 # Install any python dependencies
-RUN pip install -UI pip==9.0.3 && \
+RUN pip install -UI pip==20.1 && \
     pip install boto3 backoff fabric==1.14.0 fabvenv awscli argparse requests ujson jupyter pycrypto
 
 # Configuring ssh for user
diff --git a/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json b/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json
index b4e5ba2..c95503d 100644
--- a/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json
+++ b/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json
@@ -24,7 +24,7 @@
     },
   "templates":
   [
-    {"version":"emr-5.19.0", "applications": [{"Name":"Hadoop", "Version": "2.8.5"}, {"Name":"Spark", "Version": "2.3.2"}, {"Name":"Hive", "Version": "2.3.3"}]},
-    {"version":"emr-5.28.0", "applications": [{"Name":"Hadoop", "Version": "2.8.5"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "2.3.6"}]}
+    {"version":"emr-5.30.0", "applications": [{"Name":"Hadoop", "Version": "2.8.5"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "2.3.6"}]},
+    {"version":"emr-6.0.0", "applications": [{"Name":"Hadoop", "Version": "3.2.1"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "3.1.2"}]}
   ]
 }
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile b/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile
index a0be3e1..313ddd2 100644
--- a/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile
@@ -36,6 +36,8 @@
 COPY general/templates/os/notebook_spark-defaults_local.conf /root/templates/
 COPY general/templates/os/tensorboard.service /root/templates/
 COPY general/templates/os/${OS}/spark-* /root/templates/
+COPY general/templates/os/${OS}/livy.service /root/templates/
+COPY general/templates/os/livy-env.sh /root/templates/
 
 RUN chmod a+x /root/fabfile.py; \
     chmod a+x /root/scripts/*
diff --git a/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile b/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile
index e460e39..587a1b6 100644
--- a/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile
@@ -40,8 +40,9 @@
 COPY general/templates/os/inactive.sh /root/templates/
 COPY general/templates/os/inactive.service /root/templates/
 COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
+COPY general/templates/os/sparkmagic_config_template.json /root/templates/
 COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
 COPY general/templates/os/r_dataengine-service_template.json /root/templates/
 COPY general/templates/os/toree_dataengine-service_* /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile b/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile
index 1f401fc..a2d6198 100644
--- a/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile
@@ -35,13 +35,14 @@
 COPY general/templates/os/py3spark_local_template.json /root/templates/
 COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
 COPY general/templates/os/r_dataengine-service_template.json /root/templates/
+COPY general/templates/os/sparkmagic_config_template.json /root/templates/
 COPY general/templates/os/r_template.json /root/templates/
 COPY general/templates/os/run_template.sh /root/templates/
 COPY general/templates/os/toree_dataengine-service_* /root/templates/
 COPY general/templates/os/inactive.sh /root/templates/
 COPY general/templates/os/inactive.service /root/templates/
 COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
 COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile b/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile
index 203809c..592955e 100644
--- a/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile
@@ -37,7 +37,7 @@
 COPY general/templates/os/r_template.json /root/templates/
 COPY general/templates/os/run_template.sh /root/templates/
 COPY general/templates/os/toree_dataengine-service_* /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
 COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/azure/base_Dockerfile b/infrastructure-provisioning/src/general/files/azure/base_Dockerfile
index dcf939e..883225d 100644
--- a/infrastructure-provisioning/src/general/files/azure/base_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/base_Dockerfile
@@ -19,7 +19,7 @@
 #
 # ******************************************************************************
 
-FROM ubuntu:16.04
+FROM ubuntu:18.04
 ARG OS
 ARG SRC_PATH
 
@@ -30,7 +30,7 @@
     apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
 
 # Install any python dependencies
-RUN pip install -UI pip==9.0.3 && \
+RUN pip install -UI pip==20.1 && \
     pip install backoff fabric==1.14.0 fabvenv argparse requests ujson jupyter pycrypto azure==2.0.0 azure-mgmt-authorization pyyaml
 
 # Configuring ssh for user
diff --git a/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile b/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile
index 8e394cc..daefa72 100644
--- a/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile
@@ -37,6 +37,8 @@
 COPY general/templates/os/tensorboard.service /root/templates/
 COPY general/templates/azure/core-site* /root/templates/
 COPY general/templates/os/${OS}/spark-* /root/templates/
+COPY general/templates/os/${OS}/livy.service /root/templates/
+COPY general/templates/os/livy-env.sh /root/templates/
 
 RUN chmod a+x /root/fabfile.py; \
     chmod a+x /root/scripts/*
diff --git a/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile b/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile
index 220086e..d072a63 100644
--- a/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile
@@ -40,7 +40,7 @@
 COPY general/templates/os/inactive.sh /root/templates/
 COPY general/templates/os/inactive.service /root/templates/
 COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/azure/core-site* /root/templates/
 
diff --git a/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile b/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile
index acbb7a8..8a39401 100644
--- a/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile
@@ -35,7 +35,7 @@
 COPY general/templates/os/py3spark_local_template.json /root/templates/
 COPY general/templates/os/r_template.json /root/templates/
 COPY general/templates/os/run_template.sh /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
 COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile b/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile
index 97739c1..0ff6810 100644
--- a/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile
@@ -35,7 +35,7 @@
 COPY general/templates/os/py3spark_local_template.json /root/templates/
 COPY general/templates/os/r_template.json /root/templates/
 COPY general/templates/os/run_template.sh /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
 COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile
index 8a66b82..d8f6447 100644
--- a/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile
@@ -19,7 +19,7 @@
 #
 # ******************************************************************************
 
-FROM ubuntu:16.04
+FROM ubuntu:18.04
 ARG OS
 ARG SRC_PATH
 
@@ -30,7 +30,7 @@
     apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
 
 # Install any python dependencies
-RUN pip install -UI pip==9.0.3 && \
+RUN pip install -UI pip==20.1 && \
     pip install boto3 backoff fabric==1.14.0 fabvenv  argparse ujson jupyter pycrypto google-api-python-client google-cloud-storage \
     pyyaml google-auth-httplib2 oauth2client
 
diff --git a/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json b/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json
index 1bf4fb6..789ac05 100644
--- a/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json
+++ b/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json
@@ -25,7 +25,6 @@
   },
   "templates":
   [
-    {"version":"1.3", "applications": [{"Name":"Hadoop", "Version": "2.9.2"}, {"Name":"Spark", "Version": "2.3.2"}, {"Name":"Hive", "Version": "2.3.4"}]},
-    {"version":"1.4", "applications": [{"Name":"Hadoop", "Version": "2.9.2"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "2.3.6"}]}
+    {"version":"1.4", "applications": [{"Name":"Hadoop", "Version": "2.10.0"}, {"Name":"Spark", "Version": "2.4.5"}, {"Name":"Hive", "Version": "2.3.6"}]}
   ]
 }
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile
index 0f4f14a..139e565 100644
--- a/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile
@@ -37,6 +37,8 @@
 COPY general/templates/os/tensorboard.service /root/templates/
 COPY general/templates/gcp/core-site.xml /root/templates/
 COPY general/templates/os/${OS}/spark-* /root/templates/
+COPY general/templates/os/${OS}/livy.service /root/templates/
+COPY general/templates/os/livy-env.sh /root/templates/
 
 RUN chmod a+x /root/fabfile.py; \
     chmod a+x /root/scripts/*
diff --git a/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile
index 0a3ad63..2aa2ca4 100644
--- a/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile
@@ -40,7 +40,7 @@
 COPY general/templates/os/inactive.sh /root/templates/
 COPY general/templates/os/inactive.service /root/templates/
 COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
 COPY general/templates/os/r_dataengine-service_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile
index 8e5dabd..bd4b1bd 100644
--- a/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile
@@ -34,6 +34,7 @@
 COPY general/templates/os/pyspark_local_template.json /root/templates/
 COPY general/templates/os/py3spark_local_template.json /root/templates/
 COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
+COPY general/templates/os/sparkmagic_config_template.json /root/templates/
 COPY general/templates/os/r_dataengine-service_template.json /root/templates/
 COPY general/templates/os/r_template.json /root/templates/
 COPY general/templates/os/run_template.sh /root/templates/
@@ -41,7 +42,7 @@
 COPY general/templates/os/inactive.sh /root/templates/
 COPY general/templates/os/inactive.service /root/templates/
 COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
 COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile
index 4d68e2f..9c30f94 100644
--- a/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile
@@ -37,7 +37,7 @@
 COPY general/templates/os/r_template.json /root/templates/
 COPY general/templates/os/run_template.sh /root/templates/
 COPY general/templates/os/toree_dataengine-service_* /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
 COPY general/files/os/toree_kernel.tar.gz /root/files/
 COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
 COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json b/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json
index bd95d12..4f0ad6a 100644
--- a/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json
+++ b/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json
@@ -16,5 +16,7 @@
     "compute.images.get",
     "compute.images.delete",
     "compute.images.setLabels",
-    "compute.images.list"
+    "compute.images.list",
+    "compute.routes.create",
+    "compute.routes.get"
 ]
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/lib/aws/actions_lib.py b/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
index 9519053..8b9ffab 100644
--- a/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
@@ -224,6 +224,24 @@
                            "error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
         traceback.print_exc(file=sys.stdout)
 
+def create_nat_rt(vpc_id, infra_tag_value, edge_instance_id, private_subnet_id):
+    try:
+        ec2 = boto3.client('ec2')
+        nat_rt = ec2.create_route_table(VpcId=vpc_id)
+        nat_rt_id = nat_rt.get('RouteTable').get('RouteTableId')
+        tag = {"Key": 'Name', "Value": infra_tag_value}
+        create_tag(nat_rt_id, json.dumps(tag))
+        ec2 = boto3.resource('ec2')
+        route_table = ec2.RouteTable(nat_rt_id)
+        route_table.create_route(DestinationCidrBlock='0.0.0.0/0', InstanceId=edge_instance_id)
+        route_table.associate_with_subnet(SubnetId=private_subnet_id)
+    except Exception as err:
+        logging.info(
+            "Unable to create Route Table: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+        append_result(str({"error": "Unable to create Route Table",
+                           "error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
+        traceback.print_exc(file=sys.stdout)
+
 
 def create_subnet(vpc_id, subnet, tag, zone):
     try:
@@ -474,6 +492,15 @@
                            "error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
         traceback.print_exc(file=sys.stdout)
 
+def modify_instance_sourcedescheck(instance_id):
+    try:
+        ec2 = boto3.client('ec2')
+        ec2.modify_instance_attribute(InstanceId=instance_id, SourceDestCheck={'Value': False})
+    except Exception as err:
+        logging.info("Unable to modify EC2: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+        append_result(str({"error": "Unable to modify EC2",
+                           "error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
+        traceback.print_exc(file=sys.stdout)
 
 def tag_intance_volume(instance_id, node_name, instance_tag):
     try:
@@ -1620,6 +1647,10 @@
             endpoint_url))
         sudo('echo "spark.hadoop.fs.s3a.server-side-encryption-algorithm   AES256" >> '
              '/tmp/notebook_spark-defaults_local.conf')
+        if not exists('/opt/spark/conf/spark-env.sh'):
+            sudo('mv /opt/spark/conf/spark-env.sh.template /opt/spark/conf/spark-env.sh')
+            java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+            sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/spark/conf/spark-env.sh".format(java_home))
         if os.environ['application'] == 'zeppelin':
             sudo('echo \"spark.jars $(ls -1 ' + jars_dir + '* | tr \'\\n\' \',\')\" >> '
                                                            '/tmp/notebook_spark-defaults_local.conf')
diff --git a/infrastructure-provisioning/src/general/lib/azure/actions_lib.py b/infrastructure-provisioning/src/general/lib/azure/actions_lib.py
index 8cac3c4..761be9c 100644
--- a/infrastructure-provisioning/src/general/lib/azure/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/azure/actions_lib.py
@@ -1126,6 +1126,10 @@
             sudo('sed -i "/spark.*.memory/d" /opt/spark/conf/spark-defaults.conf')
             sudo('echo "spark.{0}.memory {1}m" >> /opt/spark/conf/spark-defaults.conf'.format(memory_type,
                                                                                               spark_memory))
+        if not exists('/opt/spark/conf/spark-env.sh'):
+            sudo('mv /opt/spark/conf/spark-env.sh.template /opt/spark/conf/spark-env.sh')
+            java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+            sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/spark/conf/spark-env.sh".format(java_home))
         if 'spark_configurations' in os.environ:
             dlab_header = sudo('cat /tmp/notebook_spark-defaults_local.conf | grep "^#"')
             spark_configurations = ast.literal_eval(os.environ['spark_configurations'])
diff --git a/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py b/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py
index b1d0acb..e550d9d 100644
--- a/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py
@@ -177,6 +177,37 @@
                                    file=sys.stdout)}))
             traceback.print_exc(file=sys.stdout)
 
+    def create_nat_route(self, nat_route_params):
+        request = self.service.routes().insert(project=self.project, body=nat_route_params)
+        try:
+            result = request.execute()
+            meta_lib.GCPMeta().wait_for_operation(result['name'])
+            print('NAT route {} created.'.format(nat_route_params['name']))
+            return result
+        except Exception as err:
+            logging.info(
+                "Unable to create NAT route: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+            append_result(str({"error": "Unable to create NAT route",
+                               "error_message": str(err) + "\n Traceback: " + traceback.print_exc(
+                                   file=sys.stdout)}))
+            traceback.print_exc(file=sys.stdout)
+
+    def delete_nat_route(self, nat_route_name):
+        request = self.service.routes().delete(project=self.project, route=nat_route_name)
+        try:
+            result = request.execute()
+            meta_lib.GCPMeta().wait_for_operation(result['name'])
+            print('NAT route {} deleteed.'.format(nat_route_name))
+            return result
+        except Exception as err:
+            logging.info(
+                "Unable to delete NAT route: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+            append_result(str({"error": "Unable to delete NAT route",
+                               "error_message": str(err) + "\n Traceback: " + traceback.print_exc(
+                                   file=sys.stdout)}))
+            traceback.print_exc(file=sys.stdout)
+
+
     def create_bucket(self, bucket_name):
         try:
             bucket = self.storage_client.create_bucket(bucket_name)
@@ -1377,6 +1408,10 @@
             sudo('sed -i "/spark.*.memory/d" /opt/spark/conf/spark-defaults.conf')
             sudo('echo "spark.{0}.memory {1}m" >> /opt/spark/conf/spark-defaults.conf'.format(memory_type,
                                                                                               spark_memory))
+        if not exists('/opt/spark/conf/spark-env.sh'):
+            sudo('mv /opt/spark/conf/spark-env.sh.template /opt/spark/conf/spark-env.sh')
+            java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+            sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/spark/conf/spark-env.sh".format(java_home))
         if 'spark_configurations' in os.environ:
             dlab_header = sudo('cat /tmp/notebook_spark-defaults_local.conf | grep "^#"')
             spark_configurations = ast.literal_eval(os.environ['spark_configurations'])
diff --git a/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py b/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py
index cc16028..6b7582b 100644
--- a/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py
+++ b/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py
@@ -157,6 +157,25 @@
                                    file=sys.stdout)}))
             traceback.print_exc(file=sys.stdout)
 
+    def get_route(self, route_name):
+        request = self.service.routes().get(
+            project=self.project,
+            route=route_name)
+        try:
+            return request.execute()
+        except errors.HttpError as err:
+            if err.resp.status == 404:
+                return ''
+            else:
+                raise err
+        except Exception as err:
+            logging.info(
+                "Unable to get Route: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+            append_result(str({"error": "Unable to get Route",
+                               "error_message": str(err) + "\n Traceback: " + traceback.print_exc(
+                                   file=sys.stdout)}))
+            traceback.print_exc(file=sys.stdout)
+
     def get_bucket(self, bucket_name):
         try:
             bucket = self.storage_client.get_bucket(bucket_name)
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py
index 5e44166..296d9ab 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py
@@ -28,51 +28,47 @@
 import time
 
 
-def manage_pkg(command, environment, requisites):
+def manage_pkg(command, environment, requisites, warn='False'):
     try:
-        attempt = 0
-        installed = False
-        while not installed:
-            print('Pkg installation attempt: {}'.format(attempt))
-            if attempt > 60:
+        allow = False
+        counter = 0
+        while not allow:
+            if counter > 60:
                 print("Notebook is broken please recreate it.")
                 sys.exit(1)
             else:
-                try:
-                    allow = False
-                    counter = 0
-                    while not allow:
-                        if counter > 60:
-                            print("Notebook is broken please recreate it.")
-                            sys.exit(1)
-                        else:
-                            print('Package manager is:')
-                            if environment == 'remote':
-                                if sudo('pgrep "^apt" -a && echo "busy" || echo "ready"') == 'busy':
-                                    counter += 1
-                                    time.sleep(10)
-                                else:
-                                    allow = True
-                                    sudo('apt-get {0} {1}'.format(command, requisites))
-                            elif environment == 'local':
-                                if local('sudo pgrep "^apt" -a && echo "busy" || echo "ready"', capture=True) == 'busy':
-                                    counter += 1
-                                    time.sleep(10)
-                                else:
-                                    allow = True
-                                    local('sudo apt-get {0} {1}'.format(command, requisites), capture=True)
-                            else:
-                                print('Wrong environment')
-                    installed = True
-                except:
-                    print("Will try to install with nex attempt.")
-                    sudo('dpkg --configure -a')
-                    attempt += 1
+                print('Package manager is:')
+                if environment == 'remote':
+                    if sudo('pgrep "^apt" -a && echo "busy" || echo "ready"') == 'busy':
+                        counter += 1
+                        time.sleep(10)
+                    else:
+                        allow = True
+                        sudo('sudo dpkg --configure -a')
+                        sudo('sudo apt update')
+                        try:
+                            sudo('apt-get {0} {1}'.format(command, requisites), warn_only=warn)
+                        except:
+                            sudo('lsof /var/lib/dpkg/lock')
+                            sudo('lsof /var/lib/apt/lists/lock')
+                            sudo('lsof /var/cache/apt/archives/lock')
+                            sudo('rm -f /var/lib/apt/lists/lock')
+                            sudo('rm -f /var/cache/apt/archives/lock')
+                            sudo('rm -f /var/lib/dpkg/lock')
+                elif environment == 'local':
+                    if local('sudo pgrep "^apt" -a && echo "busy" || echo "ready"', capture=True) == 'busy':
+                        counter += 1
+                        time.sleep(10)
+                    else:
+                        allow = True
+                        local('sudo apt-get {0} {1}'.format(command, requisites), capture=True)
+                else:
+                    print('Wrong environment')
     except:
         sys.exit(1)
 
 def ensure_pkg(user, requisites='linux-headers-generic python-pip python-dev '
-                                'groff gcc vim less git wget sysv-rc-conf '
+                                'groff gcc vim less git wget '
                                 'libssl-dev unattended-upgrades nmap '
                                 'libffi-dev unzip libxml2-dev haveged'):
     try:
@@ -109,7 +105,8 @@
 
 def renew_gpg_key():
     try:
-        sudo('mv /etc/apt/trusted.gpg /etc/apt/trusted.bkp')
+#        if exists('/etc/apt/trusted.gpg'):
+#            sudo('mv /etc/apt/trusted.gpg /etc/apt/trusted.bkp')
         sudo('apt-key update')
     except:
         sys.exit(1)
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py
index 57940db..836fd64 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py
@@ -54,8 +54,7 @@
             for cidr in config['allowed_ip_cidr']:
                 replace_string += 'acl AllowedCIDRS src {}\\n'.format(cidr)
             sudo('sed -i "s|ALLOWED_CIDRS|{}|g" /etc/squid/squid.conf'.format(replace_string))
-            sudo('service squid reload')
-            sudo('sysv-rc-conf squid on')
+            sudo('systemctl restart squid')
             sudo('touch /tmp/http_proxy_ensured')
     except Exception as err:
         print("Failed to install and configure squid: " + str(err))
@@ -66,8 +65,12 @@
                       keycloak_client_secret, user, hostname, step_cert_sans):
     try:
         if not os.path.exists('/tmp/nginx_installed'):
-            manage_pkg('-y install', 'remote', 'wget')
-            manage_pkg('-y install', 'remote', 'gcc build-essential make automake zlib1g-dev libpcre++-dev libssl-dev git libldap2-dev libc6-dev libgd-dev libgeoip-dev libpcre3-dev apt-utils autoconf liblmdb-dev libtool libxml2-dev libyajl-dev pkgconf liblua5.1-0 liblua5.1-0-dev libreadline-dev libreadline6-dev libtinfo-dev libtool-bin lua5.1 zip readline-doc')
+            manage_pkg('-y install', 'remote',
+                       'gcc build-essential make automake zlib1g-dev libpcre++-dev libssl-dev git libldap2-dev '
+                       'libc6-dev libgd-dev libgeoip-dev libpcre3-dev apt-utils autoconf liblmdb-dev libtool '
+                       'libxml2-dev libyajl-dev pkgconf libreadline-dev libreadline6-dev libtinfo-dev '
+                       'libtool-bin zip readline-doc perl curl liblua5.1-0 liblua5.1-0-dev lua5.1')
+            manage_pkg('-y install --no-install-recommends', 'remote', 'wget gnupg ca-certificates')
             if os.environ['conf_stepcerts_enabled'] == 'true':
                 sudo('mkdir -p /home/{0}/keys'.format(user))
                 sudo('''bash -c 'echo "{0}" | base64 --decode > /etc/ssl/certs/root_ca.crt' '''.format(
@@ -111,66 +114,26 @@
             else:
                 sudo('openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/certs/dlab.key \
                      -out /etc/ssl/certs/dlab.crt -subj "/C=US/ST=US/L=US/O=dlab/CN={}"'.format(hostname))
-            sudo('mkdir -p /tmp/lua')
+
             sudo('mkdir -p /tmp/src')
             with cd('/tmp/src/'):
-                sudo('wget http://nginx.org/download/nginx-{}.tar.gz'.format(nginx_version))
-                sudo('tar -xzf nginx-{}.tar.gz'.format(nginx_version))
+                sudo('wget https://luarocks.org/releases/luarocks-3.3.1.tar.gz')
+                sudo('tar -xzf luarocks-3.3.1.tar.gz')
 
-                sudo('wget https://github.com/openresty/lua-nginx-module/archive/v0.10.15.tar.gz')
-                sudo('tar -xzf v0.10.15.tar.gz')
+            sudo('wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -')
+            sudo('add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"')
+            sudo('apt-get update')
+            sudo('apt-get -y install openresty=1.15.8.1-1~bionic1')
 
-                sudo('wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.1.tar.gz')
-                sudo('tar -xzf v0.3.1.tar.gz')
-
-                sudo('wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz')
-                sudo('tar -xzf LuaJIT-2.0.5.tar.gz')
-
-                sudo('wget http://keplerproject.github.io/luarocks/releases/luarocks-2.2.2.tar.gz')
-                sudo('tar -xzf luarocks-2.2.2.tar.gz')
-
-                sudo('ln -sf nginx-{} nginx'.format(nginx_version))
-
-            with cd('/tmp/src/LuaJIT-2.0.5/'):
-                sudo('make')
-                sudo('make install')
-
-            with cd('/tmp/src/nginx/'), shell_env(LUAJIT_LIB='/usr/local/lib/', LUAJIT_INC='/usr/local/include/luajit-2.0'):
-                sudo('./configure --user=nginx --group=nginx --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx \
-                              --conf-path=/etc/nginx/nginx.conf --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx \
-                              --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log \
-                              --with-http_gzip_static_module --with-http_stub_status_module --with-http_ssl_module --with-pcre \
-                              --with-http_realip_module --with-file-aio --with-ipv6 --with-http_v2_module --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB"  \
-                              --without-http_scgi_module --without-http_uwsgi_module --without-http_fastcgi_module --with-http_sub_module \
-                              --add-dynamic-module=/tmp/src/ngx_devel_kit-0.3.1 --add-dynamic-module=/tmp/src/lua-nginx-module-0.10.15')
-                sudo('make')
-                sudo('make install')
-
-            with cd('/tmp/src/luarocks-2.2.2/'):
+            with cd('/tmp/src/luarocks-3.3.1/'):
                 sudo('./configure')
-                sudo('make build')
                 sudo('make install')
-                sudo('wget https://luarocks.org/manifests/cdbattags/lua-resty-jwt-0.2.0-0.src.rock')
-                sudo('luarocks build lua-resty-jwt-0.2.0-0.src.rock')
-                sudo('wget https://luarocks.org/manifests/bungle/lua-resty-session-2.26-1.src.rock')
-                sudo('luarocks build lua-resty-session-2.26-1.src.rock')
-                sudo('wget https://luarocks.org/manifests/pintsized/lua-resty-http-0.15-0.src.rock')
-                sudo('luarocks build lua-resty-http-0.15-0.src.rock')
-                sudo('wget https://luarocks.org/manifests/hanszandbelt/lua-resty-openidc-1.7.2-1.src.rock')
-                sudo('luarocks build lua-resty-openidc-1.7.2-1.src.rock')
-                sudo('wget https://luarocks.org/manifests/starius/luacrypto-0.3.2-2.src.rock')
-                sudo('luarocks build luacrypto-0.3.2-2.src.rock')
-                sudo('wget https://luarocks.org/manifests/openresty/lua-cjson-2.1.0.6-1.src.rock')
-                sudo('luarocks build lua-cjson-2.1.0.6-1.src.rock')
-                sudo('wget https://luarocks.org/manifests/avlubimov/lua-resty-core-0.1.17-4.src.rock')
-                sudo('luarocks build lua-resty-core-0.1.17-4.src.rock')
-                sudo('wget https://luarocks.org/manifests/hjpotter92/random-1.1-0.rockspec')
-                sudo('luarocks install random-1.1-0.rockspec')
-                sudo('wget https://luarocks.org/manifests/rsander/lua-resty-string-0.09-0.rockspec')
-                sudo('luarocks install lua-resty-string-0.09-0.rockspec')
+                sudo('luarocks install lua-resty-openidc --tree /usr/local/openresty/lualib/resty/')
+
+            sudo('luarocks install lua-resty-openidc')
 
             sudo('useradd -r nginx')
-            sudo('rm -f /etc/nginx/nginx.conf')
+
             sudo('mkdir -p /opt/dlab/templates')
             put('/root/templates', '/opt/dlab', use_sudo=True)
             sudo('sed -i \'s/EDGE_IP/{}/g\' /opt/dlab/templates/conf.d/proxy.conf'.format(edge_ip))
@@ -183,15 +146,11 @@
             sudo('sed -i \'s/KEYCLOAK_CLIENT_SECRET/{}/g\' /opt/dlab/templates/conf.d/proxy.conf'.format(
                 keycloak_client_secret))
 
-            sudo('cp /opt/dlab/templates/nginx.conf /etc/nginx/')
-            sudo('mkdir /etc/nginx/conf.d')
-            sudo('cp /opt/dlab/templates/conf.d/proxy.conf /etc/nginx/conf.d/')
-            sudo('mkdir /etc/nginx/locations')
-            sudo('cp /opt/dlab/templates/nginx_debian /etc/init.d/nginx')
-            sudo('chmod +x /etc/init.d/nginx')
-            sudo('systemctl daemon-reload')
-            sudo('systemctl enable nginx')
-            sudo('/etc/init.d/nginx start')
+            sudo('cp /opt/dlab/templates/nginx.conf /usr/local/openresty/nginx/conf')
+            sudo('mkdir /usr/local/openresty/nginx/conf/conf.d')
+            sudo('cp /opt/dlab/templates/conf.d/proxy.conf /usr/local/openresty/nginx/conf/conf.d/')
+            sudo('mkdir /usr/local/openresty/nginx/conf/locations')
+            sudo('systemctl start openresty')
             sudo('touch /tmp/nginx_installed')
             if os.environ['conf_letsencrypt_enabled'] == 'true':
                 print("Configuring letsencrypt certificates.")
@@ -203,4 +162,26 @@
                 configure_nginx_LE(os.environ['conf_letsencrypt_domain_name'], os.environ['project_name'])
     except Exception as err:
         print("Failed install nginx with ldap: " + str(err))
+        sys.exit(1)
+
+def configure_nftables(config):
+    try:
+        if not exists('/tmp/nftables_ensured'):
+            manage_pkg('-y install', 'remote', 'nftables')
+            sudo('systemctl enable nftables.service')
+            sudo('systemctl start nftables')
+            sudo('sysctl net.ipv4.ip_forward=1')
+            if os.environ['conf_cloud_provider'] == 'aws':
+                interface = 'eth0'
+            elif os.environ['conf_cloud_provider'] == 'gcp':
+                interface = 'ens4'
+            sudo('sed -i \'s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g\' /etc/sysctl.conf')
+            sudo('sed -i \'s/EDGE_IP/{}/g\' /opt/dlab/templates/nftables.conf'.format(config['edge_ip']))
+            sudo('sed -i "s|INTERFACE|{}|g" /opt/dlab/templates/nftables.conf'.format(interface))
+            sudo('sed -i "s|SUBNET_CIDR|{}|g" /opt/dlab/templates/nftables.conf'.format(config['exploratory_subnet']))
+            sudo('cp /opt/dlab/templates/nftables.conf /etc/')
+            sudo('systemctl restart nftables')
+            sudo('touch /tmp/nftables_ensured')
+    except Exception as err:
+        print("Failed to configure nftables: " + str(err))
         sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py
index 18d7f59..1ee213d 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py
@@ -39,6 +39,7 @@
 def enable_proxy(proxy_host, proxy_port):
     try:
         proxy_string = "http://%s:%s" % (proxy_host, proxy_port)
+        proxy_https_string = "http://%s:%s" % (proxy_host, proxy_port)
         sudo('sed -i "/^export http_proxy/d" /etc/profile')
         sudo('sed -i "/^export https_proxy/d" /etc/profile')
         sudo('echo export http_proxy=' + proxy_string + ' >> /etc/profile')
@@ -46,6 +47,7 @@
         if exists('/etc/apt/apt.conf'):
             sudo("sed -i '/^Acquire::http::Proxy/d' /etc/apt/apt.conf")
         sudo("echo 'Acquire::http::Proxy \"" + proxy_string + "\";' >> /etc/apt/apt.conf")
+        sudo("echo 'Acquire::http::Proxy \"" + proxy_https_string + "\";' >> /etc/apt/apt.conf")
 
         print("Renewing gpg key")
         renew_gpg_key()
@@ -118,25 +120,35 @@
             sudo('gdebi -n rstudio-server-{}-amd64.deb'.format(rstudio_version))
             sudo('mkdir -p /mnt/var')
             sudo('chown {0}:{0} /mnt/var'.format(os_user))
+            http_proxy = run('echo $http_proxy')
+            https_proxy = run('echo $https_proxy')
             sudo("sed -i '/Type=forking/a \Environment=USER=dlab-user' /etc/systemd/system/rstudio-server.service")
             sudo("sed -i '/ExecStart/s|=/usr/lib/rstudio-server/bin/rserver|=/bin/bash -c \"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64; /usr/lib/rstudio-server/bin/rserver --auth-none 1|g' /etc/systemd/system/rstudio-server.service")
             sudo("sed -i '/ExecStart/s|$|\"|g' /etc/systemd/system/rstudio-server.service")
+            sudo(
+                'sed -i \'/\[Service\]/a Environment=\"HTTP_PROXY={}\"\'  /etc/systemd/system/rstudio-server.service'.format(
+                    http_proxy))
+            sudo(
+                'sed -i \'/\[Service\]/a Environment=\"HTTPS_PROXY={}\"\'  /etc/systemd/system/rstudio-server.service'.format(
+                    https_proxy))
+            java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+            sudo('sed -i \'/\[Service\]/ a\Environment=\"JAVA_HOME={}\"\'  /etc/systemd/system/rstudio-server.service'.format(
+                java_home))
             sudo("systemctl daemon-reload")
             sudo('touch /home/{}/.Renviron'.format(os_user))
             sudo('chown {0}:{0} /home/{0}/.Renviron'.format(os_user))
             sudo('''echo 'SPARK_HOME="{0}"' >> /home/{1}/.Renviron'''.format(local_spark_path, os_user))
+            sudo('''echo 'JAVA_HOME="{0}"' >> /home/{1}/.Renviron'''.format(java_home, os_user))
             sudo('touch /home/{}/.Rprofile'.format(os_user))
             sudo('chown {0}:{0} /home/{0}/.Rprofile'.format(os_user))
             sudo('''echo 'library(SparkR, lib.loc = c(file.path(Sys.getenv("SPARK_HOME"), "R", "lib")))' >> /home/{}/.Rprofile'''.format(os_user))
-            http_proxy = run('echo $http_proxy')
-            https_proxy = run('echo $https_proxy')
             sudo('''echo 'Sys.setenv(http_proxy = \"{}\")' >> /home/{}/.Rprofile'''.format(http_proxy, os_user))
             sudo('''echo 'Sys.setenv(https_proxy = \"{}\")' >> /home/{}/.Rprofile'''.format(https_proxy, os_user))
             sudo('rstudio-server start')
             sudo('echo "{0}:{1}" | chpasswd'.format(os_user, rstudio_pass))
-            sudo("sed -i '/exit 0/d' /etc/rc.local")
-            sudo('''bash -c "echo \'sed -i 's/^#SPARK_HOME/SPARK_HOME/' /home/{}/.Renviron\' >> /etc/rc.local"'''.format(os_user))
-            sudo("bash -c 'echo exit 0 >> /etc/rc.local'")
+            #sudo("sed -i '/exit 0/d' /etc/rc.local")
+            #sudo('''bash -c "echo \'sed -i 's/^#SPARK_HOME/SPARK_HOME/' /home/{}/.Renviron\' >> /etc/rc.local"'''.format(os_user))
+            #sudo("bash -c 'echo exit 0 >> /etc/rc.local'")
             sudo('touch /home/{}/.ensure_dir/rstudio_ensured'.format(os_user))
         except:
             sys.exit(1)
@@ -156,8 +168,8 @@
             sudo('pip2 install matplotlib==2.0.2 --no-cache-dir')
             sudo('pip3 install matplotlib==2.0.2 --no-cache-dir')
             if os.environ['application'] in ('tensor', 'deeplearning'):
-                sudo('python2.7 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy_version']))
-                sudo('python3.5 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy_version']))
+                sudo('python2.7 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy2_version']))
+                sudo('python3.6 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy_version']))
             sudo('touch /home/' + os_user + '/.ensure_dir/matplot_ensured')
         except:
             sys.exit(1)
@@ -165,13 +177,14 @@
 @backoff.on_exception(backoff.expo, SystemExit, max_tries=10)
 def add_sbt_key():
     sudo(
-        'apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823')
+        'curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add')
 
 def ensure_sbt(os_user):
     if not exists('/home/' + os_user + '/.ensure_dir/sbt_ensured'):
         try:
             manage_pkg('-y install', 'remote', 'apt-transport-https')
             sudo('echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list')
+
             add_sbt_key()
             manage_pkg('update', 'remote', '')
             manage_pkg('-y install', 'remote', 'sbt')
@@ -195,6 +208,8 @@
         try:
             manage_pkg('-y install', 'remote', 'default-jre')
             manage_pkg('-y install', 'remote', 'default-jdk')
+            manage_pkg('-y install', 'remote', 'openjdk-8-jdk')
+            manage_pkg('-y install', 'remote', 'openjdk-8-jre')
             sudo('touch /home/' + os_user + '/.ensure_dir/jre_jdk_ensured')
         except:
             sys.exit(1)
@@ -205,7 +220,7 @@
         try:
             manage_pkg('-y install', 'remote', 'libjpeg8-dev zlib1g-dev')
             if os.environ['application'] in ('jupyter', 'zeppelin'):
-                sudo('pip2 install NumPy=={} SciPy pandas Sympy Pillow sklearn --no-cache-dir'.format(os.environ['notebook_numpy_version']))
+                sudo('pip2 install NumPy=={} SciPy pandas Sympy Pillow sklearn --no-cache-dir'.format(os.environ['notebook_numpy2_version']))
                 sudo('pip3 install NumPy=={} SciPy pandas Sympy Pillow sklearn --no-cache-dir'.format(os.environ['notebook_numpy_version']))
             if os.environ['application'] in ('tensor', 'deeplearning'):
                 sudo('pip2 install opencv-python h5py --no-cache-dir')
@@ -231,10 +246,10 @@
     if not exists('/home/' + os_user + '/.ensure_dir/python2_libraries_ensured'):
         try:
             try:
-                manage_pkg('-y install', 'remote', 'libssl-dev python-virtualenv')
+                manage_pkg('-y install', 'remote', 'libssl1.0-dev python-virtualenv')
             except:
                 sudo('pip2 install virtualenv --no-cache-dir')
-                manage_pkg('-y install', 'remote', 'libssl-dev')
+                manage_pkg('-y install', 'remote', 'libssl1.0-dev')
             try:
                 sudo('pip2 install tornado=={0} ipython ipykernel=={1} --no-cache-dir' \
                      .format(os.environ['notebook_tornado_version'], os.environ['notebook_ipykernel_version']))
@@ -252,13 +267,15 @@
 def ensure_python3_libraries(os_user):
     if not exists('/home/' + os_user + '/.ensure_dir/python3_libraries_ensured'):
         try:
-            manage_pkg('-y install', 'remote', 'python3-setuptools')
+            #manage_pkg('-y install', 'remote', 'python3-setuptools')
             manage_pkg('-y install', 'remote', 'python3-pip')
+            manage_pkg('-y install', 'remote', 'libkrb5-dev')
+            sudo('pip3 install setuptools=={}'.format(os.environ['notebook_setuptools_version']))
             try:
-                sudo('pip3 install tornado=={0} ipython==7.9.0 ipykernel=={1} --no-cache-dir' \
+                sudo('pip3 install tornado=={0} ipython==7.9.0 ipykernel=={1} sparkmagic --no-cache-dir' \
                      .format(os.environ['notebook_tornado_version'], os.environ['notebook_ipykernel_version']))
             except:
-                sudo('pip3 install tornado=={0} ipython==5.0.0 ipykernel=={1} --no-cache-dir' \
+                sudo('pip3 install tornado=={0} ipython==5.0.0 ipykernel=={1} sparkmagic --no-cache-dir' \
                      .format(os.environ['notebook_tornado_version'], os.environ['notebook_ipykernel_version']))
             sudo('pip3 install -U pip=={} --no-cache-dir'.format(os.environ['conf_pip_version']))
             sudo('pip3 install boto3 --no-cache-dir')
@@ -278,39 +295,53 @@
             sudo('echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf')
             sudo('update-initramfs -u')
             with settings(warn_only=True):
-                reboot(wait=150)
-            manage_pkg('-y install', 'remote', 'dkms')
+                reboot(wait=180)
+            manage_pkg('-y install', 'remote', 'dkms libglvnd-dev')
             kernel_version = run('uname -r | tr -d "[..0-9-]"')
             if kernel_version == 'azure':
                 manage_pkg('-y install', 'remote', 'linux-modules-`uname -r`')
             else:
-                #legacy support for old kernels
-                sudo('if [[ $(apt-cache search linux-image-`uname -r`) ]]; then apt-get -y install linux-image-`uname -r`; else apt-get -y install linux-modules-`uname -r`; fi;')
-            sudo('wget http://us.download.nvidia.com/XFree86/Linux-x86_64/{0}/NVIDIA-Linux-x86_64-{0}.run -O /home/{1}/NVIDIA-Linux-x86_64-{0}.run'.format(nvidia_version, os_user))
+                # legacy support for old kernels
+                sudo('if [[ $(apt-cache search linux-image-`uname -r`) ]]; then apt-get -y '
+                     'install linux-image-`uname -r`; else apt-get -y install linux-modules-`uname -r`; fi;')
+            sudo('wget http://us.download.nvidia.com/tesla/{0}/NVIDIA-Linux-x86_64-{0}.run -O '
+                 '/home/{1}/NVIDIA-Linux-x86_64-{0}.run'.format(nvidia_version, os_user))
             sudo('/bin/bash /home/{0}/NVIDIA-Linux-x86_64-{1}.run -s --dkms'.format(os_user, nvidia_version))
             sudo('rm -f /home/{0}/NVIDIA-Linux-x86_64-{1}.run'.format(os_user, nvidia_version))
             # install cuda
-            sudo('python3.5 -m pip install --upgrade pip=={0} wheel numpy=={1} --no-cache-dir'. format(os.environ['conf_pip_version'], os.environ['notebook_numpy_version']))
-            sudo('wget -P /opt https://developer.nvidia.com/compute/cuda/{0}/prod/local_installers/{1}'.format(cuda_version, cuda_file_name))
+            sudo('python3 -m pip install --upgrade pip=={0} wheel numpy=={1} --no-cache-dir'.format(
+                os.environ['conf_pip_version'], os.environ['notebook_numpy_version']))
+            sudo('wget -P /opt http://developer.download.nvidia.com/compute/cuda/{0}/Prod/local_installers/{1}'.format(
+                cuda_version, cuda_file_name))
             sudo('sh /opt/{} --silent --toolkit'.format(cuda_file_name))
             sudo('mv /usr/local/cuda-{} /opt/'.format(cuda_version))
             sudo('ln -s /opt/cuda-{0} /usr/local/cuda-{0}'.format(cuda_version))
             sudo('rm -f /opt/{}'.format(cuda_file_name))
             # install cuDNN
-            run('wget http://developer.download.nvidia.com/compute/redist/cudnn/v{0}/{1} -O /tmp/{1}'.format(cudnn_version, cudnn_file_name))
+            run('wget http://developer.download.nvidia.com/compute/redist/cudnn/v{0}/{1} -O /tmp/{1}'.format(
+                cudnn_version, cudnn_file_name))
             run('tar xvzf /tmp/{} -C /tmp'.format(cudnn_file_name))
             sudo('mkdir -p /opt/cudnn/include')
             sudo('mkdir -p /opt/cudnn/lib64')
             sudo('mv /tmp/cuda/include/cudnn.h /opt/cudnn/include')
             sudo('mv /tmp/cuda/lib64/libcudnn* /opt/cudnn/lib64')
             sudo('chmod a+r /opt/cudnn/include/cudnn.h /opt/cudnn/lib64/libcudnn*')
-            run('echo "export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64\"" >> ~/.bashrc')
+            run(
+                'echo "export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64\"" >> ~/.bashrc')
             # install TensorFlow and run TensorBoard
-            sudo('python2.7 -m pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp27-none-linux_x86_64.whl --no-cache-dir'.format(tensorflow_version))
-            sudo('python3 -m pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp35-cp35m-linux_x86_64.whl --no-cache-dir'.format(tensorflow_version))
+            # sudo('python2.7 -m pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp27-none-linux_x86_64.whl --no-cache-dir'.format(tensorflow_version))
+            sudo('python3 -m pip install --upgrade '
+                 'https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp36-cp36m-manylinux2010_x86_64.whl'
+                 ' --no-cache-dir'.format(tensorflow_version))
             sudo('mkdir /var/log/tensorboard; chown {0}:{0} -R /var/log/tensorboard'.format(os_user))
             put('{}tensorboard.service'.format(templates_dir), '/tmp/tensorboard.service')
             sudo("sed -i 's|OS_USR|{}|' /tmp/tensorboard.service".format(os_user))
+            http_proxy = run('echo $http_proxy')
+            https_proxy = run('echo $https_proxy')
+            sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTP_PROXY={}\"\'  /tmp/tensorboard.service'.format(
+                http_proxy))
+            sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTPS_PROXY={}\"\'  /tmp/tensorboard.service'.format(
+                https_proxy))
             sudo("chmod 644 /tmp/tensorboard.service")
             sudo('\cp /tmp/tensorboard.service /etc/systemd/system/')
             sudo("systemctl daemon-reload")
@@ -358,7 +389,7 @@
 
 def install_nodejs(os_user):
     if not exists('/home/{}/.ensure_dir/nodejs_ensured'.format(os_user)):
-        sudo('curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -')
+        sudo('curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -')
         manage_pkg('-y install', 'remote', 'nodejs')
         sudo('touch /home/{}/.ensure_dir/nodejs_ensured'.format(os_user))
 
@@ -372,53 +403,57 @@
         manage_pkg('update', 'remote', '')
         for os_pkg in requisites:
             if os_pkg[1] != '' and os_pkg[1] !='N/A':
+                version = os_pkg[1]
                 os_pkg = "{}={}".format(os_pkg[0], os_pkg[1])
             else:
+                version = 'N/A'
                 os_pkg = os_pkg[0]
-            sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install {0} 2>&1 | tee /tmp/tee.tmp; if ! grep -w -E "({1})" /tmp/tee.tmp > '
+            sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install --allow-downgrades {0} 2>&1 | tee /tmp/tee.tmp; if ! grep -w -E "({1})" /tmp/tee.tmp > '
                  '/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, error_parser))
             err = sudo('cat /tmp/os_install_{}.log'.format(os_pkg)).replace('"', "'")
-            sudo('cat /tmp/tee.tmp | if ! grep -w -E -A 20 "({1})" /tmp/tee.tmp > '
+            sudo('cat /tmp/tee.tmp | if ! grep -w -E -A 30 "({1})" /tmp/tee.tmp > '
                  '/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, new_pkgs_parser))
             dep = sudo('cat /tmp/os_install_{}.log'.format(os_pkg))
-            if err == '':
-                dep = dep[len(new_pkgs_parser): dep.find(" upgraded, ") - 1].replace('\r', '') \
-                    .replace('\n', '').replace('  ', ' ').replace(' {} '.format(os_pkg.split("=")[0]), ' ').strip().split(' ')
-                if dep == '' or dep == os_pkg.split("=")[0]:
-                    dep = []
-                else:
-                    for n, i in enumerate(dep):
-                        pkg = sudo('apt list --installed 2>&1 | grep {}'.format(i))
-                        if pkg == '':
-                            pkg = sudo('apt list --installed 2>&1 | grep {}'.format(i.lower()))
-                        if i == os_pkg.split("=")[0]:
-                            dep[n] = ''
-                        elif "/" in pkg:
-                            dep[n] = '{} v.{}'.format(pkg.split('/')[0], pkg.split(' ')[1])
-                    dep = [i for i in dep if i]
-            else:
+            if dep == '':
                 dep = []
-            if 'E: Version' in err and 'was not found' in err:
-                versions = sudo ('apt-cache policy {} | grep 500 | grep -v Packages'.format(os_pkg.split("=")[0])).replace('\r\n', '').replace(' 500', '').replace('     ', ' ').strip().split(' ')
-                status_msg = 'invalid version'
             else:
-                versions = []
-                status_msg = 'failed'
+                dep = dep[len(new_pkgs_parser): dep.find(" upgraded, ") - 1].replace('\r', '') \
+                        .replace('\n', '').replace('  ', ' ').strip().split(' ')
+                for n, i in enumerate(dep):
+                    if i == os_pkg.split("=")[0]:
+                        dep[n] = ''
+                    else:
+                        sudo('apt show {0} 2>&1 | if ! grep Version: > '
+                 '/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(i))
+                        dep[n] =sudo('cat /tmp/os_install_{}.log'.format(i)).replace('Version: ', '{} v.'.format(i))
+                dep = [i for i in dep if i]
+            versions = []
             sudo('apt list --installed | if ! grep {0}/ > /tmp/os_install_{1}.list; then  echo "" > /tmp/os_install_{1}.list;fi'.format(os_pkg.split("=")[0], os_pkg))
             res = sudo('cat /tmp/os_install_{}.list'.format(os_pkg))
-            if res:
+            if err:
+                status_msg = 'installation_error'
+            elif res:
                 ansi_escape = re.compile(r'\x1b[^m]*m')
                 ver = ansi_escape.sub('', res).split("\r\n")
                 version = [i for i in ver if os_pkg.split("=")[0] in i][0].split(' ')[1]
-                status.append({"group": "os_pkg", "name": os_pkg.split("=")[0], "version": version, "status": "installed", "add_pkgs": dep})
-            else:
-                status.append({"group": "os_pkg", "name": os_pkg.split("=")[0], "status": status_msg, "error_message": err, "available_versions": versions})
+                status_msg = "installed"
+            if 'E: Version' in err and 'was not found' in err:
+                versions = sudo ('apt-cache policy {} | grep 500 | grep -v Packages'.format(os_pkg.split("=")[0]))\
+                    .replace('\r\n', '').replace(' 500', '').replace('     ', ' ').replace('***', '').strip().split(' ')
+                if versions != '':
+                    status_msg = 'invalid_version'
+            status.append({"group": "os_pkg", "name": os_pkg.split("=")[0], "version": version, "status": status_msg,
+                           "error_message": err, "add_pkgs": dep, "available_versions": versions})
         sudo('unattended-upgrades -v')
         sudo('export LC_ALL=C')
         return status
     except Exception as err:
-        append_result("Failed to install OS packages", str(err))
-        sys.exit(1)
+        for os_pkg in requisites:
+            name, vers = os_pkg
+            status.append(
+                {"group": "os_pkg", "name": name, "version": vers, "status": 'installation_error', "error_message": err})
+        print("Failed to install OS packages: {}".format(requisites))
+        return status
 
 
 @backoff.on_exception(backoff.expo, SystemExit, max_tries=10)
@@ -448,17 +483,19 @@
     if not exists('/home/{}/.ensure_dir/caffe2_ensured'.format(os_user)):
         env.shell = "/bin/bash -l -c -i"
         manage_pkg('update', 'remote', '')
-        manage_pkg('-y install --no-install-recommends', 'remote', 'build-essential cmake git libgoogle-glog-dev libprotobuf-dev protobuf-compiler python-dev python-pip')
-        sudo('pip2 install numpy=={} protobuf --no-cache-dir'.format(os.environ['notebook_numpy_version']))
+        manage_pkg('-y install --no-install-recommends', 'remote', 'build-essential cmake git libgoogle-glog-dev '
+                   'libprotobuf-dev protobuf-compiler python-dev python-pip')
+        sudo('pip2 install numpy=={} protobuf --no-cache-dir'.format(os.environ['notebook_numpy2_version']))
         sudo('pip3 install numpy=={} protobuf --no-cache-dir'.format(os.environ['notebook_numpy_version']))
         manage_pkg('-y install --no-install-recommends', 'remote', 'libgflags-dev')
-        manage_pkg('-y install --no-install-recommends', 'remote', 'libgtest-dev libiomp-dev libleveldb-dev liblmdb-dev libopencv-dev libopenmpi-dev libsnappy-dev openmpi-bin openmpi-doc python-pydot')
+        manage_pkg('-y install --no-install-recommends', 'remote', 'libgtest-dev libiomp-dev libleveldb-dev liblmdb-dev '
+                   'libopencv-dev libopenmpi-dev libsnappy-dev openmpi-bin openmpi-doc python-pydot')
         sudo('pip2 install flask graphviz hypothesis jupyter matplotlib==2.0.2 pydot python-nvd3 pyyaml requests scikit-image '
              'scipy setuptools tornado --no-cache-dir')
         sudo('pip3 install flask graphviz hypothesis jupyter matplotlib==2.0.2 pydot python-nvd3 pyyaml requests scikit-image '
              'scipy setuptools tornado --no-cache-dir')
-        sudo('cp -f /opt/cudnn/include/* /opt/cuda-8.0/include/')
-        sudo('cp -f /opt/cudnn/lib64/* /opt/cuda-8.0/lib64/')
+        sudo('cp -f /opt/cudnn/include/* /opt/cuda-{}/include/'.format(os.environ['notebook_cuda_version']))
+        sudo('cp -f /opt/cudnn/lib64/* /opt/cuda-{}/lib64/'.format(os.environ['notebook_cuda_version']))
         sudo('wget https://cmake.org/files/v{2}/cmake-{1}.tar.gz -O /home/{0}/cmake-{1}.tar.gz'.format(
             os_user, cmake_version, cmake_version.split('.')[0] + "." + cmake_version.split('.')[1]))
         sudo('tar -zxvf cmake-{}.tar.gz'.format(cmake_version))
@@ -469,16 +506,16 @@
         with cd('/home/{}/pytorch/'.format(os_user)):
             sudo('git submodule update --init')
             with settings(warn_only=True):
-                sudo('git checkout v{}'.format(caffe2_version))
-                sudo('git submodule update --recursive')
-            sudo('mkdir build && cd build && cmake{} .. && make "-j$(nproc)" install'.format(cmake_version))
+                sudo('git checkout {}'.format(os.environ['notebook_pytorch_branch']))
+                sudo('git submodule update --init --recursive')
+            sudo('python3 setup.py install')
         sudo('touch /home/' + os_user + '/.ensure_dir/caffe2_ensured')
 
 
-def install_cntk(os_user, cntk_version):
+def install_cntk(os_user, cntk2_version, cntk_version):
     if not exists('/home/{}/.ensure_dir/cntk_ensured'.format(os_user)):
-        sudo('pip2 install https://cntk.ai/PythonWheel/GPU/cntk-{}-cp27-cp27mu-linux_x86_64.whl --no-cache-dir'.format(cntk_version))
-        sudo('pip3 install https://cntk.ai/PythonWheel/GPU/cntk-{}-cp35-cp35m-linux_x86_64.whl --no-cache-dir'.format(cntk_version))
+        sudo('pip2 install https://cntk.ai/PythonWheel/GPU/cntk-{}-cp27-cp27mu-linux_x86_64.whl --no-cache-dir'.format(cntk2_version))
+        sudo('pip3 install https://cntk.ai/PythonWheel/GPU/cntk_gpu-{}.post1-cp36-cp36m-manylinux1_x86_64.whl --no-cache-dir'.format(cntk_version))
         sudo('touch /home/{}/.ensure_dir/cntk_ensured'.format(os_user))
 
 
@@ -498,19 +535,19 @@
 
 def install_mxnet(os_user, mxnet_version):
     if not exists('/home/{}/.ensure_dir/mxnet_ensured'.format(os_user)):
-        sudo('pip2 install mxnet-cu80=={} opencv-python --no-cache-dir'.format(mxnet_version))
-        sudo('pip3 install mxnet-cu80=={} opencv-python --no-cache-dir'.format(mxnet_version))
+        sudo('pip2 install mxnet-cu101=={} opencv-python --no-cache-dir'.format(mxnet_version))
+        sudo('pip3 install mxnet-cu101=={} opencv-python --no-cache-dir'.format(mxnet_version))
         sudo('touch /home/{}/.ensure_dir/mxnet_ensured'.format(os_user))
 
 
-def install_torch(os_user):
-    if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
-        run('git clone https://github.com/torch/distro.git ~/torch --recursive')
-        with cd('/home/{}/torch/'.format(os_user)):
-            run('bash install-deps;')
-            run('./install.sh -b')
-        run('source /home/{}/.bashrc'.format(os_user))
-        sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
+#def install_torch(os_user):
+#    if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
+#        run('git clone https://github.com/nagadomi/distro.git ~/torch --recursive')
+#        with cd('/home/{}/torch/'.format(os_user)):
+#           run('bash install-deps;')
+#           run('./install.sh -b')
+#        run('source /home/{}/.bashrc'.format(os_user))
+#        sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
 
 
 def install_gitlab_cert(os_user, certfile):
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py
index ff89fec..0c38603 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py
@@ -91,8 +91,8 @@
             sudo("find /var/lib/jenkins/jobs/ -type f | xargs sed -i \'s/OS_USR/{}/g; s/SBN/{}/g; s/CTUN/{}/g; s/SGI/{}/g; s/VPC/{}/g; s/SNI/{}/g; s/AKEY/{}/g\'".format(os_user, config['service_base_name'], tag_resource_id, config['security_group_id'], config['vpc_id'], config['subnet_id'], config['admin_key']))
             sudo('chown -R jenkins:jenkins /var/lib/jenkins')
             sudo('/etc/init.d/jenkins stop; sleep 5')
-            sudo('sysv-rc-conf jenkins on')
-            sudo('service jenkins start')
+            sudo('systemctl enable jenkins')
+            sudo('systemctl start jenkins')
             sudo('touch ' + dlab_path + '/tmp/jenkins_configured')
             sudo('echo "jenkins ALL = NOPASSWD:ALL" >> /etc/sudoers')
     except Exception as err:
diff --git a/infrastructure-provisioning/src/general/lib/os/fab.py b/infrastructure-provisioning/src/general/lib/os/fab.py
index 4505cf0..df8cbe1 100644
--- a/infrastructure-provisioning/src/general/lib/os/fab.py
+++ b/infrastructure-provisioning/src/general/lib/os/fab.py
@@ -54,19 +54,23 @@
 
 def install_pip_pkg(requisites, pip_version, lib_group):
     status = list()
-    error_parser = "Could not|No matching|ImportError:|failed|EnvironmentError:"
+    error_parser = "Could not|No matching|ImportError:|failed|EnvironmentError:|requires|FileNotFoundError:|RuntimeError:|error:"
     try:
         if pip_version == 'pip3' and not exists('/bin/pip3'):
-            sudo('ln -s /bin/pip3.5 /bin/pip3')
+            for v in range(4, 8):
+                if exists('/bin/pip3.{}'.format(v)):
+                    sudo('ln -s /bin/pip3.{} /bin/pip3'.format(v))
         sudo('{} install -U pip=={} setuptools'.format(pip_version, os.environ['conf_pip_version']))
         sudo('{} install -U pip=={} --no-cache-dir'.format(pip_version, os.environ['conf_pip_version']))
         sudo('{} install --upgrade pip=={}'.format(pip_version, os.environ['conf_pip_version']))
         for pip_pkg in requisites:
             if pip_pkg[1] == '' or pip_pkg[1] == 'N/A':
                 pip_pkg = pip_pkg[0]
+                version = 'N/A'
             else:
+                version = pip_pkg[1]
                 pip_pkg = "{}=={}".format(pip_pkg[0], pip_pkg[1])
-            sudo('{0} install {1} --no-cache-dir 2>&1 | tee /tmp/tee.tmp; if ! grep -w -i -E  "({2})" /tmp/tee.tmp >  /tmp/{0}install_{1}.log; then  echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg, error_parser))
+            sudo('{0} install -U {1} --no-cache-dir 2>&1 | tee /tmp/tee.tmp; if ! grep -w -i -E  "({2})" /tmp/tee.tmp >  /tmp/{0}install_{1}.log; then  echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg, error_parser))
             err = sudo('cat /tmp/{0}install_{1}.log'.format(pip_version, pip_pkg)).replace('"', "'")
             sudo('{0} freeze | if ! grep -w -i {1} > /tmp/{0}install_{1}.list; then  echo "" > /tmp/{0}install_{1}.list;fi'.format(pip_version, pip_pkg))
             res = sudo('cat /tmp/{0}install_{1}.list'.format(pip_version, pip_pkg))
@@ -77,7 +81,9 @@
                 sudo('{0} freeze | if ! grep -w -i {1} > /tmp/{0}install_{1}.list; then  echo "" > '
                      '/tmp/{0}install_{1}.list;fi'.format(pip_version, changed_pip_pkg))
                 res = sudo('cat /tmp/{0}install_{1}.list'.format(pip_version, changed_pip_pkg))
-            if res:
+            if err:
+                status_msg = 'installation_error'
+            elif res:
                 res = res.lower()
                 ansi_escape = re.compile(r'\x1b[^m]*m')
                 ver = ansi_escape.sub('', res).split("\r\n")
@@ -85,41 +91,41 @@
                     version = [i for i in ver if changed_pip_pkg.lower() in i][0].split('==')[1]
                 else:
                     version = \
-                    [i for i in ver if pip_pkg.split("==")[0].lower() in i][0].split(
-                        '==')[1]
-                sudo('if ! grep -w -i -E  "Installing collected packages:" /tmp/tee.tmp > /tmp/{0}install_{1}.log; then  echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg))
-                dep = sudo('cat /tmp/{0}install_{1}.log'.format(pip_version, pip_pkg)).replace('\r\n', '').strip()[31:]
-                if dep == '' or dep == pip_pkg.split("==")[0]:
-                    dep = []
-                else:
-                    dep = dep.split(', ')
-                    for n, i in enumerate(dep):
-                        if i == pip_pkg.split("==")[0]:
-                            dep[n] = ''
-                        else:
-                            dep[n] = sudo('{} freeze 2>&1 | grep {}=='.format(pip_version , i)).replace('==', ' v.')
-                            if dep[n] == '':
-                                dep[n] = sudo('{} freeze 2>&1 | grep {}=='.format(pip_version, i.lower())).replace('==', ' v.')
-                    dep = [i for i in dep if i]
-
-                status.append({"group": "{}".format(lib_group), "name": pip_pkg.split("==")[0], "version": version, "status": "installed", "add_pkgs": dep})
-            else:
-                err_status = 'failed'
-                versions = ''
-                if 'Could not find a version that satisfies the requirement' in err:
-                    versions = err[err.find("(from versions: ") + 16: err.find(")\r\n")]
-                    err_status = 'invalid version'
-                if versions == '':
-                    versions = []
-                else:
+                    [i for i in ver if pip_pkg.split("==")[0].lower() in i][0].split('==')[1]
+                status_msg = "installed"
+            versions = []
+            if 'Could not find a version that satisfies the requirement' in err:
+                versions = err[err.find("(from versions: ") + 16: err.find(")\r\n")]
+                if versions != '':
                     versions = versions.split(', ')
-                status.append({"group": "{}".format(lib_group), "name": pip_pkg.split("==")[0], "status": err_status,
-                                   "error_message": err, "available_versions": versions})
+                    status_msg = 'invalid_version'
+                else:
+                    versions = []
+
+            sudo('if ! grep -w -i -E  "Installing collected packages:" /tmp/tee.tmp > /tmp/{0}install_{1}.log; '
+                 'then  echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg))
+            dep = sudo('cat /tmp/{0}install_{1}.log'.format(pip_version, pip_pkg)).replace('\r\n', '').strip()[31:]
+            if dep == '':
+                dep = []
+            else:
+                dep = dep.split(', ')
+                for n, i in enumerate(dep):
+                    if i == pip_pkg.split("==")[0]:
+                        dep[n] = ''
+                    else:
+                        sudo('{0} show {1} 2>&1 | if ! grep Version: /tmp/tee.tmp > '
+                             '/tmp/{0}_install_{1}.log; then echo "" > /tmp/{0}_install_{1}.log;fi'.format(pip_version, i))
+                        dep[n] = sudo('cat /tmp/{0}_install_{1}.log'.format(pip_version, i)).replace('Version: ', '{} v.'.format(i))
+                dep = [i for i in dep if i]
+            status.append({"group": lib_group, "name": pip_pkg.split("==")[0], "version": version, "status": status_msg,
+                           "error_message": err, "available_versions": versions, "add_pkgs": dep})
         return status
     except Exception as err:
-        append_result("Failed to install {} packages".format(pip_version), str(err))
+        for pip_pkg in requisites:
+            name, vers = pip_pkg
+            status.append({"group": lib_group, "name": name, "version": vers, "status": 'installation_error', "error_message": err})
         print("Failed to install {} packages".format(pip_version))
-        sys.exit(1)
+        return status
 
 
 def id_generator(size=10, chars=string.digits + string.ascii_letters):
@@ -180,8 +186,8 @@
         try:
             sudo('pip2 install notebook==5.7.8 --no-cache-dir')
             sudo('pip2 install jupyter --no-cache-dir')
-            sudo('pip3.5 install notebook=={} --no-cache-dir'.format(jupyter_version))
-            sudo('pip3.5 install jupyter --no-cache-dir')
+            sudo('pip3 install notebook=={} --no-cache-dir'.format(jupyter_version))
+            sudo('pip3 install jupyter --no-cache-dir')
             sudo('rm -rf {}'.format(jupyter_conf_file))
             run('jupyter notebook --generate-config --config {}'.format(jupyter_conf_file))
             with cd('/home/{}'.format(os_user)):
@@ -203,6 +209,15 @@
                      "/caffe/python:/home/" + os_user + "/pytorch/build:$PYTHONPATH ; |g' /tmp/jupyter-notebook.service")
             sudo("sed -i 's|CONF_PATH|{}|' /tmp/jupyter-notebook.service".format(jupyter_conf_file))
             sudo("sed -i 's|OS_USR|{}|' /tmp/jupyter-notebook.service".format(os_user))
+            http_proxy = run('echo $http_proxy')
+            https_proxy = run('echo $https_proxy')
+            #sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTP_PROXY={}\"\'  /tmp/jupyter-notebook.service'.format(
+            #    http_proxy))
+            #sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTPS_PROXY={}\"\'  /tmp/jupyter-notebook.service'.format(
+            #    https_proxy))
+            java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+            sudo('sed -i \'/\[Service\]/ a\Environment=\"JAVA_HOME={}\"\'  /tmp/jupyter-notebook.service'.format(
+                java_home))
             sudo('\cp /tmp/jupyter-notebook.service /etc/systemd/system/jupyter-notebook.service')
             sudo('chown -R {0}:{0} /home/{0}/.local'.format(os_user))
             sudo('mkdir -p /mnt/var')
@@ -234,7 +249,7 @@
                   stable"')
             manage_pkg('update', 'remote', '')
             sudo('apt-cache policy docker-ce')
-            manage_pkg('-y install', 'remote', 'docker-ce={}~ce~3-0~ubuntu'.format(docker_version))
+            manage_pkg('-y install', 'remote', 'docker-ce={}~ce~3-0~ubuntu'.format(docker_version), 'True')
             sudo('touch /home/{}/.ensure_dir/docker_ensured'.format(os_user))
     except Exception as err:
         print('Failed to configure Docker:', str(err))
@@ -419,6 +434,7 @@
     try:
         for r_pkg in requisites:
             name, vers = r_pkg
+            version = vers
             if vers =='N/A':
                 vers = ''
             else:
@@ -436,30 +452,37 @@
             else:
                 dep = dep.split(' ')
                 for n, i in enumerate(dep):
-                    dep[n] = '{} v.{}'.format(dep[n], dep_ver[n])
+                    if i == name:
+                        dep[n] = ''
+                    else:
+                        dep[n] = '{} v.{}'.format(dep[n], dep_ver[n])
                 dep = [i for i in dep if i]
             err = sudo('cat /tmp/install_{0}.log'.format(name)).replace('"', "'")
             sudo('R -e \'installed.packages()[,c(3:4)]\' | if ! grep -w {0} > /tmp/install_{0}.list; then  echo "" > /tmp/install_{0}.list;fi'.format(name))
             res = sudo('cat /tmp/install_{0}.list'.format(name))
-            if res:
+            if err:
+                status_msg = 'installation_error'
+            elif res:
                 ansi_escape = re.compile(r'\x1b[^m]*m')
                 version = ansi_escape.sub('', res).split("\r\n")[0].split('"')[1]
-                status.append({"group": "r_pkg", "name": name, "version": version, "status": "installed", "add_pkgs": dep})
-            else:
-                if 'Error in download_version_url(package, version, repos, type) :' in err:
-                    sudo('R -e \'install.packages("versions", repos="https://cloud.r-project.org", dep=TRUE)\'')
-                    versions = sudo('R -e \'library(versions); available.versions("' + name + '")\' 2>&1 | grep -A 50 '
+                status_msg = 'installed'
+            if 'Error in download_version_url(package, version, repos, type) :' in err:
+                sudo('R -e \'install.packages("versions", repos="https://cloud.r-project.org", dep=TRUE)\'')
+                versions = sudo('R -e \'library(versions); available.versions("' + name + '")\' 2>&1 | grep -A 50 '
                                     '\'date available\' | awk \'{print $2}\'').replace('\r\n', ' ')[5:].split(' ')
-                    status_msg = 'invalid version'
-                else:
-                    versions = []
-                    status_msg = 'failed'
-                status.append({"group": "r_pkg", "name": name, "status": status_msg, "error_message": err, "available_versions": versions})
+                if versions != ['']:
+                    status_msg = 'invalid_version'
+            else:
+                versions = []
+            status.append({"group": "r_pkg", "name": name, "version": version, "status": status_msg, "error_message": err, "available_versions": versions, "add_pkgs": dep})
         return status
     except Exception as err:
-        append_result("Failed to install R packages", str(err))
+        for r_pkg in requisites:
+            name, vers = r_pkg
+            status.append(
+                {"group": "r_pkg", "name": name, "version": vers, "status": 'installation_error', "error_message": err})
         print("Failed to install R packages")
-        sys.exit(1)
+        return status
 
 
 def update_spark_jars(jars_dir='/opt/jars'):
@@ -517,14 +540,16 @@
                 sudo('cp -f $(find {0} -name "*.jar" | xargs) {1}'.format(ivy_cache_dir, dest_dir))
                 status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "version": version, "status": "installed"})
             else:
-                status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "status": "failed", "error_message": err})
+                status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "status": "installation_error", "error_message": err})
         update_spark_jars()
         return status
     except Exception as err:
-        append_result("Failed to install {} packages".format(requisites), str(err))
+        for java_pkg in requisites:
+            group, artifact, version, override = java_pkg
+            status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "status": "installation_error",
+                           "error_message": err})
         print("Failed to install {} packages".format(requisites))
-        sys.exit(1)
-
+        return status
 
 def get_available_r_pkgs():
     try:
@@ -547,8 +572,8 @@
             sudo('ln -s /opt/spark/ /usr/local/spark')
             sudo('jupyter toree install')
             sudo('mv ' + scala_kernel_path + 'lib/* /tmp/')
-            put(files_dir + 'toree-assembly-0.2.0.jar', '/tmp/toree-assembly-0.2.0.jar')
-            sudo('mv /tmp/toree-assembly-0.2.0.jar ' + scala_kernel_path + 'lib/')
+            put(files_dir + 'toree-assembly-0.3.0.jar', '/tmp/toree-assembly-0.3.0.jar')
+            sudo('mv /tmp/toree-assembly-0.3.0.jar ' + scala_kernel_path + 'lib/')
             sudo(
                 'sed -i "s|Apache Toree - Scala|Local Apache Toree - Scala (Scala-' + scala_version +
                 ', Spark-' + spark_version + ')|g" ' + scala_kernel_path + 'kernel.json')
@@ -686,18 +711,28 @@
             sys.exit(1)
 
 
-def configure_data_engine_service_pip(hostname, os_user, keyfile):
+def configure_data_engine_service_pip(hostname, os_user, keyfile, emr=False):
     env['connection_attempts'] = 100
     env.key_filename = [keyfile]
     env.host_string = os_user + '@' + hostname
     if not exists('/usr/bin/pip2'):
-        sudo('ln -s /usr/bin/pip-2.7 /usr/bin/pip2')
+        if not exists('/usr/bin/pip-2.7'):
+            manage_pkg('-y install', 'remote', 'python2-pip')
+        else:
+            sudo('ln -s /usr/bin/pip-2.7 /usr/bin/pip2')
+    manage_pkg('-y install', 'remote', 'python3-pip')
     if not exists('/usr/bin/pip3') and sudo("python3.4 -V 2>/dev/null | awk '{print $2}'"):
         sudo('ln -s /usr/bin/pip-3.4 /usr/bin/pip3')
     elif not exists('/usr/bin/pip3') and sudo("python3.5 -V 2>/dev/null | awk '{print $2}'"):
         sudo('ln -s /usr/bin/pip-3.5 /usr/bin/pip3')
     elif not exists('/usr/bin/pip3') and sudo("python3.6 -V 2>/dev/null | awk '{print $2}'"):
         sudo('ln -s /usr/bin/pip-3.6 /usr/bin/pip3')
+    elif not exists('/usr/bin/pip3') and sudo("python3.7 -V 2>/dev/null | awk '{print $2}'"):
+        sudo('ln -s /usr/bin/pip-3.7 /usr/bin/pip3')
+    if emr:
+        sudo('pip3 install -U pip=={}'.format(os.environ['conf_pip_version']))
+        sudo('pip2 install -U pip=={}'.format(os.environ['conf_pip_version']))
+        sudo('ln -s /usr/local/bin/pip3.7 /bin/pip3.7')
     sudo('echo "export PATH=$PATH:/usr/local/bin" >> /etc/profile')
     sudo('source /etc/profile')
     run('source /etc/profile')
diff --git a/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py b/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py
index 34bae34..d159289 100644
--- a/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py
@@ -346,23 +346,62 @@
 def install_os_pkg(requisites):
     status = list()
     error_parser = "Could not|No matching|Error:|failed|Requires:|Errno"
+    new_pkgs_parser = "Dependency Installed:"
     try:
         print("Updating repositories and installing requested tools: {}".format(requisites))
         manage_pkg('update-minimal --security -y --skip-broken', 'remote', '')
         sudo('export LC_ALL=C')
         for os_pkg in requisites:
-            manage_pkg('-y install', 'remote', '{0} --nogpgcheck 2>&1 | if ! grep -w -E  "({1})" >  /tmp/os_install_{0}.log; then  echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, error_parser))
+            name, vers = os_pkg
+            if vers != '' and vers !='N/A':
+                version = vers
+                os_pkg = "{}-{}".format(name, vers)
+            else:
+                version = 'N/A'
+                os_pkg = name
+            manage_pkg('-y install', 'remote', '{0} --nogpgcheck 2>&1 | tee /tmp/tee.tmp; if ! grep -w -E  "({1})" /tmp/tee.tmp >  /tmp/os_install_{0}.log; then  echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, error_parser))
+            install_output = sudo('cat /tmp/tee.tmp')
             err = sudo('cat /tmp/os_install_{}.log'.format(os_pkg)).replace('"', "'")
-            try:
-                res = sudo('python -c "import os,sys,yum; yb = yum.YumBase(); pl = yb.doPackageLists(); print [pkg.vr for pkg in pl.installed if pkg.name == \'{0}\'][0]"'.format(os_pkg))
+            sudo('cat /tmp/tee.tmp | if ! grep -w -E -A 30 "({1})" /tmp/tee.tmp > '
+                 '/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, new_pkgs_parser))
+            dep = sudo('cat /tmp/os_install_{}.log'.format(os_pkg))
+            if dep == '':
+                dep = []
+            else:
+                dep = dep[len(new_pkgs_parser): dep.find("Complete!") - 1].replace('  ', '').strip().split('\r\n')
+                for n, i in enumerate(dep):
+                    i = i.split('.')[0]
+                    sudo('yum info {0} 2>&1 | if ! grep Version > /tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(i))
+                    dep[n] =sudo('cat /tmp/os_install_{}.log'.format(i)).replace('Version     : ', '{} v.'.format(i))
+                dep = [i for i in dep if i]
+            versions = []
+            res = sudo(
+                'python -c "import os,sys,yum; yb = yum.YumBase(); pl = yb.doPackageLists(); print [pkg.vr for pkg in pl.installed if pkg.name == \'{0}\'][0]"'.format(
+                    name))
+            if err:
+                status_msg = 'installation_error'
+            elif res:
                 version = res.split('\r\n')[1].replace("'", "\"")
-                status.append({"group": "os_pkg", "name": os_pkg, "version": version, "status": "installed"})
-            except:
-                status.append({"group": "os_pkg", "name": os_pkg, "status": "failed", "error_message": err})
+                status_msg = "installed"
+            if 'No package {} available'.format(os_pkg) in install_output:
+                versions = sudo ('yum --showduplicates list ' + name + ' | expand | grep -A 10 "Available Packages" | grep -v "Available Packages"| awk \'{print $2}\'').replace('\r\n', '').split(' ')
+                if versions != '':
+                    status_msg = 'invalid_version'
+                    for n, i in enumerate(versions):
+                        if ':' in i:
+                            versions[n] = i.split(':')[1].split('-')[0]
+                        else:
+                            versions[n] = i.split('-')[0]
+            status.append({"group": "os_pkg", "name": name, "version": version, "status": status_msg,
+                           "error_message": err, "add_pkgs": dep, "available_versions": versions})
         return status
-    except:
-        return "Fail to install OS packages"
-
+    except Exception as err:
+        for os_pkg in requisites:
+            name, vers = os_pkg
+            status.append(
+                {"group": "os_pkg", "name": name, "version": vers, "status": 'installation_error', "error_message": err})
+        print("Failed to install OS packages: {}".format(requisites))
+        return status
 
 def remove_os_pkg(pkgs):
     try:
@@ -462,14 +501,14 @@
         sudo('touch /home/{}/.ensure_dir/mxnet_ensured'.format(os_user))
 
 
-def install_torch(os_user):
-    if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
-        run('git clone https://github.com/torch/distro.git ~/torch --recursive')
-        with cd('/home/{}/torch/'.format(os_user)):
-            manage_pkg('-y install --nogpgcheck', 'remote', 'cmake curl readline-devel ncurses-devel gcc-c++ gcc-gfortran git gnuplot unzip libjpeg-turbo-devel libpng-devel ImageMagick GraphicsMagick-devel fftw-devel sox-devel sox zeromq3-devel qt-devel qtwebkit-devel sox-plugins-freeworld qt-devel')
-            run('./install.sh -b')
-        run('source /home/{}/.bashrc'.format(os_user))
-        sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
+#def install_torch(os_user):
+#    if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
+#        run('git clone https://github.com/torch/distro.git ~/torch --recursive')
+#        with cd('/home/{}/torch/'.format(os_user)):
+#            manage_pkg('-y install --nogpgcheck', 'remote', 'cmake curl readline-devel ncurses-devel gcc-c++ gcc-gfortran git gnuplot unzip libjpeg-turbo-devel libpng-devel ImageMagick GraphicsMagick-devel fftw-devel sox-devel sox zeromq3-devel qt-devel qtwebkit-devel sox-plugins-freeworld qt-devel')
+#            run('./install.sh -b')
+#        run('source /home/{}/.bashrc'.format(os_user))
+#        sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
 
 
 def install_gitlab_cert(os_user, certfile):
diff --git a/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py b/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py
index b4dc3c6..83dd48a 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py
@@ -129,20 +129,23 @@
             subnet_id = get_subnet_by_cidr(subnet_check)
         print("SUBNET_ID: {}".format(subnet_id))
         if not args.ssn:
-            print("Associating route_table with the subnet")
-            ec2 = boto3.resource('ec2')
-            if os.environ['conf_duo_vpc_enable'] == 'true':
-                rt = get_route_table_by_tag(args.infra_tag_value + '-secondary-tag', args.infra_tag_value)
+            if os.environ['edge_is_nat'] == 'true':
+                print('Subnet will be associted with route table for NAT')
             else:
-                rt = get_route_table_by_tag(args.infra_tag_name, args.infra_tag_value)
-            route_table = ec2.RouteTable(rt)
-            try:
-                route_table.associate_with_subnet(SubnetId=subnet_id)
+                print("Associating route_table with the subnet")
+                ec2 = boto3.resource('ec2')
                 if os.environ['conf_duo_vpc_enable'] == 'true':
-                    create_peer_routes(os.environ['aws_peering_id'], args.infra_tag_value)
-            except exceptions.ClientError as err:
-                if 'Resource.AlreadyAssociated' in str(err):
-                    print('Other route table is already associted with this subnet. Skipping...')
+                    rt = get_route_table_by_tag(args.infra_tag_value + '-secondary-tag', args.infra_tag_value)
+                else:
+                    rt = get_route_table_by_tag(args.infra_tag_name, args.infra_tag_value)
+                route_table = ec2.RouteTable(rt)
+                try:
+                    route_table.associate_with_subnet(SubnetId=subnet_id)
+                    if os.environ['conf_duo_vpc_enable'] == 'true':
+                        create_peer_routes(os.environ['aws_peering_id'], args.infra_tag_value)
+                except exceptions.ClientError as err:
+                    if 'Resource.AlreadyAssociated' in str(err):
+                        print('Other route table is already associted with this subnet. Skipping...')
         else:
             print("Associating route_table with the subnet")
             ec2 = boto3.resource('ec2')
diff --git a/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py b/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py
index 5c481ac..5a1a6f0 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py
@@ -78,7 +78,7 @@
                                                                       notebook_config['project_name'],
                                                                       notebook_config['endpoint_name'],
                                                                       notebook_config['exploratory_name'], args.uuid)
-        notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '12')(
+        notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '16')(
             os.environ['application'])
         notebook_config['role_profile_name'] = '{}-{}-{}-nb-de-profile'.format(
             notebook_config['service_base_name'], notebook_config['project_name'], notebook_config['endpoint_name'])
diff --git a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py
index 9e9fb40..147247a 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py
@@ -33,6 +33,7 @@
 import logging
 import argparse
 import multiprocessing
+from dlab.common_lib import manage_pkg
 
 
 parser = argparse.ArgumentParser()
@@ -81,12 +82,13 @@
         print('[CONFIGURE DATAENGINE SERVICE]')
         try:
             dlab.fab.configure_data_engine_service_pip(emr_conf['instance_ip'], emr_conf['os_user'],
-                                                       emr_conf['key_path'])
+                                                       emr_conf['key_path'], True)
             env['connection_attempts'] = 100
             env.key_filename = emr_conf['key_path']
             env.host_string = emr_conf['os_user'] + '@' + emr_conf['instance_ip']
             sudo('echo "[main]" > /etc/yum/pluginconf.d/priorities.conf ; echo "enabled = 0" >> '
                  '/etc/yum/pluginconf.d/priorities.conf')
+            manage_pkg('-y install', 'remote', 'R-devel')
         except:
             traceback.print_exc()
             raise Exception
@@ -174,7 +176,7 @@
             emr_conf['computational_name'] = os.environ['computational_name']
         else:
             emr_conf['computational_name'] = ''
-        emr_conf['apps'] = 'Hadoop Hive Hue Spark'
+        emr_conf['apps'] = 'Hadoop Hive Hue Spark Livy'
         emr_conf['service_base_name'] = os.environ['conf_service_base_name']
         emr_conf['project_name'] = os.environ['project_name']
         emr_conf['endpoint_name'] = os.environ['endpoint_name']
diff --git a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py
index 0626285..699f07c 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py
@@ -63,7 +63,7 @@
     with open('/tmp/r_version', 'w') as outfile:
         outfile.write(r_ver)
     os.system('touch /tmp/python_version')
-    for v in range(4, 7):
+    for v in range(4, 8):
         python_ver_checker = "python3.{} -V 2>/dev/null".format(v) + " | awk '{print $2}'"
         python_ver = subprocess.check_output(python_ver_checker, shell=True)
         if python_ver != '':
diff --git a/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py b/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py
index d96ef49..2a809f6 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py
@@ -161,6 +161,21 @@
         except:
             traceback.print_exc()
             raise Exception
+        print('RESTARTING EDGE NODE')
+        try:
+            print('Stoping EDGE node')
+            dlab.actions_lib.stop_ec2(edge_conf['tag_name'], edge_conf['instance_name'])
+        except Exception as err:
+            print('Error: {0}'.format(err))
+            dlab.fab.append_result("Failed to stop edge.", str(err))
+            sys.exit(1)
+        try:
+            print('Starting EDGE node')
+            dlab.actions_lib.start_ec2(edge_conf['tag_name'], edge_conf['instance_name'])
+        except Exception as err:
+            print('Error: {0}'.format(err))
+            dlab.fab.append_result("Failed to start edge.", str(err))
+            sys.exit(1)
     except Exception as err:
         dlab.fab.append_result("Failed installing apps: apt & pip.", str(err))
         clear_resources()
@@ -245,6 +260,25 @@
         sys.exit(1)
 
     try:
+        print('[CONFIGRING EDGE AS NAT]')
+        if os.environ['edge_is_nat'] == 'true':
+            print('Installing nftables')
+            additional_config = {"exploratory_subnet": edge_conf['private_subnet_cidr'],
+                                 "edge_ip": edge_conf['edge_private_ip']}
+            params = "--hostname {} --keyfile {} --additional_config '{}' --user {}".format(
+                edge_conf['instance_hostname'], edge_conf['keyfile_name'], json.dumps(additional_config),
+                edge_conf['dlab_ssh_user'])
+            try:
+                local("~/scripts/{}.py {}".format('configure_nftables', params))
+            except:
+                traceback.print_exc()
+                raise Exception
+    except Exception as err:
+        dlab.fab.append_result("Failed to configure NAT." + str(err))
+        clear_resources()
+        sys.exit(1)
+
+    try:
         print('[SUMMARY]')
         logging.info('[SUMMARY]')
         print("Instance name: {}".format(edge_conf['instance_name']))
diff --git a/infrastructure-provisioning/src/general/scripts/aws/edge_configure_route_table.py b/infrastructure-provisioning/src/general/scripts/aws/edge_configure_route_table.py
new file mode 100644
index 0000000..c3ac2e4
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/edge_configure_route_table.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import argparse
+from dlab.actions_lib import *
+from dlab.meta_lib import *
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--vpc_id', type=str, default='')
+parser.add_argument('--infra_tag_value', type=str, default='')
+parser.add_argument('--edge_instance_id', type=str, default='')
+parser.add_argument('--private_subnet_id', type=str, default='')
+args = parser.parse_args()
+
+if __name__ == "__main__":
+    rt_id = create_nat_rt(args.vpc_id, args.infra_tag_value, args.edge_instance_id, args.private_subnet_id)
+
diff --git a/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py b/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py
index 5f17c07..1bb09b3 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py
@@ -52,6 +52,8 @@
 parser.add_argument('--pip_mirror', type=str, default='')
 parser.add_argument('--numpy_version', type=str, default='')
 parser.add_argument('--application', type=str, default='')
+parser.add_argument('--master_ip', type=str, default='')
+parser.add_argument('--python_version', type=str, default='')
 args = parser.parse_args()
 
 emr_dir = '/opt/' + args.emr_version + '/jars/'
@@ -106,8 +108,8 @@
     else:
         local('mkdir -p ' + kernels_dir + 'toree_' + args.cluster_name + '/')
         local('tar zxvf /tmp/toree_kernel.tar.gz -C ' + kernels_dir + 'toree_' + args.cluster_name + '/')
-        local('sudo mv {0}toree_{1}/toree-0.2.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
-        local('sudo rm -r {0}toree_{1}/toree-0.2.0-incubating'.format(kernels_dir, args.cluster_name))
+        local('sudo mv {0}toree_{1}/toree-0.3.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
+        local('sudo rm -r {0}toree_{1}/toree-0.3.0-incubating'.format(kernels_dir, args.cluster_name))
         kernel_path = kernels_dir + "toree_" + args.cluster_name + "/kernel.json"
         template_file = "/tmp/toree_dataengine-service_templatev2.json"
         with open(template_file, 'r') as f:
@@ -162,22 +164,57 @@
     local(""" sudo bash -c "sed -i '/spark.driver.extraClassPath/s/$/:\/opt\/""" + args.emr_version +
           """\/jars\/usr\/other\/*/' """ + spark_defaults_path + """" """)
 
+def install_sparkamagic_kernels(args):
+    try:
+        local('sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension')
+        sparkmagic_dir = local("sudo pip3 show sparkmagic | grep 'Location: ' | awk '{print $2}'", capture=True)
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkkernel --user'.format(sparkmagic_dir))
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/pysparkkernel --user'.format(sparkmagic_dir))
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkrkernel --user'.format(sparkmagic_dir))
+        pyspark_kernel_name = 'PySpark (Python-{0} / Spark-{1} ) [{2}]'.format(args.python_version, args.spark_version,
+                                                                         args.cluster_name)
+        local('sed -i \'s|PySpark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/pysparkkernel/kernel.json'.format(
+            pyspark_kernel_name, args.os_user))
+        spark_kernel_name = 'Spark (Scala-{0} / Spark-{1} ) [{2}]'.format(args.scala_version, args.spark_version,
+                                                                         args.cluster_name)
+        local('sed -i \'s|Spark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkkernel/kernel.json'.format(
+            spark_kernel_name, args.os_user))
+        sparkr_kernel_name = 'SparkR (R-{0} / Spark-{1} ) [{2}]'.format(args.r_version, args.spark_version,
+                                                                            args.cluster_name)
+        local('sed -i \'s|SparkR|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkrkernel/kernel.json'.format(
+            sparkr_kernel_name, args.os_user))
+        local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/pysparkkernel '
+              '/home/{0}/.local/share/jupyter/kernels/pysparkkernel_{1}'.format(args.os_user, args.cluster_name))
+        local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkkernel '
+              '/home/{0}/.local/share/jupyter/kernels/sparkkernel_{1}'.format(args.os_user, args.cluster_name))
+        local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkrkernel '
+              '/home/{0}/.local/share/jupyter/kernels/sparkrkernel_{1}'.format(args.os_user, args.cluster_name))
+        local('mkdir -p /home/' + args.os_user + '/.sparkmagic')
+        local('cp -f /tmp/sparkmagic_config_template.json /home/' + args.os_user + '/.sparkmagic/config.json')
+        local('sed -i \'s|LIVY_HOST|{0}|g\' /home/{1}/.sparkmagic/config.json'.format(
+                args.master_ip, args.os_user))
+        local('sudo chown -R {0}:{0} /home/{0}/.sparkmagic/'.format(args.os_user))
+    except:
+        sys.exit(1)
+
+
 
 if __name__ == "__main__":
     if args.dry_run == 'true':
         parser.print_help()
     else:
-        result = prepare(emr_dir, yarn_dir)
-        if result == False :
-            jars(args, emr_dir)
-        yarn(args, yarn_dir)
-        install_emr_spark(args)
-        pyspark_kernel(kernels_dir, args.emr_version, args.cluster_name, args.spark_version, args.bucket,
-                       args.project_name, args.region, args.os_user, args.application, args.pip_mirror, args.numpy_version)
-        toree_kernel(args)
-        if args.r_version != 'false':
-            print('R version: {}'.format(args.r_version))
-            r_kernel(args)
-        spark_defaults(args)
-        configuring_notebook(args.emr_version)
-        add_breeze_library_emr(args)
+        install_sparkamagic_kernels(args)
+        #result = prepare(emr_dir, yarn_dir)
+        #if result == False :
+        #    jars(args, emr_dir)
+        #yarn(args, yarn_dir)
+        #install_emr_spark(args)
+        #pyspark_kernel(kernels_dir, args.emr_version, args.cluster_name, args.spark_version, args.bucket,
+        #               args.project_name, args.region, args.os_user, args.application, args.pip_mirror, args.numpy_version)
+        #toree_kernel(args)
+        #if args.r_version != 'false':
+        #    print('R version: {}'.format(args.r_version))
+        #    r_kernel(args)
+        #spark_defaults(args)
+        #configuring_notebook(args.emr_version)
+        #add_breeze_library_emr(args)
diff --git a/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py b/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py
index fb29f0a..37d102a 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py
@@ -50,14 +50,15 @@
     templates_dir = '/root/templates/'
     files_dir = '/root/files/'
     scripts_dir = '/root/scripts/'
-    put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
-    put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
-    put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
+    put(templates_dir + 'sparkmagic_config_template.json', '/tmp/sparkmagic_config_template.json')
+    #put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
+    #put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
+    #put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
     put(scripts_dir + '{}_dataengine-service_create_configs.py'.format(args.application),
         '/tmp/jupyter_dataengine-service_create_configs.py')
-    put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
-    put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
-    put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
+    #put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
+    #put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
+    #put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
     sudo('\cp /tmp/jupyter_dataengine-service_create_configs.py /usr/local/bin/jupyter_dataengine-service_create_configs.py')
     sudo('chmod 755 /usr/local/bin/jupyter_dataengine-service_create_configs.py')
     sudo('mkdir -p /usr/lib/python2.7/dlab/')
@@ -82,9 +83,14 @@
     s3_client = boto3.client('s3', config=Config(signature_version='s3v4'), region_name=args.region)
     s3_client.download_file(args.bucket, args.project_name + '/' + args.cluster_name + '/scala_version',
                             '/tmp/scala_version')
+    s3_client.download_file(args.bucket, args.project_name + '/' + args.cluster_name + '/python_version',
+                            '/tmp/python_version')
     with file('/tmp/scala_version') as f:
         scala_version = str(f.read()).rstrip()
         print(scala_version)
+    with file('/tmp/python_version') as f:
+        python_version = str(f.read()).rstrip()
+        print(python_version)
     if r_enabled == 'true':
         s3_client.download_file(args.bucket, args.project_name + '/' + args.cluster_name + '/r_version', '/tmp/r_version')
         with file('/tmp/r_version') as g:
@@ -92,9 +98,13 @@
             print(r_version)
     else:
         r_version = 'false'
+    cluster_id = get_emr_id_by_name(args.cluster_name)
+    master_instances = get_emr_instances_list(cluster_id, 'MASTER')
+    master_ip = master_instances[0].get('PrivateIpAddress')
     sudo("/usr/bin/python /usr/local/bin/jupyter_dataengine-service_create_configs.py --bucket " + args.bucket
          + " --cluster_name " + args.cluster_name + " --emr_version " + args.emr_version + " --spark_version "
          + spark_version + " --scala_version " + scala_version + " --r_version " + r_version + " --hadoop_version "
          + hadoop_version + " --region " + args.region + " --excluded_lines '" + args.emr_excluded_spark_properties
          + "' --project_name " + args.project_name + " --os_user " + args.os_user + " --pip_mirror "
-         + args.pip_mirror + " --numpy_version " + numpy_version + " --application " + args.application)
+         + args.pip_mirror + " --numpy_version " + numpy_version + " --application "
+         + args.application + " --master_ip " + master_ip + " --python_version " + python_version)
diff --git a/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py b/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py
index 9d44ba5..9986ab2 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py
@@ -60,6 +60,7 @@
             os.environ['conf_os_family'])])
         project_conf['instance_size'] = os.environ['aws_edge_instance_size']
         project_conf['sg_ids'] = os.environ['aws_security_groups_ids']
+        project_conf['instance_class'] = 'edge'
         project_conf['edge_instance_name'] = '{}-{}-{}-edge'.format(project_conf['service_base_name'],
                                                                     project_conf['project_name'],
                                                                     project_conf['endpoint_name'])
@@ -400,6 +401,12 @@
                 "FromPort": 389,
                 "IpRanges": [{"CidrIp": project_conf['all_ip_cidr']}],
                 "ToPort": 389, "IpProtocol": "tcp", "UserIdGroupPairs": []
+            },
+            {
+                "PrefixListIds": [],
+                "FromPort": -1,
+                "IpRanges": [{"CidrIp": project_conf['all_ip_cidr']}],
+                "ToPort": -1, "IpProtocol": "icmp", "UserIdGroupPairs": []
             }
         ])
         params = "--name {} --vpc_id {} --security_group_rules '{}' --infra_tag_name {} --infra_tag_value {} \
@@ -622,6 +629,12 @@
             local("~/scripts/{}.py {}".format('common_create_instance', params))
             edge_instance = dlab.meta_lib.get_instance_by_name(project_conf['tag_name'],
                                                                project_conf['edge_instance_name'])
+            if os.environ['edge_is_nat']:
+                try:
+                    dlab.actions_lib.modify_instance_sourcedescheck(edge_instance)
+                except:
+                    traceback.print_exc()
+                    raise Exception
         except:
             traceback.print_exc()
             raise Exception
@@ -670,3 +683,34 @@
             dlab.actions_lib.remove_sgroups(project_conf['edge_instance_name'])
             dlab.actions_lib.remove_s3('edge', project_conf['project_name'])
             sys.exit(1)
+
+    if os.environ['edge_is_nat'] == 'true':
+        try:
+            print('[CONFIGURING ROUTE TABLE FOR NAT]')
+            project_conf['nat_rt_name'] = '{0}-{1}-{2}-nat-rt'.format(project_conf['service_base_name'],
+                                                                              project_conf['project_name'],
+                                                                              project_conf['endpoint_name'])
+            params = "--vpc_id {} --infra_tag_value {} --edge_instance_id {} --private_subnet_id {}".format(
+                project_conf['vpc2_id'], project_conf['nat_rt_name'], edge_instance, subnet_id)
+            try:
+                local("~/scripts/{}.py {}".format('edge_configure_route_table', params))
+            except:
+                traceback.print_exc()
+                raise Exception
+        except Exception as err:
+            dlab.fab.append_result("Failed to configure route table.", str(err))
+            try:
+                project_conf['edge_public_ip'] = dlab.meta_lib.get_instance_ip_address(
+                    project_conf['tag_name'], project_conf['edge_instance_name']).get('Public')
+                project_conf['allocation_id'] = dlab.meta_lib.get_allocation_id_by_elastic_ip(
+                    project_conf['edge_public_ip'])
+            except:
+                print("No Elastic IPs to release!")
+            dlab.actions_lib.remove_ec2(project_conf['tag_name'], project_conf['edge_instance_name'])
+            dlab.actions_lib.remove_all_iam_resources('notebook', project_conf['project_name'])
+            dlab.actions_lib.remove_all_iam_resources('edge', project_conf['project_name'])
+            dlab.actions_lib.remove_sgroups(project_conf['dataengine_instances_name'])
+            dlab.actions_lib.remove_sgroups(project_conf['notebook_instance_name'])
+            dlab.actions_lib.remove_sgroups(project_conf['edge_instance_name'])
+            dlab.actions_lib.remove_s3('edge', project_conf['project_name'])
+            sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/common_create_nat_route.py b/infrastructure-provisioning/src/general/scripts/gcp/common_create_nat_route.py
new file mode 100644
index 0000000..8f03ea8
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/gcp/common_create_nat_route.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import json
+import argparse
+from dlab.actions_lib import *
+from dlab.meta_lib import *
+import sys
+from botocore.exceptions import ClientError
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--nat_route_name', type=str)
+parser.add_argument('--vpc', type=str)
+parser.add_argument('--tag', type=str)
+parser.add_argument('--edge_instance', type=str)
+args = parser.parse_args()
+
+
+if __name__ == "__main__":
+    if GCPMeta().get_route(args.nat_route_name):
+        print("REQUESTED ROUTE {} ALREADY EXISTS".format(args.nat_route_name))
+    else:
+        print("Creating NAT ROUTE {}".format(args.nat_route_name))
+        params = {
+            "destRange": "0.0.0.0/0",
+            "name": args.nat_route_name,
+            "network": args.vpc,
+            "priority": 0,
+            "tags": [
+                args.tag
+            ],
+            "nextHopInstance": args.edge_instance
+        }
+        GCPActions().create_nat_route(params)
+else:
+    parser.print_help()
+    sys.exit(2)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py b/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py
index 5f7931f..dcba179 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py
@@ -96,7 +96,7 @@
                                                                        notebook_config['project_name'],
                                                                        notebook_config['endpoint_name'],
                                                                        notebook_config['exploratory_name'])
-        notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '12')(
+        notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '16')(
             os.environ['application'])
         notebook_config['secondary_disk_size'] = os.environ['notebook_disk_size']
 
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py
index c07e515..04870f2 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py
@@ -44,7 +44,7 @@
         outfile.write(r_ver)
 
     os.system('touch /tmp/python_version')
-    for v in range(4, 7):
+    for v in range(4, 8):
         python_ver_checker = "python3.{} -V 2>/dev/null".format(v) + " | awk '{print $2}'"
         python_ver = subprocess.check_output(python_ver_checker, shell=True).decode('UTF-8')
         if python_ver != '':
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py
index 993b8e7..91d16e2 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py
@@ -152,6 +152,8 @@
     dataproc_cluster['config']['workerConfig']['machineTypeUri'] = os.environ['dataproc_slave_instance_type']
     dataproc_cluster['config']['masterConfig']['numInstances'] = int(os.environ['dataproc_master_count'])
     dataproc_cluster['config']['workerConfig']['numInstances'] = int(os.environ['dataproc_slave_count'])
+    livy_init = 'gs://goog-dataproc-initialization-actions-{}/livy/livy.sh'.format(dataproc_conf['region'])
+    dataproc_cluster['config']['initializationActions'][0]['executableFile'] = livy_init
     if int(os.environ['dataproc_preemptible_count']) != 0:
         dataproc_cluster['config']['secondaryWorkerConfig']['numInstances'] = int(
             os.environ['dataproc_preemptible_count'])
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py b/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py
index 110efb9..7b2286d 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py
@@ -267,6 +267,25 @@
         sys.exit(1)
 
     try:
+        print('[CONFIGRING EDGE AS NAT]')
+        if os.environ['edge_is_nat'] == 'true':
+            print('Installing nftables')
+            additional_config = {"exploratory_subnet": edge_conf['private_subnet_cidr'],
+                                 "edge_ip": edge_conf['private_ip']}
+            params = "--hostname {} --keyfile {} --additional_config '{}' --user {}".format(
+                edge_conf['instance_hostname'], edge_conf['ssh_key_path'], json.dumps(additional_config),
+                edge_conf['dlab_ssh_user'])
+            try:
+                local("~/scripts/{}.py {}".format('configure_nftables', params))
+            except:
+                traceback.print_exc()
+                raise Exception
+    except Exception as err:
+        dlab.fab.append_result("Failed to configure NAT." + str(err))
+        clear_resources()
+        sys.exit(1)
+
+    try:
         print('[SUMMARY]')
         logging.info('[SUMMARY]')
         print("Instance name: {}".format(edge_conf['instance_name']))
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py
index 9bc8e37..2e7929c 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py
@@ -51,6 +51,8 @@
 parser.add_argument('--r_version', type=str, default='')
 parser.add_argument('--r_enabled', type=str, default='')
 parser.add_argument('--scala_version', type=str, default='')
+parser.add_argument('--python_version', type=str, default='')
+parser.add_argument('--master_ip', type=str, default='')
 args = parser.parse_args()
 
 dataproc_dir = '/opt/{}/jars/'.format(args.dataproc_version)
@@ -82,8 +84,8 @@
     spark_path = '/opt/{0}/{1}/spark/'.format(args.dataproc_version, args.cluster_name)
     local('mkdir -p {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
     local('tar zxvf /tmp/toree_kernel.tar.gz -C {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
-    local('sudo mv {0}toree_{1}/toree-0.2.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
-    local('sudo rm -r {0}toree_{1}/toree-0.2.0-incubating'.format(kernels_dir, args.cluster_name))
+    local('sudo mv {0}toree_{1}/toree-0.3.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
+    local('sudo rm -r {0}toree_{1}/toree-0.3.0-incubating'.format(kernels_dir, args.cluster_name))
     kernel_path = '{0}toree_{1}/kernel.json'.format(kernels_dir, args.cluster_name)
     template_file = "/tmp/toree_dataengine-service_templatev2.json"
     with open(template_file, 'r') as f:
@@ -111,20 +113,47 @@
     with open(run_sh_path, 'w') as f:
         f.write(text)
 
+def install_sparkamagic_kernels(args):
+    try:
+        local('sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension')
+        sparkmagic_dir = local("sudo pip3 show sparkmagic | grep 'Location: ' | awk '{print $2}'", capture=True)
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkkernel --user'.format(sparkmagic_dir))
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/pysparkkernel --user'.format(sparkmagic_dir))
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkrkernel --user'.format(sparkmagic_dir))
+        pyspark_kernel_name = 'PySpark (Python-{0} / Spark-{1} ) [{2}]'.format(args.python_version, args.spark_version,
+                                                                         args.cluster_name)
+        local('sed -i \'s|PySpark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/pysparkkernel/kernel.json'.format(
+            pyspark_kernel_name, args.os_user))
+        spark_kernel_name = 'Spark (Scala-{0} / Spark-{1} ) [{2}]'.format(args.scala_version, args.spark_version,
+                                                                         args.cluster_name)
+        local('sed -i \'s|Spark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkkernel/kernel.json'.format(
+            spark_kernel_name, args.os_user))
+        sparkr_kernel_name = 'SparkR (R-{0} / Spark-{1} ) [{2}]'.format(args.r_version, args.spark_version,
+                                                                            args.cluster_name)
+        local('sed -i \'s|SparkR|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkrkernel/kernel.json'.format(
+            sparkr_kernel_name, args.os_user))
+        local('mkdir -p /home/' + args.os_user + '/.sparkmagic')
+        local('cp -f /tmp/sparkmagic_config_template.json /home/' + args.os_user + '/.sparkmagic/config.json')
+        local('sed -i \'s|LIVY_HOST|{0}|g\' /home/{1}/.sparkmagic/config.json'.format(
+                args.master_ip, args.os_user))
+        local('sudo chown -R {0}:{0} /home/{0}/.sparkmagic/'.format(args.os_user))
+    except:
+        sys.exit(1)
 
 if __name__ == "__main__":
     if args.dry_run == 'true':
         parser.print_help()
     else:
-        result = prepare(dataproc_dir, yarn_dir)
-        if result == False :
-            actions_lib.GCPActions().jars(args, dataproc_dir)
-        actions_lib.GCPActions().yarn(args, yarn_dir)
-        actions_lib.GCPActions().install_dataproc_spark(args)
-        pyspark_kernel(kernels_dir, args.dataproc_version, args.cluster_name, args.spark_version, args.bucket,
-                       args.user_name, args.region, args.os_user, args.application, args.pip_mirror)
-        toree_kernel(args)
-        if args.r_enabled == 'true':
-            r_kernel(args)
-        actions_lib.GCPActions().spark_defaults(args)
-        configuring_notebook(args.dataproc_version)
+        install_sparkamagic_kernels(args)
+        #result = prepare(dataproc_dir, yarn_dir)
+        #if result == False :
+        #    actions_lib.GCPActions().jars(args, dataproc_dir)
+        #actions_lib.GCPActions().yarn(args, yarn_dir)
+        #actions_lib.GCPActions().install_dataproc_spark(args)
+        #pyspark_kernel(kernels_dir, args.dataproc_version, args.cluster_name, args.spark_version, args.bucket,
+        #               args.user_name, args.region, args.os_user, args.application, args.pip_mirror)
+        #toree_kernel(args)
+        #if args.r_enabled == 'true':
+        #    r_kernel(args)
+        #actions_lib.GCPActions().spark_defaults(args)
+        #configuring_notebook(args.dataproc_version)
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py
index cb17668..24586af 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py
@@ -51,13 +51,14 @@
     templates_dir = '/root/templates/'
     files_dir = '/root/files/'
     scripts_dir = '/root/scripts/'
-    put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
-    put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
-    put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
+    put(templates_dir + 'sparkmagic_config_template.json', '/tmp/sparkmagic_config_template.json')
+    #put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
+    #put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
+    #put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
     put(scripts_dir + '{}_dataengine-service_create_configs.py'.format(args.application), '/tmp/create_configs.py')
-    put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
-    put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
-    put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
+    #put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
+    #put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
+    #put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
     sudo('\cp /tmp/create_configs.py /usr/local/bin/create_configs.py')
     sudo('chmod 755 /usr/local/bin/create_configs.py')
     sudo('mkdir -p /usr/lib/python2.7/dlab/')
@@ -81,14 +82,21 @@
     configure_notebook(args)
     spark_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
                                                                      args.cluster_name, 'spark')
+    python_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
+                                                                     args.cluster_name, 'python')
     hadoop_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
                                                                       args.cluster_name, 'hadoop')
     r_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
                                                                  args.cluster_name, 'r')
     r_enabled = os.environ['notebook_r_enabled']
+    master_host = '{}-m'.format(args.cluster_name)
+    master_ip = get_instance_private_ip_address(os.environ['gcp_zone'], master_host)
     sudo('echo "[global]" > /etc/pip.conf; echo "proxy = $(cat /etc/profile | grep proxy | head -n1 | cut -f2 -d=)" >> /etc/pip.conf')
     sudo('echo "use_proxy=yes" > ~/.wgetrc; proxy=$(cat /etc/profile | grep proxy | head -n1 | cut -f2 -d=); echo "http_proxy=$proxy" >> ~/.wgetrc; echo "https_proxy=$proxy" >> ~/.wgetrc')
-    sudo('unset http_proxy https_proxy; export gcp_project_id="{0}"; export conf_resource="{1}"; /usr/bin/python /usr/local/bin/create_configs.py --bucket {2} --cluster_name {3} --dataproc_version {4} --spark_version {5} --hadoop_version {6} --region {7} --user_name {8} --os_user {9} --pip_mirror {10} --application {11} --r_version {12} --r_enabled {13} --scala_version {14}'
+    sudo('unset http_proxy https_proxy; export gcp_project_id="{0}"; export conf_resource="{1}"; '
+         '/usr/bin/python /usr/local/bin/create_configs.py --bucket {2} --cluster_name {3} --dataproc_version {4}'
+         ' --spark_version {5} --hadoop_version {6} --region {7} --user_name {8} --os_user {9} --pip_mirror {10} '
+         '--application {11} --r_version {12} --r_enabled {13} --python_version {14}  --master_ip {15} --scala_version {16}'
          .format(os.environ['gcp_project_id'], os.environ['conf_resource'], args.bucket, args.cluster_name,
                  args.dataproc_version, spark_version, hadoop_version, args.region, args.project_name, args.os_user,
-                 args.pip_mirror, args.application, r_version, r_enabled, scala_version))
+                 args.pip_mirror, args.application, r_version, r_enabled, python_version, master_ip, scala_version))
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py b/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py
index f9822a0..d42ffdf 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py
@@ -539,3 +539,41 @@
         GCPActions.remove_role(project_conf['edge_role_name'])
         GCPActions.remove_subnet(project_conf['private_subnet_name'], project_conf['region'])
         sys.exit(1)
+
+    if os.environ['edge_is_nat'] == 'true':
+        try:
+            logging.info('[CREATE NAT ROUTE]')
+            print('[REATE NAT ROUTE]')
+            nat_route_name = '{0}-{1}-{2}-nat-route'.format(project_conf['service_base_name'],
+                                                                  project_conf['project_name'],
+                                                                  project_conf['endpoint_name'])
+            edge_instance = GCPMeta.get_instance(project_conf['instance_name'])['selfLink']
+            params = "--nat_route_name {} --vpc {} --tag {} --edge_instance {}".format(nat_route_name,
+                                                                                                       project_conf['vpc_selflink'],
+                                                                                                       project_conf['ps_firewall_target'],
+                                                                                                       edge_instance)
+            try:
+                local("~/scripts/{}.py {}".format('common_create_nat_route', params))
+            except:
+                traceback.print_exc()
+                raise Exception
+        except Exception as err:
+            dlab.fab.append_result("Failed to create nat route.", str(err))
+            GCPActions.remove_instance(project_conf['instance_name'], project_conf['zone'])
+            GCPActions.remove_static_address(project_conf['static_address_name'], project_conf['region'])
+            GCPActions.remove_bucket(project_conf['bucket_name'])
+            GCPActions.remove_firewall(project_conf['fw_edge_ingress_public'])
+            GCPActions.remove_firewall(project_conf['fw_edge_ingress_internal'])
+            GCPActions.remove_firewall(project_conf['fw_edge_egress_public'])
+            GCPActions.remove_firewall(project_conf['fw_edge_egress_internal'])
+            GCPActions.remove_firewall(project_conf['fw_ps_ingress'])
+            GCPActions.remove_firewall(project_conf['fw_ps_egress_private'])
+            GCPActions.remove_firewall(project_conf['fw_ps_egress_public'])
+            GCPActions.remove_service_account(project_conf['ps_service_account_name'],
+                                              project_conf['service_base_name'])
+            GCPActions.remove_role(project_conf['ps_role_name'])
+            GCPActions.remove_service_account(project_conf['edge_service_account_name'],
+                                              project_conf['service_base_name'])
+            GCPActions.remove_role(project_conf['edge_role_name'])
+            GCPActions.remove_subnet(project_conf['private_subnet_name'], project_conf['region'])
+            sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py b/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py
index ef8f4f8..f3dd262 100644
--- a/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py
+++ b/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py
@@ -56,7 +56,7 @@
     try:
         sudo('systemctl stop jupyter-notebook')
         sudo('pip2 uninstall -y notebook jupyter')
-        sudo('pip3.5 uninstall -y notebook jupyter')
+        sudo('pip3 uninstall -y notebook jupyter')
         sudo('rm -rf /usr/local/share/jupyter/')
         sudo('rm -rf /home/{}/.jupyter/'.format(args.os_user))
         sudo('rm -rf /home/{}/.ipython/'.format(args.os_user))
diff --git a/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py b/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py
index 41454d2..53cba79 100644
--- a/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py
+++ b/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py
@@ -106,8 +106,8 @@
     env['connection_attempts'] = 100
     env.key_filename = [args.keyfile]
     env.host_string = args.os_user + '@' + args.edge_hostname
-    put('/tmp/{}.conf'.format(conf_file_name), '/etc/nginx/locations', use_sudo=True)
-    sudo('service nginx reload')
+    put('/tmp/{}.conf'.format(conf_file_name), '/usr/local/openresty/nginx/conf/locations', use_sudo=True)
+    sudo('service openresty reload')
 
 
 
diff --git a/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py
index cc65bc5..924489d 100644
--- a/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py
@@ -88,9 +88,9 @@
     text = text.replace('SPARK_VERSION', 'Spark-' + spark_version)
     text = text.replace('SPARK_PATH', spark_path)
     text = text.replace('MASTER', args.spark_master)
-    text = text.replace('PYTHON_SHORT_VERSION', '3.5')
-    text = text.replace('PYTHON_FULL_VERSION', '3.5')
-    text = text.replace('PYTHON_PATH', '/usr/bin/python3.5')
+    text = text.replace('PYTHON_SHORT_VERSION', '3.6')
+    text = text.replace('PYTHON_FULL_VERSION', '3.6')
+    text = text.replace('PYTHON_PATH', '/usr/bin/python3.6')
     with open(kernel_path, 'w') as f:
         f.write(text)
     local('touch /tmp/{}/kernel_var.json'.format(args.cluster_name))
diff --git a/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py b/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py
index 48d22a1..3d2b4b6 100644
--- a/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py
@@ -84,7 +84,7 @@
 
     if os.environ['application'] in ('jupyter', 'jupyterlab', 'zeppelin', 'deeplearning', 'tensor', 'tensor-rstudio', 'rstudio'):
         all_pkgs['pip2'] = get_available_pip_pkgs("2.7")
-        all_pkgs['pip3'] = get_available_pip_pkgs("3.5")
+        all_pkgs['pip3'] = get_available_pip_pkgs("3.6")
         all_pkgs['others'] = get_uncategorised_pip_pkgs(all_pkgs['pip2'], all_pkgs['pip3'])
 
     if (os.environ['application'] in ('jupyter', 'jupyterlab', 'zeppelin')
diff --git a/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py b/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py
index d2ce331..c57b2c9 100644
--- a/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py
@@ -97,12 +97,16 @@
     try:
         print('Installing other packages: {}'.format(pkgs['libraries']['others']))
         for pkg in pkgs['libraries']['others']:
-            status_pip2 = install_pip_pkg([pkg], 'pip2', 'others')
-            status_pip3 = install_pip_pkg([pkg], 'pip3', 'others')
-            if status_pip2[0]['status'] == 'installed':
-                general_status = general_status + status_pip2
-            else:
+            if os.environ['conf_resource'] in ('dataengine-service'):#, 'dataengine'):
+                status_pip3 = install_pip_pkg([pkg], 'pip3', 'others')
                 general_status = general_status + status_pip3
+            else:
+                status_pip2 = install_pip_pkg([pkg], 'pip2', 'others')
+                status_pip3 = install_pip_pkg([pkg], 'pip3', 'others')
+                if status_pip2[0]['status'] == 'installed':
+                    general_status = general_status + status_pip2
+                else:
+                    general_status = general_status + status_pip3
     except KeyError:
         pass
 
@@ -111,6 +115,13 @@
             or os.environ['application'] in ('rstudio', 'tensor-rstudio'):
         try:
             print('Installing R packages: {}'.format(pkgs['libraries']['r_pkg']))
+            if os.environ['conf_resource'] in ('dataengine-service') :
+                if os.environ['conf_cloud_provider'] in ('aws'):
+                    manage_pkg('-y install', 'remote', 'libcurl libcurl-devel')
+                elif os.environ['conf_cloud_provider'] in ('gcp'):
+                    manage_pkg('-y build-dep', 'remote', 'libcurl4-gnutls-dev libxml2-dev')
+                    manage_pkg('-y install', 'remote', 'libcurl4-gnutls-dev libxml2-dev')
+                sudo('R -e "install.packages(\'devtools\', repos = \'https://cloud.r-project.org\')"')
             status = install_r_pkg(pkgs['libraries']['r_pkg'])
             general_status = general_status + status
         except KeyError:
diff --git a/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py
index 60a3246..cf0639c 100644
--- a/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py
@@ -82,8 +82,8 @@
     scala_version = local('spark-submit --version 2>&1 | grep -o -P "Scala version \K.{0,7}"', capture=True)
     local('mkdir -p ' + kernels_dir + 'toree_' + args.cluster_name + '/')
     local('tar zxvf /tmp/{}/toree_kernel.tar.gz -C '.format(args.cluster_name) + kernels_dir + 'toree_' + args.cluster_name + '/')
-    local('sudo mv {0}toree_{1}/toree-0.2.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
-    local('sudo rm -r {0}toree_{1}/toree-0.2.0-incubating'.format(kernels_dir, args.cluster_name))
+    local('sudo mv {0}toree_{1}/toree-0.3.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
+    local('sudo rm -r {0}toree_{1}/toree-0.3.0-incubating'.format(kernels_dir, args.cluster_name))
     kernel_path = kernels_dir + "toree_" + args.cluster_name + "/kernel.json"
     template_file = "/tmp/{}/toree_dataengine_template.json".format(args.cluster_name)
     with open(template_file, 'r') as f:
@@ -143,9 +143,9 @@
     text = text.replace('SPARK_VERSION', 'Spark-' + spark_version)
     text = text.replace('SPARK_PATH', spark_path)
     text = text.replace('MASTER', args.spark_master)
-    text = text.replace('PYTHON_SHORT_VERSION', '3.5')
-    text = text.replace('PYTHON_FULL_VERSION', '3.5')
-    text = text.replace('PYTHON_PATH', '/usr/bin/python3.5')
+    text = text.replace('PYTHON_SHORT_VERSION', '3.6')
+    text = text.replace('PYTHON_FULL_VERSION', '3.6')
+    text = text.replace('PYTHON_PATH', '/usr/bin/python3.6')
     with open(kernel_path, 'w') as f:
         f.write(text)
     local('touch /tmp/{}/kernel_var.json'.format(args.cluster_name))
@@ -154,17 +154,54 @@
         format(args.cluster_name, kernel_path, args.os_user))
     local('sudo mv /tmp/{}/kernel_var.json '.format(args.cluster_name) + kernel_path)
 
+def install_sparkamagic_kernels(args):
+    try:
+        local('sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension')
+        sparkmagic_dir = local("sudo pip3 show sparkmagic | grep 'Location: ' | awk '{print $2}'", capture=True)
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkkernel --user'.format(sparkmagic_dir))
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/pysparkkernel --user'.format(sparkmagic_dir))
+        local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkrkernel --user'.format(sparkmagic_dir))
+        pyspark_kernel_name = 'PySpark (Python-3.6 / Spark-{0} ) [{1}]'.format(args.spark_version,
+                                                                         args.cluster_name)
+        local('sed -i \'s|PySpark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/pysparkkernel/kernel.json'.format(
+            pyspark_kernel_name, args.os_user))
+        scala_version = local('spark-submit --version 2>&1 | grep -o -P "Scala version \K.{0,7}"', capture=True)
+        spark_kernel_name = 'Spark (Scala-{0} / Spark-{1} ) [{2}]'.format(scala_version, args.spark_version,
+                                                                         args.cluster_name)
+        local('sed -i \'s|Spark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkkernel/kernel.json'.format(
+            spark_kernel_name, args.os_user))
+        r_version = local("R --version | awk '/version / {print $3}'", capture=True)
+        sparkr_kernel_name = 'SparkR (R-{0} / Spark-{1} ) [{2}]'.format(str(r_version), args.spark_version,
+                                                                            args.cluster_name)
+        local('sed -i \'s|SparkR|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkrkernel/kernel.json'.format(
+            sparkr_kernel_name, args.os_user))
+        local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/pysparkkernel '
+              '/home/{0}/.local/share/jupyter/kernels/pysparkkernel_{1}'.format(args.os_user, args.cluster_name))
+        local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkkernel '
+              '/home/{0}/.local/share/jupyter/kernels/sparkkernel_{1}'.format(args.os_user, args.cluster_name))
+        local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkrkernel '
+              '/home/{0}/.local/share/jupyter/kernels/sparkrkernel_{1}'.format(args.os_user, args.cluster_name))
+        local('mkdir -p /home/' + args.os_user + '/.sparkmagic')
+        local('cp -f /tmp/sparkmagic_config_template.json /home/' + args.os_user + '/.sparkmagic/config.json')
+        spark_master_ip = args.spark_master.split('//')[1].split(':')[0]
+        local('sed -i \'s|LIVY_HOST|{0}|g\' /home/{1}/.sparkmagic/config.json'.format(
+                spark_master_ip, args.os_user))
+        local('sudo chown -R {0}:{0} /home/{0}/.sparkmagic/'.format(args.os_user))
+    except:
+        sys.exit(1)
+
 
 if __name__ == "__main__":
     if args.dry_run == 'true':
         parser.print_help()
     else:
-        dataengine_dir_prepare('/opt/{}/'.format(args.cluster_name))
-        install_dataengine_spark(args.cluster_name, spark_link, spark_version, hadoop_version, cluster_dir, args.os_user,
-                                 args.datalake_enabled)
-        configure_dataengine_spark(args.cluster_name, local_jars_dir, cluster_dir, args.datalake_enabled,
-                                   args.spark_configurations)
-        pyspark_kernel(args)
-        toree_kernel(args)
-        if args.r_enabled == 'true':
-            r_kernel(args)
+        install_sparkamagic_kernels(args)
+        #dataengine_dir_prepare('/opt/{}/'.format(args.cluster_name))
+        #install_dataengine_spark(args.cluster_name, spark_link, spark_version, hadoop_version, cluster_dir, args.os_user,
+        #                         args.datalake_enabled)
+        #configure_dataengine_spark(args.cluster_name, local_jars_dir, cluster_dir, args.datalake_enabled,
+        #                           args.spark_configurations)
+        #pyspark_kernel(args)
+        #toree_kernel(args)
+        #if args.r_enabled == 'true':
+        #    r_kernel(args)
diff --git a/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py b/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py
index 9b984af..01afe7b 100644
--- a/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py
+++ b/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py
@@ -46,12 +46,13 @@
     files_dir = '/root/files/'
     scripts_dir = '/root/scripts/'
     run('mkdir -p /tmp/{}/'.format(args.cluster_name))
-    put(templates_dir + 'pyspark_dataengine_template.json', '/tmp/{}/pyspark_dataengine_template.json'.format(args.cluster_name))
-    put(templates_dir + 'r_dataengine_template.json', '/tmp/{}/r_dataengine_template.json'.format(args.cluster_name))
-    put(templates_dir + 'toree_dataengine_template.json','/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
-    put(files_dir + 'toree_kernel.tar.gz', '/tmp/{}/toree_kernel.tar.gz'.format(args.cluster_name))
-    put(templates_dir + 'toree_dataengine_template.json', '/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
-    put(templates_dir + 'run_template.sh', '/tmp/{}/run_template.sh'.format(args.cluster_name))
+    put(templates_dir + 'sparkmagic_config_template.json', '/tmp/sparkmagic_config_template.json')
+    #put(templates_dir + 'pyspark_dataengine_template.json', '/tmp/{}/pyspark_dataengine_template.json'.format(args.cluster_name))
+    #put(templates_dir + 'r_dataengine_template.json', '/tmp/{}/r_dataengine_template.json'.format(args.cluster_name))
+    #put(templates_dir + 'toree_dataengine_template.json','/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
+    #put(files_dir + 'toree_kernel.tar.gz', '/tmp/{}/toree_kernel.tar.gz'.format(args.cluster_name))
+    #put(templates_dir + 'toree_dataengine_template.json', '/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
+    #put(templates_dir + 'run_template.sh', '/tmp/{}/run_template.sh'.format(args.cluster_name))
     put(templates_dir + 'notebook_spark-defaults_local.conf', '/tmp/{}/notebook_spark-defaults_local.conf'.format(args.cluster_name))
     spark_master_ip = args.spark_master.split('//')[1].split(':')[0]
     spark_memory = get_spark_memory(True, args.os_user, spark_master_ip, keyfile)
@@ -86,7 +87,7 @@
     create_inactivity_log(args.spark_master_ip, env.host_string)
     sudo('/usr/bin/python /usr/local/bin/jupyter_dataengine_create_configs.py '
          '--cluster_name {} --spark_version {} --hadoop_version {} --os_user {} \
-         --spark_master {} --region {} --datalake_enabled {} --r_enabled {} --spark_configurations "{}"'.
+         --spark_master {} --datalake_enabled {} --r_enabled {} --spark_configurations "{}"'.
          format(args.cluster_name, args.spark_version, args.hadoop_version, args.os_user, args.spark_master,
-                region, args.datalake_enabled, r_enabled, os.environ['spark_configurations']))
+                args.datalake_enabled, r_enabled, os.environ['spark_configurations']))
 
diff --git a/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py b/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py
index c4ff97b..77b00a4 100644
--- a/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py
+++ b/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py
@@ -38,7 +38,7 @@
 def start_jupyterlab_container(jupyterlab_dir):
     try:
         with cd('{}'.format(jupyterlab_dir)):
-            run('docker build --file Dockerfile_jupyterlab -t jupyter-lab .'.format(args.os_user))
+            run('docker build --network=host --file Dockerfile_jupyterlab -t jupyter-lab .'.format(args.os_user))
             container_id = run('docker ps | awk \'NR==2{print $1}\'')
             if container_id != '':
                 run('docker stop ' + container_id)
diff --git a/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py
index b26a713..2190879 100644
--- a/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py
@@ -88,9 +88,9 @@
     text = text.replace('SPARK_VERSION', 'Spark-' + spark_version)
     text = text.replace('SPARK_PATH', spark_path)
     text = text.replace('MASTER', args.spark_master)
-    text = text.replace('PYTHON_SHORT_VERSION', '3.5')
-    text = text.replace('PYTHON_FULL_VERSION', '3.5')
-    text = text.replace('PYTHON_PATH', '/usr/bin/python3.5')
+    text = text.replace('PYTHON_SHORT_VERSION', '3.6')
+    text = text.replace('PYTHON_FULL_VERSION', '3.6')
+    text = text.replace('PYTHON_PATH', '/usr/bin/python3.6')
     with open(kernel_path, 'w') as f:
         f.write(text)
     local('touch /tmp/{}/kernel_var.json'.format(args.cluster_name))
diff --git a/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py
index 7e7cfc2..78b591d 100644
--- a/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py
@@ -96,7 +96,7 @@
             if os.path.exists(livy_path + 'conf/spark-blacklist.conf'):
                 local('sudo sed -i "s/^/#/g" ' + livy_path + 'conf/spark-blacklist.conf')
             local(''' sudo echo "export SPARK_HOME=''' + cluster_dir + '''spark/" >> ''' + livy_path + '''conf/livy-env.sh''')
-            local(''' sudo echo "export PYSPARK3_PYTHON=python3.5" >> ''' +
+            local(''' sudo echo "export PYSPARK3_PYTHON=python3.6" >> ''' +
                   livy_path + '''conf/livy-env.sh''')
             template_file = "/tmp/{}/dataengine_interpreter.json".format(args.cluster_name)
             fr = open(template_file, 'r+')
@@ -127,7 +127,7 @@
             local('sudo systemctl start livy-server-' + str(livy_port))
         else:
             template_file = "/tmp/{}/dataengine_interpreter.json".format(args.cluster_name)
-            p_versions = ["2", "3.5"]
+            p_versions = ["2", "3.6"]
             for p_version in p_versions:
                 fr = open(template_file, 'r+')
                 text = fr.read()
diff --git a/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json b/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json
index 9f8367d..e6ec49b 100644
--- a/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json
+++ b/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json
@@ -14,7 +14,10 @@
             },
             "tags": [
                 "CLUSTER_TAG"
-            ]
+            ],
+            "metadata": {
+                "livy-version": "0.6.0"
+            }
         },
         "masterConfig": {
             "numInstances": "NUM_MASTERS",
@@ -38,6 +41,11 @@
         },
         "softwareConfig": {
             "imageVersion": "IMAGE_VERSION"
-        }
+        },
+        "initializationActions": [
+            {
+                "executableFile": "LIVY"
+            }
+        ]
     }
 }
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/debian/livy.service b/infrastructure-provisioning/src/general/templates/os/debian/livy.service
new file mode 100644
index 0000000..a37f1f8
--- /dev/null
+++ b/infrastructure-provisioning/src/general/templates/os/debian/livy.service
@@ -0,0 +1,35 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+[Unit]
+Description=Apache Livy service
+After=network.target
+
+[Service]
+Group=OS_USER
+User=OS_USER
+Type=forking
+ExecStart=/opt/livy/bin/livy-server start
+ExecStop=/opt/livy/bin/livy-server stop
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/livy-env.sh b/infrastructure-provisioning/src/general/templates/os/livy-env.sh
new file mode 100644
index 0000000..e9a5738
--- /dev/null
+++ b/infrastructure-provisioning/src/general/templates/os/livy-env.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# LIVY ENVIRONMENT VARIABLES
+#
+export SPARK_HOME=/opt/spark
+export SPARK_CONF_DIR=/opt/spark/conf
+export LIVY_LOG_DIR=/var/log/livy
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json b/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json
index 969228e..e03c629 100644
--- a/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json
+++ b/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json
@@ -1,15 +1,15 @@
 {
  "argv": [
-  "/usr/bin/python3.5",
+  "/usr/bin/python3",
   "-m",
   "ipykernel",
   "-f",
   "{connection_file}"
  ],
  "language": "python",
- "display_name": "Local PySpark (Python-3.5 / Spark-SP_VER )",
+ "display_name": "Local PySpark (Python-3.6 / Spark-SP_VER )",
  "env": {
-  "PYSPARK_PYTHON": "python3.5",
+  "PYSPARK_PYTHON": "python3.6",
   "SPARK_HOME": "/opt/spark/",
   "PYTHONPATH": "PY4J:/opt/spark/python/:",
   "PYTHONSTARTUP": "/opt/spark/python/pyspark/shell.py",
diff --git a/infrastructure-provisioning/src/general/templates/os/sparkmagic_config_template.json b/infrastructure-provisioning/src/general/templates/os/sparkmagic_config_template.json
new file mode 100644
index 0000000..e6fa8ef
--- /dev/null
+++ b/infrastructure-provisioning/src/general/templates/os/sparkmagic_config_template.json
@@ -0,0 +1,20 @@
+{
+  "kernel_python_credentials" : {
+    "username": "",
+    "password": "",
+    "url": "http://LIVY_HOST:8998",
+    "auth": "None"
+  },
+  "kernel_scala_credentials" : {
+    "username": "",
+    "password": "",
+    "url": "http://LIVY_HOST:8998",
+    "auth": "None"
+  },
+  "kernel_r_credentials": {
+    "username": "",
+    "password": "",
+    "url": "http://LIVY_HOST:8998",
+    "auth": "None"
+  }
+}
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/tensorboard.service b/infrastructure-provisioning/src/general/templates/os/tensorboard.service
index a4a1d68..f7dee8b 100644
--- a/infrastructure-provisioning/src/general/templates/os/tensorboard.service
+++ b/infrastructure-provisioning/src/general/templates/os/tensorboard.service
@@ -25,7 +25,7 @@
 [Service]
 Type=simple
 PIDFile=/var/run/tensorboard.pid
-ExecStart=/bin/bash -c "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64; tensorboard --logdir=/var/log/tensorboard --port 6006"
+ExecStart=/bin/bash -c "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64; tensorboard --logdir=/var/log/tensorboard --host 0.0.0.0 --port 6006"
 ExecStop=/bin/bash -c "for i in $(ps aux | grep 'tensorboard' | grep -v grep | awk '{print $2}'); do kill -9 $i; done"
 User=OS_USR
 Group=OS_USR
diff --git a/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py b/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py
index 94ad123..11b42cd 100644
--- a/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py
+++ b/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py
@@ -63,7 +63,7 @@
 templates_dir = '/root/templates/'
 files_dir = '/root/files/'
 local_spark_path = '/opt/spark/'
-toree_link = 'http://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree-pip/toree-0.2.0.tar.gz'
+toree_link = 'http://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree-pip/toree-0.3.0.tar.gz'
 r_libs = ['R6', 'pbdZMQ', 'RCurl', 'devtools', 'reshape2', 'caTools', 'rJava', 'ggplot2']
 gitlab_certfile = os.environ['conf_gitlab_certfile']
 
diff --git a/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py b/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py
index 1486ff3..f50de32 100644
--- a/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py
+++ b/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py
@@ -71,7 +71,7 @@
 templates_dir = '/root/templates/'
 files_dir = '/root/files/'
 local_spark_path = '/opt/spark/'
-toree_link = 'http://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree-pip/toree-0.2.0.tar.gz'
+toree_link = 'http://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree-pip/toree-0.3.0.tar.gz'
 r_libs = ['R6', 'pbdZMQ', 'RCurl', 'devtools', 'reshape2', 'caTools', 'rJava', 'ggplot2']
 gitlab_certfile = os.environ['conf_gitlab_certfile']
 
diff --git a/infrastructure-provisioning/src/project/scripts/configure_nftables.py b/infrastructure-provisioning/src/project/scripts/configure_nftables.py
new file mode 100644
index 0000000..de4dc12
--- /dev/null
+++ b/infrastructure-provisioning/src/project/scripts/configure_nftables.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+from fabric.api import *
+from fabric.contrib.files import exists
+from dlab.edge_lib import configure_nftables
+import argparse
+import json
+import sys
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--hostname', type=str, default='')
+parser.add_argument('--keyfile', type=str, default='')
+parser.add_argument('--user', type=str, default='')
+parser.add_argument('--additional_config', type=str, default='{"empty":"string"}')
+args = parser.parse_args()
+
+##############
+# Run script #
+##############
+if __name__ == "__main__":
+    print("Configure connections")
+    try:
+        env['connection_attempts'] = 100
+        env.key_filename = [args.keyfile]
+        env.host_string = '{}@{}'.format(args.user, args.hostname)
+        deeper_config = json.loads(args.additional_config)
+    except:
+        sys.exit(2)
+
+    print("Configuring nftables on edge node.")
+    configure_nftables(deeper_config)
diff --git a/infrastructure-provisioning/src/project/templates/nftables.conf b/infrastructure-provisioning/src/project/templates/nftables.conf
new file mode 100644
index 0000000..f5d4404
--- /dev/null
+++ b/infrastructure-provisioning/src/project/templates/nftables.conf
@@ -0,0 +1,22 @@
+#!/usr/sbin/nft -f
+
+flush ruleset
+
+table inet filter {
+        chain input {
+                type filter hook input priority 0;
+        }
+        chain forward {
+                type filter hook forward priority 0;
+        }
+        chain output {
+                type filter hook output priority 0;
+        }
+}
+
+table ip nat {
+        chain postrouting {
+                type nat hook postrouting priority 100; policy accept;
+                ip saddr SUBNET_CIDR oif "INTERFACE" snat to EDGE_IP
+        }
+}
diff --git a/infrastructure-provisioning/src/project/templates/nginx.conf b/infrastructure-provisioning/src/project/templates/nginx.conf
index d012375..698e25d 100644
--- a/infrastructure-provisioning/src/project/templates/nginx.conf
+++ b/infrastructure-provisioning/src/project/templates/nginx.conf
@@ -19,25 +19,29 @@
 #
 # ******************************************************************************
 user nginx;
-worker_processes 1;
-error_log /var/log/nginx/error.log;
-pid /run/nginx.pid;
+worker_processes  1;
 
-load_module /etc/nginx/modules/ndk_http_module.so;
-load_module /etc/nginx/modules/ngx_http_lua_module.so;
+error_log  logs/error.log;
+error_log  logs/error.log  notice;
+error_log  logs/error.log  info;
 
-include /usr/share/nginx/modules/*.conf;
+pid        logs/nginx.pid;
+
 
 events {
-    worker_connections 1024;
+    worker_connections  1024;
 }
 
+
 http {
+    include       mime.types;
+    default_type  application/octet-stream;
+
     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                       '$status $body_bytes_sent "$http_referer" '
                       '"$http_user_agent" "$http_x_forwarded_for"';
 
-    access_log  /var/log/nginx/access.log  main;
+    access_log  logs/access.log  main;
 
     sendfile            on;
     tcp_nopush          on;
@@ -50,11 +54,6 @@
     resolver 8.8.8.8;
     resolver_timeout 10s;
 
-    include             /etc/nginx/mime.types;
-    default_type        application/octet-stream;
-
-    lua_shared_dict discovery 1m;
-    lua_shared_dict jwks 1m;
-
-    include /etc/nginx/conf.d/*.conf;
+    include /usr/local/openresty/nginx/conf/conf.d/*.conf;
 }
+
diff --git a/infrastructure-provisioning/src/ssn/scripts/configure_docker.py b/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
index 727f97e..f0dd69a 100644
--- a/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
+++ b/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
@@ -58,13 +58,13 @@
 
 def download_toree():
     toree_path = '/opt/dlab/sources/infrastructure-provisioning/src/general/files/os/'
-    tarball_link = 'https://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree/toree-0.2.0-incubating-bin.tar.gz'
-    jar_link = 'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.2.0-incubating/toree-assembly-0.2.0-incubating.jar'
+    tarball_link = 'https://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree/toree-0.3.0-incubating-bin.tar.gz'
+    jar_link = 'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.3.0-incubating/toree-assembly-0.3.0-incubating.jar'
     try:
         run('wget {}'.format(tarball_link))
         run('wget {}'.format(jar_link))
-        run('mv toree-0.2.0-incubating-bin.tar.gz {}toree_kernel.tar.gz'.format(toree_path))
-        run('mv toree-assembly-0.2.0-incubating.jar {}toree-assembly-0.2.0.jar'.format(toree_path))
+        run('mv toree-0.3.0-incubating-bin.tar.gz {}toree_kernel.tar.gz'.format(toree_path))
+        run('mv toree-assembly-0.3.0-incubating.jar {}toree-assembly-0.3.0.jar'.format(toree_path))
     except Exception as err:
         traceback.print_exc()
         print('Failed to download toree: ', str(err))
diff --git a/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py b/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py
index 9993a70..53614d2 100644
--- a/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py
+++ b/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py
@@ -50,6 +50,13 @@
         print('Failed to set hostname: ', str(err))
         sys.exit(1)
 
+def set_resolve():
+    try:
+        sudo('ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf')
+    except Exception as err:
+        traceback.print_exc()
+        print('Failed to set resolve: ', str(err))
+        sys.exit(1)
 
 def cp_key(keyfile, host_string, os_user):
     try:
@@ -222,6 +229,9 @@
     else:
         custom_ssl_cert = False
 
+    print('Setting resolve DNS configuration')
+    set_resolve()
+
     print("Creating service directories.")
     creating_service_directories(args.dlab_path, args.os_user)
 
diff --git a/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py b/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py
index fda8b1f..1afef2b 100644
--- a/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py
+++ b/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py
@@ -85,6 +85,8 @@
             sudo('tar -zxvf /tmp/zeppelin-' + zeppelin_version + '-bin-netinst.tgz -C /opt/')
             sudo('ln -s /opt/zeppelin-' + zeppelin_version + '-bin-netinst /opt/zeppelin')
             sudo('cp /opt/zeppelin/conf/zeppelin-env.sh.template /opt/zeppelin/conf/zeppelin-env.sh')
+            java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+            sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/zeppelin/conf/zeppelin-env.sh".format(java_home))
             sudo('cp /opt/zeppelin/conf/zeppelin-site.xml.template /opt/zeppelin/conf/zeppelin-site.xml')
             sudo('sed -i \"/# export ZEPPELIN_PID_DIR/c\export ZEPPELIN_PID_DIR=/var/run/zeppelin\" /opt/zeppelin/conf/zeppelin-env.sh')
             sudo('sed -i \"/# export ZEPPELIN_IDENT_STRING/c\export ZEPPELIN_IDENT_STRING=notebook\" /opt/zeppelin/conf/zeppelin-env.sh')
@@ -106,6 +108,12 @@
         try:
             put(templates_dir + 'zeppelin-notebook.service', '/tmp/zeppelin-notebook.service')
             sudo("sed -i 's|OS_USR|" + os_user + "|' /tmp/zeppelin-notebook.service")
+            http_proxy = run('echo $http_proxy')
+            https_proxy = run('echo $https_proxy')
+            sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTP_PROXY={}\"\'  /tmp/zeppelin-notebook.service'.format(
+                http_proxy))
+            sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTPS_PROXY={}\"\'  /tmp/zeppelin-notebook.service'.format(
+                https_proxy))
             sudo("chmod 644 /tmp/zeppelin-notebook.service")
             sudo('cp /tmp/zeppelin-notebook.service /etc/systemd/system/zeppelin-notebook.service')
             sudo('chown ' + os_user + ':' + os_user + ' -R /opt/zeppelin/')
diff --git a/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf b/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf
index 1fb08e5..ccb9781 100644
--- a/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf
+++ b/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf
@@ -1,12 +1,33 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 provider "aws" {
   access_key = var.access_key_id
   secret_key = var.secret_access_key
-  region     = var.region
+  region = var.region
 }
 
 module "common" {
-  source        = "../modules/common"
-  sbn           = var.service_base_name
+  source = "../modules/common"
+  sbn = var.service_base_name
   project_name  = var.project_name
   project_tag   = var.project_tag
   endpoint_tag  = var.endpoint_tag
diff --git a/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf b/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf
index 13f0d25..a2587e3 100644
--- a/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf
+++ b/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 variable "access_key_id" {}
 
 variable "secret_access_key" {}
diff --git a/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf b/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf
index 8a930e0..86f70f0 100644
--- a/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf
+++ b/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf
@@ -1,33 +1,33 @@
 # *****************************************************************************
- #
- # Licensed to the Apache Software Foundation (ASF) under one
- # or more contributor license agreements.  See the NOTICE file
- # distributed with this work for additional information
- # regarding copyright ownership.  The ASF licenses this file
- # to you under the Apache License, Version 2.0 (the
- # "License"); you may not use this file except in compliance
- # with the License.  You may obtain a copy of the License at
- #
- #   http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing,
- # software distributed under the License is distributed on an
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- # KIND, either express or implied.  See the License for the
- # specific language governing permissions and limitations
- # under the License.
- #
- # ******************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
 
- locals {
-   shared_s3_name = "${var.service_base_name}-${var.endpoint_id}-shared-bucket"
- }
+locals {
+  shared_s3_name = "${var.service_base_name}-${var.endpoint_id}-shared-bucket"
+}
 
- resource "aws_s3_bucket" "shared_bucket" {
-   bucket = local.shared_s3_name
-   acl    = "private"
-   tags   = {
-     Name                           = local.shared_s3_name
+resource "aws_s3_bucket" "shared_bucket" {
+  bucket = local.shared_s3_name
+  acl = "private"
+  tags = {
+    Name = local.shared_s3_name
      "${local.additional_tag[0]}"   = local.additional_tag[1]
      "${var.tag_resource_id}"       = "${var.service_base_name}:${local.shared_s3_name}"
      "${var.service_base_name}-tag" = local.shared_s3_name
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore
index fbe01f8..e25078a 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # Patterns to ignore when building packages.
 # This supports shell glob matching, relative path matching, and
 # negation (prefixed with !). Only one pattern per line.
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml
index 4b334aa..d133831 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: v1
 appVersion: 0.13.2
 description: An online certificate authority and related tools for secure automated
@@ -6,7 +27,7 @@
 home: https://smallstep.com
 icon: https://raw.githubusercontent.com/smallstep/certificates/master/icon.png
 keywords:
-- acme
+  - acme
 - authority
 - ca
 - certificate
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl
index e240bac..b65f748 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
 {{/* vim: set filetype=mustache: */}}
 {{/*
 Expand the name of the chart.
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml
index 4fa3240..3e67b22 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml
@@ -1,11 +1,32 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
+  {{- if .Release.IsInstall -}}
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: {{ include "step-certificates.fullname" . }}-config
   namespace: {{.Release.Namespace}}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
 ---
 apiVersion: batch/v1
 kind: Job
@@ -24,16 +45,16 @@
       serviceAccountName: {{ include "step-certificates.fullname" . }}-config
       restartPolicy: Never
       volumes:
-      - name: bootstrap
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-bootstrap
+        - name: bootstrap
+          configMap:
+            name: {{ include "step-certificates.fullname" . }}-bootstrap
       containers:
-      - name: config
-        image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
-        imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
-        command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
-        volumeMounts:
-          - name: bootstrap
-            mountPath: /home/step/bootstrap
-            readOnly: true
+        - name: config
+          image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
+          imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
+          command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
+          volumeMounts:
+            - name: bootstrap
+              mountPath: /home/step/bootstrap
+              readOnly: true
 {{- end -}}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml
index 7c5929c..dde19cc 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml
@@ -1,9 +1,30 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: apps/v1
 kind: StatefulSet
 metadata:
   name: {{ include "step-certificates.fullname" . }}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
 spec:
   # Only one replica is supported at this moment
   # Requested {{ .Values.replicaCount }}
@@ -20,99 +41,99 @@
         app.kubernetes.io/instance: {{ .Release.Name }}
     spec:
 {{- if .Release.IsInstall }}
-      initContainers:
-        - name: {{ .Chart.Name }}-init
-          image: busybox:latest
-          imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command: ["sleep", "20"]
+initContainers:
+  - name: {{ .Chart.Name }}-init
+    image: busybox:latest
+    imagePullPolicy: {{ .Values.image.pullPolicy }}
+    command: ["sleep", "20"]
 {{- end }}
-      securityContext:
-        {{- if .Values.ca.runAsRoot }}
-        runAsUser: 0
-        {{- else }}
-        runAsUser: 1000
-        runAsNonRoot: true
-        runAsGroup: 1000
-        fsGroup: 1000
-        allowPrivilegeEscalation: false
-        {{- end }}
-      containers:
-        - name: {{ .Chart.Name }}
-          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
-          imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command: ["/usr/local/bin/step-ca",
-            "--password-file", "/home/step/secrets/passwords/password",
-            "/home/step/config/ca.json"]
-          env:
-          - name: NAMESPACE
-            value: "{{ .Release.Namespace }}"
-          ports:
-            - name: https
-              containerPort: {{ .Values.service.targetPort }}
-              protocol: TCP
-          livenessProbe:
-            initialDelaySeconds: 5
-            httpGet:
-              path: /health
-              port: {{ .Values.service.targetPort }}
-              scheme: HTTPS
-          readinessProbe:
-            initialDelaySeconds: 5
-            httpGet:
-              path: /health
-              port: {{ .Values.service.targetPort }}
-              scheme: HTTPS
-          resources:
-            {{- toYaml .Values.resources | nindent 12 }}
-          volumeMounts:
-          - name: certs
-            mountPath: /home/step/certs
-            readOnly: true
-          - name: config
-            mountPath: /home/step/config
-            readOnly: true
-          - name: secrets
-            mountPath: /home/step/secrets
-            readOnly: true
-          - name: ca-password
-            mountPath: /home/step/secrets/passwords
-            readOnly: true
-          {{- if .Values.ca.db.enabled }}
-          - name: database
-            mountPath: /home/step/db
-            readOnly: false
-          {{- end }}
-      volumes:
+securityContext:
+  {{- if .Values.ca.runAsRoot }}
+  runAsUser: 0
+  {{- else }}
+  runAsUser: 1000
+  runAsNonRoot: true
+  runAsGroup: 1000
+  fsGroup: 1000
+  allowPrivilegeEscalation: false
+  {{- end }}
+containers:
+  - name: {{ .Chart.Name }}
+    image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+    imagePullPolicy: {{ .Values.image.pullPolicy }}
+    command: ["/usr/local/bin/step-ca",
+              "--password-file", "/home/step/secrets/passwords/password",
+              "/home/step/config/ca.json"]
+    env:
+      - name: NAMESPACE
+        value: "{{ .Release.Namespace }}"
+    ports:
+      - name: https
+        containerPort: {{ .Values.service.targetPort }}
+        protocol: TCP
+    livenessProbe:
+      initialDelaySeconds: 5
+      httpGet:
+        path: /health
+        port: {{ .Values.service.targetPort }}
+        scheme: HTTPS
+    readinessProbe:
+      initialDelaySeconds: 5
+      httpGet:
+        path: /health
+        port: {{ .Values.service.targetPort }}
+        scheme: HTTPS
+    resources:
+      {{- toYaml .Values.resources | nindent 12 }}
+    volumeMounts:
       - name: certs
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-certs
+        mountPath: /home/step/certs
+        readOnly: true
       - name: config
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-config
+        mountPath: /home/step/config
+        readOnly: true
       - name: secrets
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-secrets
+        mountPath: /home/step/secrets
+        readOnly: true
       - name: ca-password
-        secret:
-          secretName: {{ include "step-certificates.fullname" . }}-ca-password
-      {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
-      - name: database
-        emptyDir: {}
-      {{- end }}
-      {{- with .Values.nodeSelector }}
-      nodeSelector:
-      {{- toYaml . | nindent 8 }}
-      {{- end }}
-      {{- with .Values.affinity }}
-      affinity:
-      {{- toYaml . | nindent 8 }}
-      {{- end }}
-      {{- with .Values.tolerations }}
-      tolerations:
-      {{- toYaml . | nindent 8 }}
-      {{- end }}
+        mountPath: /home/step/secrets/passwords
+        readOnly: true
+    {{- if .Values.ca.db.enabled }}
+    - name: database
+      mountPath: /home/step/db
+      readOnly: false
+    {{- end }}
+volumes:
+  - name: certs
+    configMap:
+      name: {{ include "step-certificates.fullname" . }}-certs
+  - name: config
+configMap:
+  name: {{ include "step-certificates.fullname" . }}-config
+  - name: secrets
+configMap:
+  name: {{ include "step-certificates.fullname" . }}-secrets
+  - name: ca-password
+secret:
+  secretName: {{ include "step-certificates.fullname" . }}-ca-password
+  {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
+  - name: database
+emptyDir: {}
+  {{- end }}
+  {{- with .Values.nodeSelector }}
+nodeSelector:
+  {{- toYaml . | nindent 8 }}
+  {{- end }}
+  {{- with .Values.affinity }}
+affinity:
+  {{- toYaml . | nindent 8 }}
+  {{- end }}
+  {{- with .Values.tolerations }}
+tolerations:
+  {{- toYaml . | nindent 8 }}
+  {{- end }}
 {{- if and .Values.ca.db.enabled .Values.ca.db.persistent }}
-  volumeClaimTemplates:
+volumeClaimTemplates:
   - metadata:
       name: database
       labels:
@@ -122,16 +143,16 @@
     spec:
       accessModes:
       {{- range .Values.ca.db.accessModes }}
-        - {{ . | quote }}
+      - {{ . | quote }}
       {{- end }}
       resources:
         requests:
           storage: {{ .Values.ca.db.size | quote }}
     {{- if .Values.ca.db.storageClass }}
     {{- if (eq "-" .Values.ca.db.storageClass) }}
-      storageClassName: ""
+    storageClassName: ""
     {{- else }}
-      storageClassName: {{ .Values.ca.db.storageClass | quote }}
+    storageClassName: {{ .Values.ca.db.storageClass | quote }}
     {{- end }}
     {{- end }}
 {{- end }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml
index 28ad488..dc15383 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # ConfigMaps that will be updated by the configuration job:
 # 1. Step CA config directory.
 # 2. Step CA certs direcotry.
@@ -71,76 +92,76 @@
       permission_error "create secrets"
     fi
 {{ if .Values.autocert.enabled }}
-    echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
+echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
     kubectl auth can-i create mutatingwebhookconfiguration --namespace {{.Release.Namespace}}
     if [ $? -ne 0 ]; then
       permission_error "create mutatingwebhookconfiguration"
-    fi
+  fi
 {{- end }}
 
-    # Setting this here on purpose, after the above section which explicitly checks
-    # for and handles exit errors.
-    set -e
+# Setting this here on purpose, after the above section which explicitly checks
+# for and handles exit errors.
+  set -e
 
-    echo -e "\n\e[1mInitializating the CA...\e[0m"
+  echo -e "\n\e[1mInitializating the CA...\e[0m"
 
-    # CA password
+# CA password
 {{- if .Values.ca.password }}
-    CA_PASSWORD={{ quote .Values.ca.password }}
+  CA_PASSWORD={{ quote .Values.ca.password }}
 {{- else }}
-    CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+  CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
 {{- end }}
-    # Provisioner password
+# Provisioner password
 {{- if .Values.ca.provisioner.password }}
-    CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
+  CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
 {{- else }}
-    CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+  CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
 {{- end }}
 
-    TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
-    TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+  TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+  TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
 
-    echo $CA_PASSWORD > $TMP_CA_PASSWORD
-    echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
+  echo $CA_PASSWORD > $TMP_CA_PASSWORD
+  echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
 
-    step ca init \
-      --name "{{.Values.ca.name}}" \
-      --dns "{{include "step-certificates.dns" .}}" \
-      --address "{{.Values.ca.address}}" \
-      --provisioner "{{.Values.ca.provisioner.name}}" \
-      --with-ca-url "{{include "step-certificates.url" .}}" \
-      --password-file "$TMP_CA_PASSWORD" \
-      --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
+  step ca init \
+  --name "{{.Values.ca.name}}" \
+  --dns "{{include "step-certificates.dns" .}}" \
+  --address "{{.Values.ca.address}}" \
+  --provisioner "{{.Values.ca.provisioner.name}}" \
+  --with-ca-url "{{include "step-certificates.url" .}}" \
+  --password-file "$TMP_CA_PASSWORD" \
+  --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
 
-    rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
+  rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
 
-    echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
+  echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
 
-    # Replace secrets created on helm install
-    # It allows to properly remove them on helm delete
-    kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
-    kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
-    kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
+  # Replace secrets created on helm install
+  # It allows to properly remove them on helm delete
+  kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
+  kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
+  kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
 
-    kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
-    kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
+  kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
+  kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
 
-    # Label all configmaps and secrets
-    kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+# Label all configmaps and secrets
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
 
-    # Patch webhook if autocert is enabled
+# Patch webhook if autocert is enabled
 {{ if .Values.autocert.enabled }}
-    CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
-    kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
-      --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
+  CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
+  kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
+  --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
 {{- end }}
 
-    echo -e "\n\e[1mStep Certificates installed!\e[0m"
-    echo
-    echo "CA URL: {{include "step-certificates.url" .}}"
-    echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
-    echo
\ No newline at end of file
+  echo -e "\n\e[1mStep Certificates installed!\e[0m"
+  echo
+echo "CA URL: {{include "step-certificates.url" .}}"
+echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
+  echo
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml
index 53264f1..3404ae7 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml
@@ -1,36 +1,57 @@
-{{- if .Values.ingress.enabled -}}
-{{- $fullName := include "step-certificates.fullname" . -}}
+# *****************************************************************************
+#
+  #  Licensed to the Apache Software Foundation (ASF) under one
+  #  or more contributor license agreements.  See the NOTICE file
+  #  distributed with this work for additional information
+  #  regarding copyright ownership.  The ASF licenses this file
+  #  to you under the Apache License, Version 2.0 (the
+  #  "License"); you may not use this file except in compliance
+  #  with the License.  You may obtain a copy of the License at
+  #
+  #  http://www.apache.org/licenses/LICENSE-2.0
+  #
+  #  Unless required by applicable law or agreed to in writing,
+  #  software distributed under the License is distributed on an
+  #  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  #  KIND, either express or implied.  See the License for the
+  #  specific language governing permissions and limitations
+  #  under the License.
+  #
+  # ******************************************************************************
+
+  {{- if .Values.ingress.enabled -}}
+  {{- $fullName := include "step-certificates.fullname" . -}}
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
   name: {{ $fullName }}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
   {{- with .Values.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
+annotations:
+  {{- toYaml . | nindent 4 }}
   {{- end }}
 spec:
 {{- if .Values.ingress.tls }}
-  tls:
+tls:
   {{- range .Values.ingress.tls }}
-    - hosts:
-      {{- range .hosts }}
-        - {{ . | quote }}
-      {{- end }}
-      secretName: {{ .secretName }}
+- hosts:
+  {{- range .hosts }}
+  - {{ . | quote }}
+  {{- end }}
+  secretName: {{ .secretName }}
   {{- end }}
 {{- end }}
-  rules:
+rules:
   {{- range .Values.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-        {{- range .paths }}
-          - path: {{ . }}
-            backend:
-              serviceName: {{ $fullName }}
-              servicePort: http
-        {{- end }}
+- host: {{ .host | quote }}
+  http:
+    paths:
+    {{- range .paths }}
+    - path: {{ . }}
+      backend:
+        serviceName: {{ $fullName }}
+        servicePort: http
+    {{- end }}
   {{- end }}
 {{- end }}
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml
index 6f4e137..ebab8c4 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml
@@ -1,4 +1,25 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
+  {{- if .Release.IsInstall -}}
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml
index 567a989..64f8b9b 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # Secrets that will be updated by the configuration job:
 # 1. CA keys password.
 # 2. Provisioner password.
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml
index 4ec0783..fb17ab1 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml
@@ -1,19 +1,40 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: v1
 kind: Service
 metadata:
   name: {{ include "step-certificates.fullname" . }}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
 spec:
   type: {{ .Values.service.type }}
   ports:
     - port: {{ .Values.service.port }}
       targetPort: {{ .Values.service.targetPort }}
 {{- if .Values.service.nodePort }}
-      nodePort: {{ .Values.service.nodePort }}
+nodePort: {{ .Values.service.nodePort }}
 {{- end }}
-      protocol: TCP
-      name: https
-  selector:
-    app.kubernetes.io/name: {{ include "step-certificates.name" . }}
-    app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
+protocol: TCP
+name: https
+selector:
+  app.kubernetes.io/name: {{ include "step-certificates.name" . }}
+  app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml
index 5ae87c6..19375d9 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml
@@ -1,11 +1,32 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: v1
 kind: Pod
 metadata:
   name: "{{ include "step-certificates.fullname" . }}-test-connection"
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
-  annotations:
-    "helm.sh/hook": test-success
+  {{ include "step-certificates.labels" . | indent 4 }}
+annotations:
+  "helm.sh/hook": test-success
 spec:
   containers:
     - name: wget
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml
index a8141d6..ec99d9d 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # Default values for step-certificates.
 
 # replicaCount is the number of replicas of step-certificates.
@@ -62,7 +83,7 @@
     storageClass: ${storage_class_name}
     # accessModes defines the Persistent Volume Access Mode.
     accessModes:
-    - ReadWriteOnce
+      - ReadWriteOnce
     # size is the Persistent Volume size.
     size: 10Gi
   # runAsRoot runs the ca as root instead of the step user. This is required in
@@ -91,7 +112,7 @@
   #   memory: 128Mi
   # requests:
   #   cpu: 100m
-  #   memory: 128Mi
+#   memory: 128Mi
 
 # nodeSelector contains the node labels for pod assignment.
 nodeSelector: {}
diff --git a/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml b/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml
index 4fe0b75..dd33a9e 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml
+++ b/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml b/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml
index 66f5418..6953d49 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml
+++ b/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml b/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml
index e315979..af793ba 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml
+++ b/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py b/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py
index fb05691..7a324d2 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py
+++ b/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py
@@ -1,12 +1,29 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+import argparse
+import logging
+import random
+import string
+import sys
+import time
+import traceback
 from fabric import Connection
 from patchwork.files import exists
-import logging
-import argparse
-import sys
-import traceback
-import time
-import string
-import random
 
 conn = None
 args = None
diff --git a/infrastructure-provisioning/terraform/bin/dlab.py b/infrastructure-provisioning/terraform/bin/dlab.py
index 60af3b3..b1e7cff 100644
--- a/infrastructure-provisioning/terraform/bin/dlab.py
+++ b/infrastructure-provisioning/terraform/bin/dlab.py
@@ -1,3 +1,20 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
 import argparse
 import itertools
 import json
@@ -9,10 +26,9 @@
 import sys
 import time
 from abc import abstractmethod
-
+from deploy.endpoint_fab import start_deploy
 from fabric import Connection
 from patchwork.transfers import rsync
-from deploy.endpoint_fab import start_deploy
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
 logging.basicConfig(level=logging.INFO, format='%(levelname)s-%(message)s')
diff --git a/infrastructure-provisioning/terraform/bin/terraform-cli.py b/infrastructure-provisioning/terraform/bin/terraform-cli.py
index 8e1bd60..3503b58 100755
--- a/infrastructure-provisioning/terraform/bin/terraform-cli.py
+++ b/infrastructure-provisioning/terraform/bin/terraform-cli.py
@@ -1,17 +1,34 @@
 #!/usr/bin/env python
-import itertools
-import json
-import os
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
 import abc
 import argparse
-
-import time
-from fabric import Connection
-from patchwork.transfers import rsync
+import itertools
+import json
 import logging
+import os
 import os.path
 import sys
+import time
 from deploy.endpoint_fab import start_deploy
+from fabric import Connection
+from patchwork.transfers import rsync
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
 logging.basicConfig(level=logging.INFO,
diff --git a/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py b/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py
index 33e08f7..a050d02 100644
--- a/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py
+++ b/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py
@@ -1,10 +1,27 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+import argparse
+import logging
+import sys
+import time
+import traceback
 from fabric import Connection
 from patchwork.files import exists
-import logging
-import argparse
-import sys
-import traceback
-import time
 
 conn = None
 args = None
diff --git a/infrastructure-provisioning/terraform/gcp/main/main.tf b/infrastructure-provisioning/terraform/gcp/main/main.tf
index 3cbca78..620fbea 100644
--- a/infrastructure-provisioning/terraform/gcp/main/main.tf
+++ b/infrastructure-provisioning/terraform/gcp/main/main.tf
@@ -1,12 +1,33 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 provider "google" {
   credentials = "${var.credentials}"
-  project     = "${var.project_name}"
-  region      = "${var.region_var}"
-  zone        = "${var.zone_var}"
+  project = "${var.project_name}"
+  region = "${var.region_var}"
+  zone = "${var.zone_var}"
 }
 
 module "common" {
-  source            = "../modules/common"
+  source = "../modules/common"
   project_tag       = "${var.project_tag}"
   endpoint_tag      = "${var.endpoint_tag}"
   user_tag          = "${var.user_tag}"
diff --git a/infrastructure-provisioning/terraform/gcp/main/variables.tf b/infrastructure-provisioning/terraform/gcp/main/variables.tf
index 2b328ee..12e7647 100644
--- a/infrastructure-provisioning/terraform/gcp/main/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/main/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 variable "credentials" {}
 
 variable "project_name" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf b/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf
index 6931f60..d409a34 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf
@@ -1,11 +1,32 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 locals {
   service_name = "${var.project_tag}-ps-sa"
-  role_name    = "${var.project_tag}-ps-role"
+  role_name = "${var.project_tag}-ps-role"
 }
 
 resource "google_service_account" "ps_sa" {
   #Create service account for notebooks and computational resources
-  account_id   = "${var.project_tag}-ps-sa"
+  account_id = "${var.project_tag}-ps-sa"
   display_name = "${var.project_tag}-ps-sa"
 }
 
diff --git a/infrastructure-provisioning/terraform/gcp/modules/common/network.tf b/infrastructure-provisioning/terraform/gcp/modules/common/network.tf
index 8d34249..828c987 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/common/network.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/common/network.tf
@@ -1,12 +1,33 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 resource "google_compute_subnetwork" "subnet" {
-  name          = "${var.project_tag}-subnet"
+  name = "${var.project_tag}-subnet"
   ip_cidr_range = "${var.cidr_range}"
-  region        = "${var.region}"
-  network       = "${var.vpc_name}"
+  region = "${var.region}"
+  network = "${var.vpc_name}"
 }
 
 resource "google_compute_firewall" "fw_ingress" {
-  name    = "${var.fw_ingress}"
+  name = "${var.fw_ingress}"
   network = "${var.vpc_name}"
   allow {
     protocol = "all"
diff --git a/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf
index b4180ad..ec812d0 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 variable "project_tag" {}
 
 variable "endpoint_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf b/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf
index fdb6250..9800a35 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf
@@ -1,12 +1,34 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 locals {
   notebook_name = "${var.project_tag}-nb-${var.notebook_name}"
-  cluster_name  = "${var.project_tag}-de-${var.notebook_name}-${var.cluster_name}"
+  cluster_name = "${var.project_tag}-de-${var.notebook_name}-${var.cluster_name}"
 }
 
 resource "google_compute_instance" "master" {
-  name         = "${local.cluster_name}-m"
+  name = "${local.cluster_name}-m"
   machine_type = "${var.master_shape}"
-  tags         = ["${var.network_tag}"]
+  tags = [
+    "${var.network_tag}"]
   zone         = "${var.zone_var}"
 
   boot_disk {
diff --git a/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf
index 12c4f92..934df8b 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 variable "project_tag" {}
 
 variable "endpoint_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf b/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf
index 415479c..3f8ec4a 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf
@@ -1,42 +1,63 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 locals {
   dataproc_name = "${var.project_tag}-des-${var.notebook_name}-${var.cluster_name}"
 }
 
 resource "google_dataproc_cluster" "dataproc" {
-    name       = "${local.dataproc_name}"
-    region     = "${var.region}"
-    labels = {
-        computational_name = "${var.cluster_name}"
-        name               = "${local.dataproc_name}"
-        sbn                = "${var.project_tag}"
-        user               = "${var.user_tag}"
+  name = "${local.dataproc_name}"
+  region = "${var.region}"
+  labels = {
+    computational_name = "${var.cluster_name}"
+    name               = "${local.dataproc_name}"
+    sbn                = "${var.project_tag}"
+    user               = "${var.user_tag}"
+  }
+
+  cluster_config {
+
+    master_config {
+      num_instances     = 1
+      machine_type      = "${var.master_shape}"
+      disk_config {
+        boot_disk_size_gb = 30
+      }
     }
 
-    cluster_config {
-
-        master_config {
-            num_instances     = 1
-            machine_type      = "${var.master_shape}"
-            disk_config {
-                boot_disk_size_gb = 30
-            }
-        }
-
-        worker_config {
-            num_instances     = "${var.total_count - 1}"
-            machine_type      = "${var.slave_shape}"
-            disk_config {
-                boot_disk_size_gb = 30
-            }
-        }
-
-        gce_cluster_config {
-            subnetwork = "${var.subnet_name}"
-            tags    = ["${var.network_tag}"]
-        }
-
-        preemptible_worker_config {
-            num_instances = "${var.preemptible_count}"
-        }
+    worker_config {
+      num_instances     = "${var.total_count - 1}"
+      machine_type      = "${var.slave_shape}"
+      disk_config {
+        boot_disk_size_gb = 30
+      }
     }
-  }
\ No newline at end of file
+
+    gce_cluster_config {
+      subnetwork = "${var.subnet_name}"
+      tags    = ["${var.network_tag}"]
+    }
+
+    preemptible_worker_config {
+      num_instances = "${var.preemptible_count}"
+    }
+  }
+}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf
index d3dcf15..5b850ee 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 variable "region" {}
 
 variable "project_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf b/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf
index 0943e51..725fab6 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 locals {
   name = "${var.project_tag}-nb-${var.notebook_name}"
 }
@@ -6,7 +27,7 @@
   name = "${local.name}-secondary"
   zone = "${var.zone_var}"
   labels = {
-    name    = "${local.name}"
+    name = "${local.name}"
     product = "${var.product}"
     project = "${var.project_tag}"
     user    = "${var.user_tag}"
diff --git a/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf
index 6217480..56635ac 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 variable "project_tag" {}
 
 variable "endpoint_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh
index 4f27a1b..3085eb7 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh
@@ -1,5 +1,26 @@
 #!/bin/bash
 
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
 creds_file_path=$1
 gke_name=$2
 region=$3
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore
index fbe01f8..e25078a 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # Patterns to ignore when building packages.
 # This supports shell glob matching, relative path matching, and
 # negation (prefixed with !). Only one pattern per line.
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml
index 4b334aa..d133831 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: v1
 appVersion: 0.13.2
 description: An online certificate authority and related tools for secure automated
@@ -6,7 +27,7 @@
 home: https://smallstep.com
 icon: https://raw.githubusercontent.com/smallstep/certificates/master/icon.png
 keywords:
-- acme
+  - acme
 - authority
 - ca
 - certificate
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl
index e240bac..b65f748 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
 {{/* vim: set filetype=mustache: */}}
 {{/*
 Expand the name of the chart.
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml
index 4fa3240..3e67b22 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml
@@ -1,11 +1,32 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
+  {{- if .Release.IsInstall -}}
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: {{ include "step-certificates.fullname" . }}-config
   namespace: {{.Release.Namespace}}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
 ---
 apiVersion: batch/v1
 kind: Job
@@ -24,16 +45,16 @@
       serviceAccountName: {{ include "step-certificates.fullname" . }}-config
       restartPolicy: Never
       volumes:
-      - name: bootstrap
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-bootstrap
+        - name: bootstrap
+          configMap:
+            name: {{ include "step-certificates.fullname" . }}-bootstrap
       containers:
-      - name: config
-        image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
-        imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
-        command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
-        volumeMounts:
-          - name: bootstrap
-            mountPath: /home/step/bootstrap
-            readOnly: true
+        - name: config
+          image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
+          imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
+          command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
+          volumeMounts:
+            - name: bootstrap
+              mountPath: /home/step/bootstrap
+              readOnly: true
 {{- end -}}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml
index 1113f2b..14e5f75 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml
@@ -1,9 +1,30 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: apps/v1
 kind: StatefulSet
 metadata:
   name: {{ include "step-certificates.fullname" . }}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
 spec:
   # Only one replica is supported at this moment
   # Requested {{ .Values.replicaCount }}
@@ -21,99 +42,99 @@
         app: {{ include "step-certificates.fullname" . }}
     spec:
 {{- if .Release.IsInstall }}
-      initContainers:
-        - name: {{ .Chart.Name }}-init
-          image: busybox:latest
-          imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command: ["sleep", "20"]
+initContainers:
+  - name: {{ .Chart.Name }}-init
+    image: busybox:latest
+    imagePullPolicy: {{ .Values.image.pullPolicy }}
+    command: ["sleep", "20"]
 {{- end }}
-      securityContext:
-        {{- if .Values.ca.runAsRoot }}
-        runAsUser: 0
-        {{- else }}
-        runAsUser: 1000
-        runAsNonRoot: true
-        runAsGroup: 1000
-        fsGroup: 1000
-        allowPrivilegeEscalation: false
-        {{- end }}
-      containers:
-        - name: {{ .Chart.Name }}
-          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
-          imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command: ["/usr/local/bin/step-ca",
-            "--password-file", "/home/step/secrets/passwords/password",
-            "/home/step/config/ca.json"]
-          env:
-          - name: NAMESPACE
-            value: "{{ .Release.Namespace }}"
-          ports:
-            - name: https
-              containerPort: {{ .Values.service.targetPort }}
-              protocol: TCP
-          livenessProbe:
-            initialDelaySeconds: 5
-            httpGet:
-              path: /health
-              port: {{ .Values.service.targetPort }}
-              scheme: HTTPS
-          readinessProbe:
-            initialDelaySeconds: 5
-            httpGet:
-              path: /health
-              port: {{ .Values.service.targetPort }}
-              scheme: HTTPS
-          resources:
-            {{- toYaml .Values.resources | nindent 12 }}
-          volumeMounts:
-          - name: certs
-            mountPath: /home/step/certs
-            readOnly: true
-          - name: config
-            mountPath: /home/step/config
-            readOnly: true
-          - name: secrets
-            mountPath: /home/step/secrets
-            readOnly: true
-          - name: ca-password
-            mountPath: /home/step/secrets/passwords
-            readOnly: true
-          {{- if .Values.ca.db.enabled }}
-          - name: database
-            mountPath: /home/step/db
-            readOnly: false
-          {{- end }}
-      volumes:
+securityContext:
+  {{- if .Values.ca.runAsRoot }}
+  runAsUser: 0
+  {{- else }}
+  runAsUser: 1000
+  runAsNonRoot: true
+  runAsGroup: 1000
+  fsGroup: 1000
+  allowPrivilegeEscalation: false
+  {{- end }}
+containers:
+  - name: {{ .Chart.Name }}
+    image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+    imagePullPolicy: {{ .Values.image.pullPolicy }}
+    command: ["/usr/local/bin/step-ca",
+              "--password-file", "/home/step/secrets/passwords/password",
+              "/home/step/config/ca.json"]
+    env:
+      - name: NAMESPACE
+        value: "{{ .Release.Namespace }}"
+    ports:
+      - name: https
+        containerPort: {{ .Values.service.targetPort }}
+        protocol: TCP
+    livenessProbe:
+      initialDelaySeconds: 5
+      httpGet:
+        path: /health
+        port: {{ .Values.service.targetPort }}
+        scheme: HTTPS
+    readinessProbe:
+      initialDelaySeconds: 5
+      httpGet:
+        path: /health
+        port: {{ .Values.service.targetPort }}
+        scheme: HTTPS
+    resources:
+      {{- toYaml .Values.resources | nindent 12 }}
+    volumeMounts:
       - name: certs
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-certs
+        mountPath: /home/step/certs
+        readOnly: true
       - name: config
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-config
+        mountPath: /home/step/config
+        readOnly: true
       - name: secrets
-        configMap:
-          name: {{ include "step-certificates.fullname" . }}-secrets
+        mountPath: /home/step/secrets
+        readOnly: true
       - name: ca-password
-        secret:
-          secretName: {{ include "step-certificates.fullname" . }}-ca-password
-      {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
-      - name: database
-        emptyDir: {}
-      {{- end }}
-      {{- with .Values.nodeSelector }}
-      nodeSelector:
-      {{- toYaml . | nindent 8 }}
-      {{- end }}
-      {{- with .Values.affinity }}
-      affinity:
-      {{- toYaml . | nindent 8 }}
-      {{- end }}
-      {{- with .Values.tolerations }}
-      tolerations:
-      {{- toYaml . | nindent 8 }}
-      {{- end }}
+        mountPath: /home/step/secrets/passwords
+        readOnly: true
+    {{- if .Values.ca.db.enabled }}
+    - name: database
+      mountPath: /home/step/db
+      readOnly: false
+    {{- end }}
+volumes:
+  - name: certs
+    configMap:
+      name: {{ include "step-certificates.fullname" . }}-certs
+  - name: config
+configMap:
+  name: {{ include "step-certificates.fullname" . }}-config
+  - name: secrets
+configMap:
+  name: {{ include "step-certificates.fullname" . }}-secrets
+  - name: ca-password
+secret:
+  secretName: {{ include "step-certificates.fullname" . }}-ca-password
+  {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
+  - name: database
+emptyDir: {}
+  {{- end }}
+  {{- with .Values.nodeSelector }}
+nodeSelector:
+  {{- toYaml . | nindent 8 }}
+  {{- end }}
+  {{- with .Values.affinity }}
+affinity:
+  {{- toYaml . | nindent 8 }}
+  {{- end }}
+  {{- with .Values.tolerations }}
+tolerations:
+  {{- toYaml . | nindent 8 }}
+  {{- end }}
 {{- if and .Values.ca.db.enabled .Values.ca.db.persistent }}
-  volumeClaimTemplates:
+volumeClaimTemplates:
   - metadata:
       name: database
       labels:
@@ -123,16 +144,16 @@
     spec:
       accessModes:
       {{- range .Values.ca.db.accessModes }}
-        - {{ . | quote }}
+      - {{ . | quote }}
       {{- end }}
       resources:
         requests:
           storage: {{ .Values.ca.db.size | quote }}
     {{- if .Values.ca.db.storageClass }}
     {{- if (eq "-" .Values.ca.db.storageClass) }}
-      storageClassName: ""
+    storageClassName: ""
     {{- else }}
-      storageClassName: {{ .Values.ca.db.storageClass | quote }}
+    storageClassName: {{ .Values.ca.db.storageClass | quote }}
     {{- end }}
     {{- end }}
 {{- end }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml
index 28ad488..dc15383 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # ConfigMaps that will be updated by the configuration job:
 # 1. Step CA config directory.
 # 2. Step CA certs direcotry.
@@ -71,76 +92,76 @@
       permission_error "create secrets"
     fi
 {{ if .Values.autocert.enabled }}
-    echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
+echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
     kubectl auth can-i create mutatingwebhookconfiguration --namespace {{.Release.Namespace}}
     if [ $? -ne 0 ]; then
       permission_error "create mutatingwebhookconfiguration"
-    fi
+  fi
 {{- end }}
 
-    # Setting this here on purpose, after the above section which explicitly checks
-    # for and handles exit errors.
-    set -e
+# Setting this here on purpose, after the above section which explicitly checks
+# for and handles exit errors.
+  set -e
 
-    echo -e "\n\e[1mInitializating the CA...\e[0m"
+  echo -e "\n\e[1mInitializating the CA...\e[0m"
 
-    # CA password
+# CA password
 {{- if .Values.ca.password }}
-    CA_PASSWORD={{ quote .Values.ca.password }}
+  CA_PASSWORD={{ quote .Values.ca.password }}
 {{- else }}
-    CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+  CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
 {{- end }}
-    # Provisioner password
+# Provisioner password
 {{- if .Values.ca.provisioner.password }}
-    CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
+  CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
 {{- else }}
-    CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+  CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
 {{- end }}
 
-    TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
-    TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+  TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+  TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
 
-    echo $CA_PASSWORD > $TMP_CA_PASSWORD
-    echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
+  echo $CA_PASSWORD > $TMP_CA_PASSWORD
+  echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
 
-    step ca init \
-      --name "{{.Values.ca.name}}" \
-      --dns "{{include "step-certificates.dns" .}}" \
-      --address "{{.Values.ca.address}}" \
-      --provisioner "{{.Values.ca.provisioner.name}}" \
-      --with-ca-url "{{include "step-certificates.url" .}}" \
-      --password-file "$TMP_CA_PASSWORD" \
-      --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
+  step ca init \
+  --name "{{.Values.ca.name}}" \
+  --dns "{{include "step-certificates.dns" .}}" \
+  --address "{{.Values.ca.address}}" \
+  --provisioner "{{.Values.ca.provisioner.name}}" \
+  --with-ca-url "{{include "step-certificates.url" .}}" \
+  --password-file "$TMP_CA_PASSWORD" \
+  --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
 
-    rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
+  rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
 
-    echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
+  echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
 
-    # Replace secrets created on helm install
-    # It allows to properly remove them on helm delete
-    kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
-    kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
-    kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
+  # Replace secrets created on helm install
+  # It allows to properly remove them on helm delete
+  kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
+  kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
+  kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
 
-    kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
-    kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
+  kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
+  kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
 
-    # Label all configmaps and secrets
-    kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
-    kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+# Label all configmaps and secrets
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
 
-    # Patch webhook if autocert is enabled
+# Patch webhook if autocert is enabled
 {{ if .Values.autocert.enabled }}
-    CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
-    kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
-      --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
+  CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
+  kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
+  --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
 {{- end }}
 
-    echo -e "\n\e[1mStep Certificates installed!\e[0m"
-    echo
-    echo "CA URL: {{include "step-certificates.url" .}}"
-    echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
-    echo
\ No newline at end of file
+  echo -e "\n\e[1mStep Certificates installed!\e[0m"
+  echo
+echo "CA URL: {{include "step-certificates.url" .}}"
+echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
+  echo
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml
index 53264f1..7f5403a 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml
@@ -1,36 +1,56 @@
-{{- if .Values.ingress.enabled -}}
-{{- $fullName := include "step-certificates.fullname" . -}}
+# *****************************************************************************
+#
+  #  Licensed to the Apache Software Foundation (ASF) under one
+  #  or more contributor license agreements.  See the NOTICE file
+  #  distributed with this work for additional information
+  #  regarding copyright ownership.  The ASF licenses this file
+  #  to you under the Apache License, Version 2.0 (the
+  #  "License"); you may not use this file except in compliance
+  #  with the License.  You may obtain a copy of the License at
+  #
+  #  http://www.apache.org/licenses/LICENSE-2.0
+  #
+  #  Unless required by applicable law or agreed to in writing,
+  #  software distributed under the License is distributed on an
+  #  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  #  KIND, either express or implied.  See the License for the
+  #  specific language governing permissions and limitations
+  #  under the License.
+  #
+  # ******************************************************************************
+  {{- if .Values.ingress.enabled -}}
+  {{- $fullName := include "step-certificates.fullname" . -}}
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
   name: {{ $fullName }}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
   {{- with .Values.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
+annotations:
+  {{- toYaml . | nindent 4 }}
   {{- end }}
 spec:
 {{- if .Values.ingress.tls }}
-  tls:
+tls:
   {{- range .Values.ingress.tls }}
-    - hosts:
-      {{- range .hosts }}
-        - {{ . | quote }}
-      {{- end }}
-      secretName: {{ .secretName }}
+- hosts:
+  {{- range .hosts }}
+  - {{ . | quote }}
+  {{- end }}
+  secretName: {{ .secretName }}
   {{- end }}
 {{- end }}
-  rules:
+rules:
   {{- range .Values.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-        {{- range .paths }}
-          - path: {{ . }}
-            backend:
-              serviceName: {{ $fullName }}
-              servicePort: http
-        {{- end }}
+- host: {{ .host | quote }}
+  http:
+    paths:
+    {{- range .paths }}
+    - path: {{ . }}
+      backend:
+        serviceName: {{ $fullName }}
+        servicePort: http
+    {{- end }}
   {{- end }}
 {{- end }}
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml
index 6f4e137..ebab8c4 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml
@@ -1,4 +1,25 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
+  {{- if .Release.IsInstall -}}
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml
index 567a989..64f8b9b 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # Secrets that will be updated by the configuration job:
 # 1. CA keys password.
 # 2. Provisioner password.
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml
index 4ec0783..fb17ab1 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml
@@ -1,19 +1,40 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: v1
 kind: Service
 metadata:
   name: {{ include "step-certificates.fullname" . }}
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+  {{ include "step-certificates.labels" . | indent 4 }}
 spec:
   type: {{ .Values.service.type }}
   ports:
     - port: {{ .Values.service.port }}
       targetPort: {{ .Values.service.targetPort }}
 {{- if .Values.service.nodePort }}
-      nodePort: {{ .Values.service.nodePort }}
+nodePort: {{ .Values.service.nodePort }}
 {{- end }}
-      protocol: TCP
-      name: https
-  selector:
-    app.kubernetes.io/name: {{ include "step-certificates.name" . }}
-    app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
+protocol: TCP
+name: https
+selector:
+  app.kubernetes.io/name: {{ include "step-certificates.name" . }}
+  app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml
index 5ae87c6..19375d9 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml
@@ -1,11 +1,32 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 apiVersion: v1
 kind: Pod
 metadata:
   name: "{{ include "step-certificates.fullname" . }}-test-connection"
   labels:
-{{ include "step-certificates.labels" . | indent 4 }}
-  annotations:
-    "helm.sh/hook": test-success
+  {{ include "step-certificates.labels" . | indent 4 }}
+annotations:
+  "helm.sh/hook": test-success
 spec:
   containers:
     - name: wget
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml
index 45350b6..fdc7b9a 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 # Default values for step-certificates.
 
 # replicaCount is the number of replicas of step-certificates.
@@ -63,7 +84,7 @@
     storageClass: standard
     # accessModes defines the Persistent Volume Access Mode.
     accessModes:
-    - ReadWriteOnce
+      - ReadWriteOnce
     # size is the Persistent Volume size.
     size: 10Gi
   # runAsRoot runs the ca as root instead of the step user. This is required in
@@ -92,7 +113,7 @@
   #   memory: 128Mi
   # requests:
   #   cpu: 100m
-  #   memory: 128Mi
+#   memory: 128Mi
 
 # nodeSelector contains the node labels for pod assignment.
 nodeSelector: {}
diff --git a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css
index b31310a..1f5d717 100644
--- a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css
+++ b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 .login-pf body {
     background: url("../img/login-background.png") no-repeat center center fixed;
     background-size: cover;
diff --git a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties
index ed1c3c1..5ff84ad 100644
--- a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties
+++ b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties
@@ -1,25 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
 parent=base
 import=common/keycloak
-
 styles=node_modules/patternfly/dist/css/patternfly.css node_modules/patternfly/dist/css/patternfly-additions.css lib/zocial/zocial.css css/login.css
 meta=viewport==width=device-width,initial-scale=1
-
 kcHtmlClass=login-pf
 kcLoginClass=login-pf-page
-
 kcLogoLink=http://www.keycloak.org
-
 kcLogoClass=login-pf-brand
-
 kcContainerClass=container-fluid
 kcContentClass=col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-6 col-lg-offset-3
 kcContentWrapperClass=row
-
 kcHeaderClass=login-pf-page-header
 kcFeedbackAreaClass=col-md-12
 kcLocaleClass=col-xs-12 col-sm-1
 kcAlertIconClasserror=pficon pficon-error-circle-o
-
 kcFormAreaClass=col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2
 kcFormCardClass=card-pf
 kcFormCardAccountClass=login-pf-accounts
@@ -29,13 +40,10 @@
 kcFormSocialAccountDoubleListClass=login-pf-social-double-col
 kcFormSocialAccountListLinkClass=login-pf-social-link
 kcFormHeaderClass=login-pf-header
-
 kcFeedbackErrorIcon=pficon pficon-error-circle-o
 kcFeedbackWarningIcon=pficon pficon-warning-triangle-o
 kcFeedbackSuccessIcon=pficon pficon-ok
 kcFeedbackInfoIcon=pficon pficon-info
-
-
 kcFormClass=form-horizontal
 kcFormGroupClass=form-group
 kcFormGroupErrorClass=has-error
@@ -48,10 +56,7 @@
 kcFormSettingClass=login-pf-settings
 kcTextareaClass=form-control
 kcSignUpClass=login-pf-signup
-
-
 kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-5 details
-
 ##### css classes for form buttons
 # main class used for all buttons
 kcButtonClass=btn
@@ -61,9 +66,7 @@
 # classes defining size of the button
 kcButtonLargeClass=btn-lg
 kcButtonBlockClass=btn-block
-
 ##### css classes for input
 kcInputLargeClass=input-lg
-
 ##### css classes for form accessability
 kcSrOnlyClass=sr-only
diff --git a/integration-tests-cucumber/pom.xml b/integration-tests-cucumber/pom.xml
index d96a492..d862bcb 100644
--- a/integration-tests-cucumber/pom.xml
+++ b/integration-tests-cucumber/pom.xml
@@ -1,4 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
 <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">
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java
index a06a4d7..7cfdad2 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package org.apache.dlab.dto;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java
index 11e4dea..4903fd4 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package org.apache.dlab.mongo;
 
 import com.mongodb.client.MongoClient;
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java
index a18d4d9..ae4d5ce 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package org.apache.dlab.util;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java
index 48d7cca..71688e2 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package org.apache.dlab.util;
 
 import java.io.FileInputStream;
diff --git a/integration-tests-cucumber/src/test/java/dlab/Constants.java b/integration-tests-cucumber/src/test/java/dlab/Constants.java
index 4e30e99..8e1b6b9 100644
--- a/integration-tests-cucumber/src/test/java/dlab/Constants.java
+++ b/integration-tests-cucumber/src/test/java/dlab/Constants.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package dlab;
 
 public interface Constants {
diff --git a/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java b/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java
index fdc8a4c..fb03b55 100644
--- a/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java
+++ b/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package dlab;
 
 import cucumber.api.CucumberOptions;
diff --git a/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java b/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java
index e66fc33..1c1d43a 100644
--- a/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java
+++ b/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package dlab.endpoint;
 
 import com.jayway.restassured.http.ContentType;
diff --git a/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java b/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java
index 32b29cb..fd533e0 100644
--- a/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java
+++ b/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package dlab.login;
 
 import com.jayway.restassured.http.ContentType;
diff --git a/integration-tests-cucumber/src/test/resources/config.properties b/integration-tests-cucumber/src/test/resources/config.properties
index 5cfad3c..d0cfc24 100644
--- a/integration-tests-cucumber/src/test/resources/config.properties
+++ b/integration-tests-cucumber/src/test/resources/config.properties
@@ -1,2 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
 mongo.connection.string=mongodb://localhost:27017/DLAB
 mongo.db.name=DLAB
\ No newline at end of file
diff --git a/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature b/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature
index 7281a24..1f7fe14 100644
--- a/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature
+++ b/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature
@@ -1,3 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
 Feature: Endpoint management in DLab
   Such feature allowed to manage endpoint inside DLab
 
diff --git a/integration-tests-cucumber/src/test/resources/dlab/login.feature b/integration-tests-cucumber/src/test/resources/dlab/login.feature
index 493a51e..1675aad 100644
--- a/integration-tests-cucumber/src/test/resources/dlab/login.feature
+++ b/integration-tests-cucumber/src/test/resources/dlab/login.feature
@@ -1,3 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
 Feature: DLab login API
   Used to check DLab login flow
 
diff --git a/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py b/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py
index edc981e..92a9596 100644
--- a/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py
+++ b/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py
@@ -115,11 +115,11 @@
         prepare_ipynb(i, '/home/{}/test_templates/template_theano.ipynb'.format(args.os_user), 'test_theano')
         run_ipynb('test_theano')
 
-def run_torch():
-    interpreters = ['itorch']
-    for i in interpreters:
-        prepare_ipynb(i, '/home/{}/test_templates/template_torch.ipynb'.format(args.os_user), 'test_torch')
-        run_ipynb('test_torch')
+#def run_torch():
+#    interpreters = ['itorch']
+#    for i in interpreters:
+#        prepare_ipynb(i, '/home/{}/test_templates/template_torch.ipynb'.format(args.os_user), 'test_torch')
+#        run_ipynb('test_torch')
 
 
 if __name__ == "__main__":
@@ -132,7 +132,7 @@
         run_keras()
         run_mxnet()
         run_theano()
-        run_torch()
+        #run_torch()
     except Exception as err:
         print('Error!', str(err))
         sys.exit(1)
diff --git a/integration-tests/examples/test_templates/rstudio/template_preparation.r b/integration-tests/examples/test_templates/rstudio/template_preparation.r
index 773a049..0c4377e 100644
--- a/integration-tests/examples/test_templates/rstudio/template_preparation.r
+++ b/integration-tests/examples/test_templates/rstudio/template_preparation.r
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
 sc <- sparkR.session(MASTER)
 
 working_storage <- "WORKING_STORAGE"
diff --git a/integration-tests/examples/test_templates/rstudio/template_visualization.r b/integration-tests/examples/test_templates/rstudio/template_visualization.r
index 6b38ec8..e79f460 100644
--- a/integration-tests/examples/test_templates/rstudio/template_visualization.r
+++ b/integration-tests/examples/test_templates/rstudio/template_visualization.r
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
 sc <- sparkR.session(MASTER)
 
 full_path <- function(file_path) {
diff --git a/pom.xml b/pom.xml
index e24bfd9..47645ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,41 @@
                 <module>services/billing-gcp</module>
             </modules>
         </profile>
+        <profile>
+            <id>sonar</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <properties>
+                <sonar.host.url>
+                    http://localhost:9000/sonar
+                </sonar.host.url>
+                <sonar.coverage.exclusions>
+                    **/*Exception.java,
+                    **/*DAO.java,
+                    **/*DAOImpl.java,
+                    **/*Configuration.java,
+                    **/*ApplicationConfiguration.java,
+                    src/main/java/com/epam/dlab/dto/**,
+                    src/main/java/com/epam/dlab/backendapi/interceptor/**,
+                    src/main/java/com/epam/dlab/backendapi/auth/**,
+                    src/main/java/com/epam/dlab/backendapi/conf/**,
+                    src/main/java/com/epam/dlab/backendapi/domain/**,
+                    src/main/java/com/epam/dlab/backendapi/dropwizard/**,
+                    src/main/java/com/epam/dlab/backendapi/healthcheck/**,
+                    src/main/java/com/epam/dlab/backendapi/modules/**,
+                    src/main/java/com/epam/dlab/backendapi/resources/dto/**,
+                    src/main/java/com/epam/dlab/backendapi/roles/**,
+                    src/main/java/com/epam/dlab/backendapi/servlet/guacamole/**,
+                    src/main/java/com/epam/dlab/backendapi/util/**,
+                    src/main/java/com/epam/dlab/backendapi/validation/**,
+                    src/main/java/com/epam/dlab/process/**,
+                    src/main/java/com/epam/dlab/backendapi/modules/**,
+                    src/main/java/com/epam/dlab/backendapi/validation/**,
+                    src/main/java/com/epam/dlab/backendapi/schedulers/**
+                </sonar.coverage.exclusions>
+            </properties>
+        </profile>
     </profiles>
 
     <modules>
@@ -88,6 +123,7 @@
         <logback.version>1.2.3</logback.version>
         <commons-fileupload.version>1.3.3</commons-fileupload.version>
     </properties>
+
     <dependencyManagement>
         <dependencies>
             <dependency>
@@ -130,8 +166,6 @@
                 <artifactId>dropwizard-util</artifactId>
                 <version>${io.dropwizard.version}</version>
             </dependency>
-
-
         </dependencies>
     </dependencyManagement>
 
@@ -174,6 +208,11 @@
                         </execution>
                     </executions>
                 </plugin>
+                <plugin>
+                    <groupId>org.sonarsource.scanner.maven</groupId>
+                    <artifactId>sonar-maven-plugin</artifactId>
+                    <version>3.7.0.1746</version>
+                </plugin>
             </plugins>
         </pluginManagement>
         <plugins>
@@ -230,7 +269,7 @@
             <plugin>
                 <groupId>org.apache.rat</groupId>
                 <artifactId>apache-rat-plugin</artifactId>
-                <version>0.7</version>
+                <version>0.13</version>
                 <configuration>
                     <excludes>
                         <exclude>.git/**</exclude>
@@ -241,6 +280,7 @@
                         <exclude>**/*.ipynb</exclude>
                         <exclude>**/*.iml</exclude>
                         <exclude>**/*.json</exclude>
+                        <exclude>**/*.json.tpl</exclude>
                         <exclude>**/*.r</exclude>
                         <exclude>**/__init__.py</exclude>
                         <exclude>**/*.conf</exclude>
diff --git a/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java b/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java
index 9b4d6db..15dcc32 100644
--- a/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java
+++ b/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java
@@ -23,6 +23,7 @@
 
 import java.util.List;
 
+@FunctionalInterface
 public interface BillingService {
     List<BillingData> getBillingData();
 }
diff --git a/services/billing-aws/src/main/resources/application.yml b/services/billing-aws/src/main/resources/application.yml
index ece61aa..8b1b641 100644
--- a/services/billing-aws/src/main/resources/application.yml
+++ b/services/billing-aws/src/main/resources/application.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java
index b3eec4f..441475e 100644
--- a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java
+++ b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java
@@ -22,7 +22,6 @@
 import com.epam.dlab.billing.BillingCalculationUtils;
 import com.epam.dlab.billing.azure.config.BillingConfigurationAzure;
 import com.epam.dlab.billing.azure.model.AzureDailyResourceInvoice;
-import com.epam.dlab.billing.azure.model.AzureDlabBillableResource;
 import com.epam.dlab.billing.azure.rate.AzureRateCardClient;
 import com.epam.dlab.billing.azure.rate.Meter;
 import com.epam.dlab.billing.azure.rate.RateCardResponse;
@@ -58,7 +57,6 @@
 	private static final long MAX_AUTH_TOKEN_TTL_MILLIS = 9L * 60L * 1000L;
 
 	private BillingConfigurationAzure billingConfigurationAzure;
-	private Map<String, AzureDlabBillableResource> billableResources;
 
 	/**
 	 * Constructs service class
diff --git a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java
index d432337..2f265c0 100644
--- a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java
+++ b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java
@@ -23,6 +23,7 @@
 
 import java.util.List;
 
+@FunctionalInterface
 public interface CalculateBillingService {
     List<BillingData> getBillingData();
 }
diff --git a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java
index 35e341c..9ee3d0a 100644
--- a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java
+++ b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java
@@ -44,7 +44,7 @@
     }
 
     @Bean
-    public KeycloakConfigResolver KeycloakConfigResolver() {
+    public KeycloakConfigResolver keycloakConfigResolver() {
         return new KeycloakSpringBootConfigResolver();
     }
 
diff --git a/services/billing-azure/src/main/resources/application.yml b/services/billing-azure/src/main/resources/application.yml
index eba7073..f029e30 100644
--- a/services/billing-azure/src/main/resources/application.yml
+++ b/services/billing-azure/src/main/resources/application.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/services/billing-gcp/billing.yml b/services/billing-gcp/billing.yml
index 87313c2..621c9b4 100644
--- a/services/billing-gcp/billing.yml
+++ b/services/billing-gcp/billing.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java
index ad960b0..5666283 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java
@@ -44,8 +44,8 @@
     }
 
     @Bean
-    public KeycloakConfigResolver KeycloakConfigResolver() {
-        return new KeycloakSpringBootConfigResolver();
+    public KeycloakConfigResolver keycloakConfigResolver() {
+	    return new KeycloakSpringBootConfigResolver();
     }
 
     @Bean
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
index 7c791df..31a636b 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
@@ -23,6 +23,7 @@
 
 import java.util.List;
 
+@FunctionalInterface
 public interface BillingDAO {
-    List<BillingData> getBillingData() throws InterruptedException;
+	List<BillingData> getBillingData() throws InterruptedException;
 }
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
index 061283d..3a93429 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
@@ -24,6 +24,7 @@
 import com.epam.dlab.billing.gcp.model.BillingHistory;
 import com.epam.dlab.billing.gcp.repository.BillingHistoryRepository;
 import com.epam.dlab.dto.billing.BillingData;
+import com.epam.dlab.exceptions.DlabException;
 import com.google.cloud.bigquery.BigQuery;
 import com.google.cloud.bigquery.FieldValueList;
 import com.google.cloud.bigquery.QueryJobConfiguration;
@@ -32,7 +33,6 @@
 import com.google.cloud.bigquery.TableInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.stereotype.Component;
 
 import java.time.Instant;
@@ -53,7 +53,6 @@
 	private static final String DATASET_PARAM = "dataset";
 
 	private final BillingHistoryRepository billingHistoryRepo;
-	private final MongoTemplate mongoTemplate;
 	private final BigQuery service;
 	private final String dataset;
 	private final String sbn;
@@ -69,11 +68,10 @@
 
 	@Autowired
 	public BigQueryBillingDAO(DlabConfiguration conf, BillingHistoryRepository billingHistoryRepo,
-							  BigQuery service, MongoTemplate mongoTemplate) {
+	                          BigQuery service) {
 		dataset = conf.getBigQueryDataset();
 		this.service = service;
 		this.billingHistoryRepo = billingHistoryRepo;
-		this.mongoTemplate = mongoTemplate;
 		sbn = conf.getSbn();
 	}
 
@@ -107,8 +105,9 @@
 							.map(this::toGcpBillingData);
 			billingHistoryRepo.save(new BillingHistory(tableName, table.getLastModifiedTime()));
 			return gcpBillingDataStream;
-		} catch (InterruptedException e) {
-			throw new IllegalStateException("Can not get billing info from BigQuery due to: " + e.getMessage(), e);
+		} catch (Exception e) {
+			log.error("Can not get billing info from BigQuery due to {}", e.getMessage(), e);
+			throw new DlabException("Can not get billing info from BigQuery due to: " + e.getMessage(), e);
 		}
 	}
 
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java
index 6abb2d9..8fb80f1 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.billing.gcp.model;
 
 import lombok.AllArgsConstructor;
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java
index c375904..957ced7 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.billing.gcp.repository;
 
 import com.epam.dlab.billing.gcp.model.BillingHistory;
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java
index 7bb3246..ca4277f 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java
@@ -23,6 +23,7 @@
 
 import java.util.List;
 
+@FunctionalInterface
 public interface BillingService {
-    List<BillingData> getBillingData();
+	List<BillingData> getBillingData();
 }
diff --git a/services/billing-gcp/src/main/resources/application.yml b/services/billing-gcp/src/main/resources/application.yml
index b2fda5d..9e29b04 100644
--- a/services/billing-gcp/src/main/resources/application.yml
+++ b/services/billing-gcp/src/main/resources/application.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# ******************************************************************************
+
 spring:
   main:
     allow-bean-definition-overriding: true
diff --git a/services/common/src/main/java/com/epam/dlab/auth/conf/AzureLoginConfiguration.java b/services/common/src/main/java/com/epam/dlab/auth/conf/AzureLoginConfiguration.java
deleted file mode 100644
index cf6331c..0000000
--- a/services/common/src/main/java/com/epam/dlab/auth/conf/AzureLoginConfiguration.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.epam.dlab.auth.conf;
-
-import lombok.Getter;
-
-@Getter
-public class AzureLoginConfiguration {
-	private boolean useLdap;
-	private boolean silent;
-	private String tenant;
-	private String authority;
-	private String clientId;
-	private String redirectUrl;
-	private String responseMode;
-	private String prompt;
-	private String loginPage;
-	private boolean validatePermissionScope;
-	private String permissionScope;
-	private String managementApiAuthFile;
-	private long maxSessionDurabilityMilliseconds = 8L * 60L * 60L * 1000L;// 8 hours
-}
diff --git a/services/common/src/main/java/com/epam/dlab/auth/conf/GcpLoginConfiguration.java b/services/common/src/main/java/com/epam/dlab/auth/conf/GcpLoginConfiguration.java
deleted file mode 100644
index 6dbaf02..0000000
--- a/services/common/src/main/java/com/epam/dlab/auth/conf/GcpLoginConfiguration.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.epam.dlab.auth.conf;
-
-import lombok.Data;
-
-@Data
-public class GcpLoginConfiguration {
-	private final boolean oauth2authenticationEnabled;
-	private final String redirectedUri;
-	private final String clientId;
-	private final String clientSecret;
-	private final String applicationName;
-	private final int userStateCacheSize;
-	private final long userStateCacheExpirationTime;
-}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java b/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java
index 6553f2a..1ba4eed 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java
@@ -20,14 +20,6 @@
 package com.epam.dlab;
 
 public abstract class MongoKeyWords {
-    public static final String EDGE_COLLECTION = "userCloudCredentials";
-    public static final String SETTINGS_COLLECTION = "settings";
-    public static final String NOTEBOOK_COLLECTION = "userInstances";
-    public static final String SERVICE_BASE_NAME_KEY = "conf_service_base_name";
-    public static final String SSN_STORAGE_ACCOUNT_TAG_KEY = "ssn_storage_account_tag_name";
-    public static final String SHARED_STORAGE_ACCOUNT_TAG_KEY = "shared_storage_account_tag_name";
-    public static final String DATA_LAKE_TAG_NAME = "datalake_tag_name";
-    public static final String BILLING_DETAILS = "billing";
     public static final String AZURE_BILLING_SCHEDULER = "billingScheduler";
     public static final String AZURE_BILLING_SCHEDULER_HISTORY = "billingSchedulerHistory";
 
@@ -35,30 +27,8 @@
      * Mongo DB keywords related to billing functionality
      */
     public static final String MONGO_ID = "_id";
-    public static final String DLAB_ID = "dlabId";
-    public static final String DLAB_USER = "user";
-    public static final String EXPLORATORY_ID = "exploratoryId";
-    public static final String EXPLORATORY_ID_OLD = "exploratory_id";
-    public static final String RESOURCE_TYPE = "resourceType";
-    public static final String RESOURCE_NAME = "resourceName";
-    public static final String COMPUTATIONAL_ID = "computationalId";
-    public static final String METER_CATEGORY = "meterCategory";
-    public static final String COST = "cost";
-    public static final String COST_STRING = "costString";
-    public static final String USAGE_DAY = "day";
-    public static final String USAGE_FROM = "from";
-    public static final String USAGE_TO = "to";
-    public static final String CURRENCY_CODE = "currencyCode";
 
 
     private MongoKeyWords() {
     }
-
-    public static String prepend$(String value) {
-        return "$" + value;
-    }
-
-    public static String prependId(String value) {
-        return MongoKeyWords.MONGO_ID + "." + value;
-    }
 }
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java
index 11a6db6..9134f4a 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.dto.base.project;
 
 import com.epam.dlab.dto.StatusBaseDTO;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java
index 5f131a1..aa25af4 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java
@@ -67,6 +67,10 @@
 	private int dataengineInstanceCount;
 	@JsonProperty("instance_id")
 	private String instanceId;
+	@JsonProperty("dataproc_version")
+	private String gcpClusterVersion;
+	@JsonProperty("emr_version")
+	private String awsClusterVersion;
 	private int totalInstanceCount;
 	protected List<ClusterConfig> config;
 	private Map<String, String> tags;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java
index cb32efb..557be36 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java
@@ -79,6 +79,7 @@
 		return self;
 	}
 
+	@Override
 	public T withEndpoint(String endpoint) {
 		this.endpoint = endpoint;
 		return self;
@@ -102,10 +103,12 @@
 		return self;
 	}
 
+	@Override
 	public String getEndpoint() {
 		return endpoint;
 	}
 
+	@Override
 	public void setEndpoint(String endpoint) {
 		this.endpoint = endpoint;
 	}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java
index e547bde..0211ac5 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java
@@ -168,7 +168,9 @@
 
 	@Override
 	public boolean equals(Object obj) {
-		if (this == obj) return true;
+		if (this == obj) {
+			return true;
+		}
 		return (obj instanceof ExploratoryGitCreds && (this.compareTo((ExploratoryGitCreds) obj) == 0));
 
 	}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java
index b41f432..f4cffa3 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java
@@ -48,6 +48,7 @@
 		return this;
 	}
 
+	@Override
 	public ExploratoryImageDTO withEndpoint(String endpoint) {
 		this.endpoint = endpoint;
 		return this;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java
index 78f6e89..1d670a9 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java
@@ -77,4 +77,9 @@
 		setErrorMessage(errorMessage);
 		return this;
 	}
+
+	public LibInstallDTO withAddedPackages(List<String> addedPackages) {
+		setAddedPackages(addedPackages);
+		return this;
+	}
 }
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java
index c5d0016..7804b83 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java
@@ -26,7 +26,8 @@
 public enum LibStatus {
 	INSTALLING,
 	INSTALLED,
-	FAILED;
+	INVALID_VERSION,
+	INSTALLATION_ERROR;
 
 	@JsonCreator
 	public static LibStatus of(String status) {
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java
index 23039be..b8e4718 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.dto.project;
 
 import com.epam.dlab.dto.ResourceBaseDTO;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java
index c64c505..bae34a8 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.dto.project;
 
 import com.epam.dlab.dto.ResourceBaseDTO;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java b/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java
index d02ad3c..be4ea8e 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java
@@ -19,26 +19,29 @@
 
 package com.epam.dlab.model;
 
+import lombok.extern.slf4j.Slf4j;
+
 import javax.ws.rs.WebApplicationException;
 import java.util.ArrayList;
 
+@Slf4j
 public class StringList extends ArrayList<String> {
-    public StringList(String s) {
-        super();
+	public StringList(String s) {
+		super();
 
-        for (String v : s.split(",")) {
-            try {
-                add(v.trim());
-            } catch (Exception ex) {
-                ex.printStackTrace();
-                throw new WebApplicationException(400);
-            }
-        }
-        if (isEmpty())
-            throw new WebApplicationException(400);
-    }
+		for (String v : s.split(",")) {
+			try {
+				add(v.trim());
+			} catch (Exception e) {
+				log.error("Something went wrong. Reason {}", e.getMessage(), e);
+				throw new WebApplicationException(400);
+			}
+		}
+		if (isEmpty())
+			throw new WebApplicationException(400);
+	}
 
-    public static String valueOf(String s) {
-        return s;
-    }
+	public static String valueOf(String s) {
+		return s;
+	}
 }
\ No newline at end of file
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java b/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java
index 46c82f0..ede4e23 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java
@@ -28,12 +28,18 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-/** The line of billing report.
+/**
+ * The line of billing report.
  */
 public class ReportLine {
+	/** Patterns to calculate the type of resource in report line. */
+	private static final Pattern pInstancceId = Pattern.compile("^i-[a-z0-9]{17}$");
+	private static final Pattern pVolumeId = Pattern.compile("^vol-[a-z0-9]{17}$");
+	private static final Pattern pIpAddress = Pattern.compile("^[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}$");
+	private static final Pattern pClusterId = Pattern.compile("j-[A-Z0-9]{12,13}$");
+
 	public static final String FIELD_DLAB_ID = "dlab_id";
 	public static final String FIELD_USER_ID = "user";
-	public static final String FIELD_PROJECT = "project";
 	public static final String FIELD_USAGE_DATE = "usage_date";
 	public static final String FIELD_PRODUCT = "product";
 	public static final String FIELD_USAGE_TYPE = "usage_type";
@@ -160,13 +166,6 @@
 	public void setTags(LinkedHashMap<String, String> tags) {
 		this.tags = tags;
 	}
-
-	
-	/** Patterns to calculate the type of resource in report line. */
-	private static final Pattern pInstancceId = Pattern.compile("^i-[a-z0-9]{17}$");
-	private static final Pattern pVolumeId = Pattern.compile("^vol-[a-z0-9]{17}$");
-	private static final Pattern pIpAddress = Pattern.compile("^[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}$");
-	private static final Pattern pClusterId = Pattern.compile("j-[A-Z0-9]{12,13}$");
 	
 	/** Calculate and set the type of resource and resource id.
 	 * @throws ParseException */
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java b/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java
index 0ca4562..f40521c 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java
@@ -25,6 +25,8 @@
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
 
+import java.util.List;
+
 @Data
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class Library {
@@ -34,6 +36,10 @@
 	private final LibStatus status;
 	@JsonProperty("error_message")
 	private final String errorMessage;
+	@JsonProperty("available_versions")
+	private List<String> availableVersions;
+	@JsonProperty("add_pkgs")
+	private List<String> addedPackages;
 	private String resourceName;
 	private ResourceType type;
 
diff --git a/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java b/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java
index f48a5af..251902c 100644
--- a/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java
+++ b/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java
@@ -55,7 +55,7 @@
 		try {
 			Files.deleteIfExists(Paths.get(absolutePath));
 		} catch (IOException e) {
-			log.error("Problems occured with deleting file {} due to: {}", absolutePath, e.getLocalizedMessage());
+			log.error("Problems occured with deleting file {} due to: {}", absolutePath, e.getLocalizedMessage(), e);
 		}
 	}
 }
diff --git a/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java b/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java
index 5a2beeb..d3a44b2 100644
--- a/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java
+++ b/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java
@@ -20,6 +20,7 @@
 package com.epam.dlab.util;
 
 import com.epam.dlab.exceptions.DlabException;
+import lombok.extern.slf4j.Slf4j;
 
 import java.io.IOException;
 import java.net.JarURLConnection;
@@ -30,31 +31,32 @@
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
+@Slf4j
 public class ServiceUtils {
 
 	private static String includePath = null;
-	
+
 	static {
-        includePath = System.getenv("DLAB_CONF_DIR");
-        if ( includePath == null || includePath.isEmpty() ) {
-        	includePath = getUserDir();
-        }
+		includePath = System.getenv("DLAB_CONF_DIR");
+		if ( includePath == null || includePath.isEmpty() ) {
+			includePath = getUserDir();
+		}
 	}
-	
+
 	/* Return working directory.
 	 */
 	public static String getUserDir() {
 		return System.getProperty("user.dir");
 	}
-	
+
 	/** Return path to DLab configuration directory.
 	 * @return
 	 */
 	public static String getConfPath() {
-        return includePath;
+		return includePath;
 	}
-	
-	
+
+
 	/** Return manifest for given class or empty manifest if {@link JarFile#MANIFEST_NAME} not found.
 	 * @param clazz class.
 	 * @throws IOException
@@ -73,7 +75,7 @@
 		JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
 		return jarConnection.getManifest();
 	}
-	
+
 	/** Return manifest map for given class or empty map if manifest not found or cannot be read.
 	 * @param clazz class.
 	 */
@@ -89,13 +91,13 @@
 				map.put(key.toString(), (String) attributes.get(key));
 			}
 		} catch (IOException e) {
-			System.err.println("Cannot found or open manifest for class " + className);
+			log.error("Cannot found or open manifest for class {}", className, e);
 			throw new DlabException("Cannot read manifest file", e);
 		}
-		
+
 		return map;
 	}
-	
+
 	/** Print to standard output the manifest info about application. If parameter <b>args</b> is not
 	 * <b>null</b> and one or more arguments have value -v or --version then print version and return <b>true<b/>
 	 * otherwise <b>false</b>.
@@ -108,32 +110,32 @@
 		boolean result = false;
 		if (args != null) {
 			for (String arg : args) {
-	            if (arg.equals("-v") ||
-	            	arg.equals("--version")) {
-	            	result = true;
-	            }
-	        }
+				if ("-v".equals(arg) ||
+						"--version".equals(arg)) {
+					result = true;
+				}
+			}
 			if (!result) {
 				return result;
 			}
 		}
-		
+
 		Map<String, String> manifest = getManifest(mainClass);
 		if (manifest.isEmpty()) {
 			return result;
 		}
-		
-		System.out.println("Title       " + manifest.get("Implementation-Title"));
-		System.out.println("Version     " + manifest.get("Implementation-Version"));
-		System.out.println("Created By  " + manifest.get("Created-By"));
-		System.out.println("Vendor      " + manifest.get("Implementation-Vendor"));
-		System.out.println("GIT-Branch  " + manifest.get("GIT-Branch"));
-		System.out.println("GIT-Commit  " + manifest.get("GIT-Commit"));
-		System.out.println("Build JDK   " + manifest.get("Build-Jdk"));
-		System.out.println("Build OS    " + manifest.get("Build-OS"));
-		System.out.println("Built Time  " + manifest.get("Build-Time"));
-		System.out.println("Built By    " + manifest.get("Built-By"));
-		
+
+		log.info("Title       {}", manifest.get("Implementation-Title"));
+		log.info("Version     {}", manifest.get("Implementation-Version"));
+		log.info("Created By  {}", manifest.get("Created-By"));
+		log.info("Vendor      {}", manifest.get("Implementation-Vendor"));
+		log.info("GIT-Branch  {}", manifest.get("GIT-Branch"));
+		log.info("GIT-Commit  {}", manifest.get("GIT-Commit"));
+		log.info("Build JDK   {}", manifest.get("Build-Jdk"));
+		log.info("Build OS    {}", manifest.get("Build-OS"));
+		log.info("Built Time  {}", manifest.get("Build-Time"));
+		log.info("Built By    {}", manifest.get("Built-By"));
+
 		return result;
 	}
 }
diff --git a/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java b/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java
index 9622661..4d1092c 100644
--- a/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java
+++ b/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java
@@ -23,6 +23,9 @@
 
 	private static final String UNDERLINE = "_";
 
+	private UsernameUtils() {
+	}
+
 	public static String removeDomain(String username) {
 		return username != null ? username.replaceAll("@.*", "") : null;
 	}
@@ -30,7 +33,4 @@
 	public static String replaceWhitespaces(String username) {
 		return username.replaceAll("\\s", UNDERLINE);
 	}
-
-	private UsernameUtils() {
-	}
 }
diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java
index 8aa9eb2..ba2adca 100644
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java
+++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java
@@ -20,22 +20,22 @@
 package com.epam.dlab;
 
 import com.google.inject.AbstractModule;
-
 import io.dropwizard.setup.Environment;
 
-/** The base class for an application configuration of service.
+/**
+ * The base class for an application configuration of service.
  */
-abstract public class ModuleBase<T extends ServiceConfiguration> extends AbstractModule {
+public abstract class ModuleBase<T extends ServiceConfiguration> extends AbstractModule {
 	/** Application configuration of service. */
-    protected T configuration;
-    /** Environment of service. */
-    protected Environment environment;
+	protected T configuration;
+	/** Environment of service. */
+	protected Environment environment;
 
-    /** Instantiates an application configuration of service.
-     * @param configuration application configuration of service.
-     * @param environment environment of service.
-     */
-    public ModuleBase(T configuration, Environment environment) {
+	/** Instantiates an application configuration of service.
+	 * @param configuration application configuration of service.
+	 * @param environment environment of service.
+	 */
+	public ModuleBase(T configuration, Environment environment) {
         this.configuration = configuration;
         this.environment = environment;
     }
diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
index 5c6a74f..c4b0f53 100644
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
+++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
@@ -25,7 +25,13 @@
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 import java.security.Principal;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class UserInfo implements Principal {
@@ -154,21 +160,36 @@
 
     @Override
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+	    if (this == o) {
+		    return true;
+	    }
+	    if (o == null || getClass() != o.getClass()) {
+		    return false;
+	    }
 
-        UserInfo userInfo = (UserInfo) o;
+	    UserInfo userInfo = (UserInfo) o;
 
-        if (awsUser != userInfo.awsUser) return false;
-        if (username != null ? !username.equals(userInfo.username) : userInfo.username != null) return false;
-        if (accessToken != null ? !accessToken.equals(userInfo.accessToken) : userInfo.accessToken != null)
-            return false;
-        if (!roles.equals(userInfo.roles)) return false;
-        if (!keys.equals(userInfo.keys)) return false;
-        if (firstName != null ? !firstName.equals(userInfo.firstName) : userInfo.firstName != null) return false;
-        if (lastName != null ? !lastName.equals(userInfo.lastName) : userInfo.lastName != null) return false;
-        return remoteIp != null ? remoteIp.equals(userInfo.remoteIp) : userInfo.remoteIp == null;
-
+	    if (awsUser != userInfo.awsUser) {
+		    return false;
+	    }
+	    if (username != null ? !username.equals(userInfo.username) : userInfo.username != null) {
+		    return false;
+	    }
+	    if (accessToken != null ? !accessToken.equals(userInfo.accessToken) : userInfo.accessToken != null)
+		    return false;
+	    if (!roles.equals(userInfo.roles)) {
+		    return false;
+	    }
+	    if (!keys.equals(userInfo.keys)) {
+		    return false;
+	    }
+	    if (firstName != null ? !firstName.equals(userInfo.firstName) : userInfo.firstName != null) {
+		    return false;
+	    }
+	    if (lastName != null ? !lastName.equals(userInfo.lastName) : userInfo.lastName != null) {
+		    return false;
+	    }
+	    return remoteIp != null ? remoteIp.equals(userInfo.remoteIp) : userInfo.remoteIp == null;
     }
 
 
diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/contracts/EdgeAPI.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/contracts/EdgeAPI.java
deleted file mode 100644
index 2fce5cc..0000000
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/contracts/EdgeAPI.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.epam.dlab.rest.contracts;
-
-public interface EdgeAPI {
-	String EDGE = "infrastructure/edge";
-	String EDGE_CREATE = EDGE + "/create";
-	String EDGE_START = EDGE + "/start";
-	String EDGE_STOP = EDGE + "/stop";
-	String EDGE_TERMINATE = EDGE + "/terminate";
-}
diff --git a/services/provisioning-service/pom.xml b/services/provisioning-service/pom.xml
index 1db7308..0b62c36 100644
--- a/services/provisioning-service/pom.xml
+++ b/services/provisioning-service/pom.xml
@@ -180,6 +180,20 @@
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>**/*Configuration.*</exclude>
+                        <exclude>**/*Module.*</exclude>
+                        <exclude>**/*Form.*</exclude>
+                        <exclude>com/epam/dlab/process/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/modules/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/validation/**/*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 </project>
\ No newline at end of file
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java
index 9be4251..fc2659c 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi;
 
 import org.keycloak.adapters.AdapterDeploymentContext;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java
index 1025ad6..4edc8af 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java
@@ -20,6 +20,7 @@
 package com.epam.dlab.backendapi;
 
 import com.epam.dlab.ServiceConfiguration;
+import com.epam.dlab.backendapi.conf.CloudConfiguration;
 import com.epam.dlab.backendapi.core.Directories;
 import com.epam.dlab.backendapi.validation.ProvisioningServiceCloudConfigurationSequenceProvider;
 import com.epam.dlab.validation.AwsValidation;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/CloudConfiguration.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
similarity index 98%
rename from services/provisioning-service/src/main/java/com/epam/dlab/backendapi/CloudConfiguration.java
rename to services/provisioning-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
index 9d61210..c25624c 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/CloudConfiguration.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package com.epam.dlab.backendapi;
+package com.epam.dlab.backendapi.conf;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java
index 7ad52d7..defbeaf 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java
@@ -25,6 +25,7 @@
 
 import java.util.Set;
 
+@FunctionalInterface
 public interface MetadataHolder {
     Set<ImageMetadataDTO> getMetadata(ImageType metadataType);
 }
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java
index d8fb126..0adfaa9 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java
@@ -19,6 +19,7 @@
 
 package com.epam.dlab.backendapi.core.commands;
 
+@FunctionalInterface
 public interface CmdCommand {
     String toCMD();
 }
\ No newline at end of file
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java
index a212d0a..f99eca4 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java
@@ -19,8 +19,8 @@
 
 package com.epam.dlab.backendapi.core.commands;
 
-import com.epam.dlab.backendapi.CloudConfiguration;
 import com.epam.dlab.backendapi.ProvisioningServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.conf.CloudConfiguration;
 import com.epam.dlab.cloud.CloudProvider;
 import com.epam.dlab.dto.ResourceBaseDTO;
 import com.epam.dlab.dto.aws.AwsCloudSettings;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java
index 7277961..7ad66f8 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java
@@ -42,7 +42,14 @@
 import org.apache.commons.codec.Charsets;
 import org.apache.commons.lang3.StringUtils;
 
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.URL;
 import java.nio.file.Paths;
 import java.util.List;
@@ -355,7 +362,7 @@
 			if (isSuccess) {
 				lib.setStatus(LibStatus.INSTALLED.toString());
 			} else {
-				lib.setStatus(LibStatus.FAILED.toString());
+				lib.setStatus(LibStatus.INSTALLATION_ERROR.toString());
 				lib.setErrorMessage("Mock error message");
 			}
 		}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java
index ba72555..bb8fc03 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java
@@ -20,18 +20,19 @@
 
 package com.epam.dlab.backendapi.core.response.folderlistener;
 
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
 import com.epam.dlab.backendapi.core.FileHandlerCallback;
 import com.google.common.base.MoreObjects;
 import lombok.extern.slf4j.Slf4j;
 
-/** Class to store the file handler for processing.
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Class to store the file handler for processing.
  */
 @Slf4j
 public class WatchItem implements Comparable<WatchItem> {
-	
+
 	/** Status of file processing.
 	 * <pre>
 	 * WAIT_FOR_FILE waiting for the file creation.
@@ -149,9 +150,10 @@
 			} catch (InterruptedException e) {
     			Thread.currentThread().interrupt();
 				return ItemStatus.IS_INTERRUPTED;
-			} catch (ExecutionException e) {
-				return ItemStatus.IS_FAILED;
-			}
+		    } catch (ExecutionException e) {
+			    log.error("Execution exception occurred", e);
+			    return ItemStatus.IS_FAILED;
+		    }
     	}
     	
     	return ItemStatus.INPROGRESS;
@@ -182,7 +184,7 @@
 			try {
 				futureResult = future.get();
 			} catch (Exception e) {
-				log.error("Exception occurred during getting result: {}", e.getMessage());
+				log.error("Exception occurred during getting result: {}", e.getMessage(), e);
 			}
 		}
 		return futureResult; 
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java
index 688edb8..fa41998 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.core.response.handlers;
 
 import com.epam.dlab.backendapi.core.commands.DockerAction;
@@ -19,8 +38,8 @@
 	private final String endpointName;
 
 	public ProjectCallbackHandler(RESTService selfService, String user,
-								  String uuid, DockerAction action, String callbackUri, String projectName,
-								  Class<? extends EdgeInfo> clazz, String endpointName) {
+	                              String uuid, DockerAction action, String callbackUri, String projectName,
+	                              Class<? extends EdgeInfo> clazz, String endpointName) {
 		super(selfService, user, uuid, action);
 		this.callbackUri = callbackUri;
 		this.projectName = projectName;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java
index 846e0d7..268950a 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java
@@ -89,7 +89,7 @@
 					.ifPresent(FileUtils::deleteFile);
 		} catch (IOException e) {
 			log.error("Problem occurred with accessing directory {} due to: {}", configuration.getHandlerDirectory(),
-					e.getLocalizedMessage());
+					e.getLocalizedMessage(), e);
 		}
 	}
 
@@ -102,7 +102,7 @@
 			log.trace("Persisting callback handler to file {}", absolutePath);
 			Files.write(Paths.get(absolutePath), mapper.writeValueAsBytes(handlerCallback), StandardOpenOption.CREATE);
 		} catch (Exception e) {
-			log.warn("Can not persist file handler {} due to {}", fileName, e.getMessage());
+			log.warn("Can not persist file handler {} due to {}", fileName, e.getMessage(), e);
 		}
 	}
 
@@ -114,7 +114,7 @@
 		try {
 			return Optional.of(mapper.readValue(path.toFile(), PersistentFileHandler.class));
 		} catch (Exception e) {
-			log.warn("Can not deserialize file handler from file: {}", path.toString());
+			log.warn("Can not deserialize file handler from file: {}", path.toString(), e);
 		}
 		return Optional.empty();
 	}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
index 005ad9f..2113e8c 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources;
 
 import com.epam.dlab.auth.UserInfo;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java
index e50d7ae..a46171b 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java
@@ -34,8 +34,6 @@
 @Path("/healthcheck")
 @Produces(MediaType.APPLICATION_JSON)
 public class ProvisioningHealthCheckResource {
-    private static final String HEALTH_CHECK = "ProvisioningHealthCheck";
-
     @Inject
     private ProvisioningServiceApplicationConfiguration configuration;
 
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java
index 22c26e9..57956f3 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java
@@ -28,7 +28,6 @@
 import com.epam.dlab.dto.aws.edge.EdgeInfoAws;
 import com.epam.dlab.dto.aws.keyload.UploadFileAws;
 import com.epam.dlab.dto.base.keyload.UploadFileResult;
-import com.epam.dlab.rest.contracts.EdgeAPI;
 import com.epam.dlab.util.FileUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import io.dropwizard.auth.Auth;
@@ -41,12 +40,14 @@
 import javax.ws.rs.core.MediaType;
 import java.io.IOException;
 
-import static com.epam.dlab.rest.contracts.ApiCallbacks.*;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.EDGE;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.KEY_LOADER;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.STATUS_URI;
 
 /**
  * Provides API to manage Edge node on AWS
  */
-@Path(EdgeAPI.EDGE)
+@Path("infrastructure/edge")
 @Consumes(MediaType.APPLICATION_JSON)
 @Produces(MediaType.APPLICATION_JSON)
 @Slf4j
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java
index 4ebad5c..7781227 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java
@@ -28,7 +28,6 @@
 import com.epam.dlab.dto.azure.edge.EdgeInfoAzure;
 import com.epam.dlab.dto.azure.keyload.UploadFileAzure;
 import com.epam.dlab.dto.base.keyload.UploadFileResult;
-import com.epam.dlab.rest.contracts.EdgeAPI;
 import com.epam.dlab.util.FileUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import io.dropwizard.auth.Auth;
@@ -41,12 +40,14 @@
 import javax.ws.rs.core.MediaType;
 import java.io.IOException;
 
-import static com.epam.dlab.rest.contracts.ApiCallbacks.*;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.EDGE;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.KEY_LOADER;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.STATUS_URI;
 
 /**
  * Provides API to manage Edge node on Azure
  */
-@Path(EdgeAPI.EDGE)
+@Path("infrastructure/edge")
 @Consumes(MediaType.APPLICATION_JSON)
 @Produces(MediaType.APPLICATION_JSON)
 @Slf4j
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java
index 525e3e7..4509bff 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java
@@ -28,7 +28,6 @@
 import com.epam.dlab.dto.base.keyload.UploadFileResult;
 import com.epam.dlab.dto.gcp.edge.EdgeInfoGcp;
 import com.epam.dlab.dto.gcp.keyload.UploadFileGcp;
-import com.epam.dlab.rest.contracts.EdgeAPI;
 import com.epam.dlab.util.FileUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import io.dropwizard.auth.Auth;
@@ -41,12 +40,14 @@
 import javax.ws.rs.core.MediaType;
 import java.io.IOException;
 
-import static com.epam.dlab.rest.contracts.ApiCallbacks.*;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.EDGE;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.KEY_LOADER;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.STATUS_URI;
 
 /**
  * Provides API to manage Edge node on GCP
  */
-@Path(EdgeAPI.EDGE)
+@Path("infrastructure/edge")
 @Consumes(MediaType.APPLICATION_JSON)
 @Produces(MediaType.APPLICATION_JSON)
 @Slf4j
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
index 65d4b70..8770591 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java
index 3713589..59e67b4 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java
@@ -118,7 +118,7 @@
 			commandExecutor.executeAsync(userName, uuid, command);
 		} catch (Exception e) {
 			log.error("Exception occured during reuploading key: {} for command {}", e.getLocalizedMessage(),
-					dockerCmd.toCMD());
+					dockerCmd.toCMD(), e);
 		}
 	}
 
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java
index bbedc68..5d650da 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java
@@ -89,7 +89,7 @@
 			commandExecutor.executeAsync(userName, uuid, command);
 		} catch (Exception e) {
 			log.error("Exception occured during reuploading key: {} for command {}", e.getLocalizedMessage(),
-					runDockerCommand.toCMD());
+					runDockerCommand.toCMD(), e);
 		}
 	}
 
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
index 1daf93f..5f24a1e 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.auth.UserInfo;
@@ -29,16 +48,22 @@
 	private static final String PROJECT_IMAGE = "docker.dlab-project";
 	private static final String EDGE_IMAGE = "docker.dlab-edge";
 	private static final String CALLBACK_URI = "/api/project/status";
+
+	protected final RESTService selfService;
+	private final ProvisioningServiceApplicationConfiguration configuration;
+	private final FolderListenerExecutor folderListenerExecutor;
+	private final ICommandExecutor commandExecutor;
+	private final CommandBuilder commandBuilder;
+
 	@Inject
-	protected RESTService selfService;
-	@Inject
-	private ProvisioningServiceApplicationConfiguration configuration;
-	@Inject
-	private FolderListenerExecutor folderListenerExecutor;
-	@Inject
-	private ICommandExecutor commandExecutor;
-	@Inject
-	private CommandBuilder commandBuilder;
+	public ProjectServiceImpl(RESTService selfService, ProvisioningServiceApplicationConfiguration configuration,
+	                          FolderListenerExecutor folderListenerExecutor, ICommandExecutor commandExecutor, CommandBuilder commandBuilder) {
+		this.selfService = selfService;
+		this.configuration = configuration;
+		this.folderListenerExecutor = folderListenerExecutor;
+		this.commandExecutor = commandExecutor;
+		this.commandBuilder = commandBuilder;
+	}
 
 	@Override
 	public String create(UserInfo userInfo, ProjectCreateDTO dto) {
@@ -63,7 +88,7 @@
 	}
 
 	private String executeDocker(UserInfo userInfo, ResourceBaseDTO dto, DockerAction action, String projectName,
-								 String resourceType, String image, String endpoint) {
+	                             String resourceType, String image, String endpoint) {
 		String uuid = DockerCommands.generateUUID();
 
 		folderListenerExecutor.start(configuration.getKeyLoaderDirectory(),
@@ -92,7 +117,7 @@
 		try {
 			commandExecutor.executeAsync(userInfo.getName(), uuid, commandBuilder.buildCommand(runDockerCommand, dto));
 		} catch (JsonProcessingException e) {
-			e.printStackTrace();
+			log.error("Something went wrong. Reason {}", e.getMessage(), e);
 		}
 		return uuid;
 	}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java
index 79831a4..6c5673d 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java
@@ -48,19 +48,18 @@
 
     @Override
     public List<BucketDTO> getObjects(String bucket) {
-        try {
-            S3Client s3 = S3Client.create();
-            ListObjectsRequest getRequest = ListObjectsRequest
-                    .builder()
-                    .bucket(bucket)
-                    .build();
+        try (S3Client s3 = S3Client.create()) {
+	        ListObjectsRequest getRequest = ListObjectsRequest
+			        .builder()
+			        .bucket(bucket)
+			        .build();
 
-            return s3.listObjects(getRequest).contents()
-                    .stream()
-                    .map(o -> toBucketDTO(bucket, o))
-                    .collect(Collectors.toList());
+	        return s3.listObjects(getRequest).contents()
+			        .stream()
+			        .map(o -> toBucketDTO(bucket, o))
+			        .collect(Collectors.toList());
         } catch (Exception e) {
-            log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage());
+	        log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage()));
         }
     }
@@ -68,18 +67,17 @@
     @Override
     public void uploadObject(String bucket, String object, InputStream stream, String contentType, long fileSize) {
         log.info("Uploading file {} to bucket {}", object, bucket);
-        try {
-            S3Client s3 = S3Client.create();
-            PutObjectRequest uploadRequest = PutObjectRequest
-                    .builder()
-                    .bucket(bucket)
-                    .key(object)
-                    .contentType(contentType)
-                    .build();
-            s3.putObject(uploadRequest, RequestBody.fromInputStream(stream, fileSize));
-        } catch (Exception e) {
-            log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage());
-            throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
+	    try (S3Client s3 = S3Client.create()) {
+		    PutObjectRequest uploadRequest = PutObjectRequest
+				    .builder()
+				    .bucket(bucket)
+				    .key(object)
+				    .contentType(contentType)
+				    .build();
+		    s3.putObject(uploadRequest, RequestBody.fromInputStream(stream, fileSize));
+	    } catch (Exception e) {
+		    log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
+		    throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
         }
         log.info("Finished uploading file {} to bucket {}", object, bucket);
     }
@@ -87,60 +85,57 @@
     @Override
     public void uploadFolder(UserInfo userInfo, String bucket, String folder) {
         log.info("Uploading folder {} to bucket {}", folder, bucket);
-        try {
-            S3Client s3 = S3Client.create();
-            PutObjectRequest uploadRequest = PutObjectRequest
-                    .builder()
-                    .bucket(bucket)
-                    .key(folder)
-                    .build();
-            s3.putObject(uploadRequest, RequestBody.empty());
-        } catch (Exception e) {
-            log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage());
-            throw new DlabException(String.format("Cannot upload folder %s to bucket %s. Reason: %s", folder, bucket, e.getMessage()));
-        }
+	    try (S3Client s3 = S3Client.create()) {
+		    PutObjectRequest uploadRequest = PutObjectRequest
+				    .builder()
+				    .bucket(bucket)
+				    .key(folder)
+				    .build();
+		    s3.putObject(uploadRequest, RequestBody.empty());
+	    } catch (Exception e) {
+		    log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage(), e);
+		    throw new DlabException(String.format("Cannot upload folder %s to bucket %s. Reason: %s", folder, bucket, e.getMessage()));
+	    }
         log.info("Finished uploading folder {} to bucket {}", folder, bucket);
     }
 
     @Override
     public void downloadObject(String bucket, String object, HttpServletResponse resp) {
         log.info("Downloading file {} from bucket {}", object, bucket);
-        try (ServletOutputStream outputStream = resp.getOutputStream()) {
-            S3Client s3 = S3Client.create();
-            GetObjectRequest downloadRequest = GetObjectRequest
-                    .builder()
-                    .bucket(bucket)
-                    .key(object)
-                    .build();
-            s3.getObject(downloadRequest, ResponseTransformer.toOutputStream(outputStream));
-        } catch (Exception e) {
-            log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage());
-            throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
-        }
+	    try (ServletOutputStream outputStream = resp.getOutputStream(); S3Client s3 = S3Client.create()) {
+		    GetObjectRequest downloadRequest = GetObjectRequest
+				    .builder()
+				    .bucket(bucket)
+				    .key(object)
+				    .build();
+		    s3.getObject(downloadRequest, ResponseTransformer.toOutputStream(outputStream));
+	    } catch (Exception e) {
+		    log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
+		    throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
+	    }
         log.info("Finished downloading file {} from bucket {}", object, bucket);
     }
 
     @Override
     public void deleteObjects(String bucket, List<String> objects) {
-        try {
-            S3Client s3 = S3Client.create();
-            List<ObjectIdentifier> objectsToDelete = objects
-                    .stream()
-                    .map(o -> ObjectIdentifier.builder()
-                            .key(o)
-                            .build())
-                    .collect(Collectors.toList());
+	    try (S3Client s3 = S3Client.create()) {
+		    List<ObjectIdentifier> objectsToDelete = objects
+				    .stream()
+				    .map(o -> ObjectIdentifier.builder()
+						    .key(o)
+						    .build())
+				    .collect(Collectors.toList());
 
-            DeleteObjectsRequest deleteObjectsRequests = DeleteObjectsRequest.builder()
-                    .bucket(bucket)
-                    .delete(Delete.builder()
+		    DeleteObjectsRequest deleteObjectsRequests = DeleteObjectsRequest.builder()
+				    .bucket(bucket)
+				    .delete(Delete.builder()
                             .objects(objectsToDelete)
                             .build())
                     .build();
 
             s3.deleteObjects(deleteObjectsRequests);
         } catch (Exception e) {
-            log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage());
+		    log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot delete objects %s from bucket %s. Reason: %s", objects, bucket, e.getMessage()));
         }
     }
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java
index 3d1eec4..073aca2 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java
@@ -68,7 +68,7 @@
                     .map(blob -> toBucketDTO(account.getContainer(), blob))
                     .collect(Collectors.toList());
         } catch (Exception e) {
-            log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage());
+            log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage()));
         }
     }
@@ -83,7 +83,7 @@
             BlobClient blobClient = blobContainerClient.getBlobClient(object);
             blobClient.upload(stream, fileSize);
         } catch (Exception e) {
-            log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage());
+	        log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
         }
         log.info("Finished uploading file {} to bucket {}", object, bucket);
@@ -104,7 +104,7 @@
             BlobClient blobClient = blobContainerClient.getBlobClient(object);
             blobClient.download(outputStream);
         } catch (Exception e) {
-            log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage());
+	        log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
         }
         log.info("Finished downloading file {} from bucket {}", object, bucket);
@@ -118,7 +118,7 @@
             BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(account.getContainer());
             objects.forEach(object -> blobContainerClient.getBlobClient(object).delete());
         } catch (Exception e) {
-            log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage());
+	        log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot delete objects %s from bucket %s. Reason: %s", objects, bucket, e.getMessage()));
         }
     }
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java
index 2f0b15a..4a28bf6 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java
@@ -52,7 +52,7 @@
                     .map(this::toBucketDTO)
                     .collect(Collectors.toList());
         } catch (Exception e) {
-            log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage());
+            log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage()));
         }
     }
@@ -68,7 +68,7 @@
                     .build();
             storage.create(blobInfo, stream);
         } catch (Exception e) {
-            log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage());
+	        log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
         }
         log.info("Finished uploading file {} to bucket {}", object, bucket);
@@ -83,7 +83,7 @@
             BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
             storage.create(blobInfo);
         } catch (Exception e) {
-            log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage());
+	        log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot upload folder %s to bucket %s. Reason: %s", folder, bucket, e.getMessage()));
         }
         log.info("Finished uploading folder {} to bucket {}", folder, bucket);
@@ -98,7 +98,7 @@
             blob.downloadTo(outputStream);
             log.info("Finished downloading file {} from bucket {}", object, bucket);
         } catch (Exception e) {
-            log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage());
+	        log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
         }
         log.info("Finished downloading file {} from bucket {}", object, bucket);
@@ -114,7 +114,7 @@
                     .collect(Collectors.toList());
             storage.delete(blobIds);
         } catch (Exception e) {
-            log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage());
+	        log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage(), e);
             throw new DlabException(String.format("Cannot delete objects %s from bucket %s. Reason: %s", objects, bucket, e.getMessage()));
         }
     }
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java b/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java
index f790fea..15a0e1e 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java
@@ -38,7 +38,16 @@
 import java.util.function.Function;
 import java.util.function.Supplier;
 
-import static com.epam.dlab.process.model.ProcessStatus.*;
+import static com.epam.dlab.process.model.ProcessStatus.CREATED;
+import static com.epam.dlab.process.model.ProcessStatus.FAILED;
+import static com.epam.dlab.process.model.ProcessStatus.FINISHED;
+import static com.epam.dlab.process.model.ProcessStatus.KILLED;
+import static com.epam.dlab.process.model.ProcessStatus.LAUNCHING;
+import static com.epam.dlab.process.model.ProcessStatus.REJECTED;
+import static com.epam.dlab.process.model.ProcessStatus.RUNNING;
+import static com.epam.dlab.process.model.ProcessStatus.SCHEDULED;
+import static com.epam.dlab.process.model.ProcessStatus.STOPPED;
+import static com.epam.dlab.process.model.ProcessStatus.TIMEOUT;
 
 @Slf4j
 public class ProcessInfoBuilder implements Supplier<ProcessInfo>, Testing, TimeoutAction, Expireable {
@@ -168,7 +177,7 @@
 			try {
 				future.get();
 			} catch (Exception e) {
-				log.error("Exception occurred during getting future result: {}", e.getMessage());
+				log.error("Exception occurred during getting future result: {}", e.getMessage(), e);
 			}
 		});
 	}
@@ -267,14 +276,14 @@
 					try {
 						return fPid.getInt(p);
 					} catch (IllegalAccessException e) {
-						log.error("Unable to access PID. {}", e.getMessage());
+						log.error("Unable to access PID. {}", e.getMessage(), e);
 						return -1;
 					}
 				};
 			}
 			return pidSupplier.apply(process);
 		} catch (NoSuchFieldException e) {
-			log.debug("PID field not found");
+			log.debug("PID field not found", e);
 			pidSupplier = p -> -1;
 			return -1;
 		}
diff --git a/services/self-service/entrypoint.sh b/services/self-service/entrypoint.sh
index ba2d35e..c3c47fd 100644
--- a/services/self-service/entrypoint.sh
+++ b/services/self-service/entrypoint.sh
@@ -1,5 +1,26 @@
 #!/bin/sh
 
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
 checkfile () {
 if [ -s /root/step-certs/ca.crt ]
 then
diff --git a/services/self-service/pom.xml b/services/self-service/pom.xml
index f21caf9..b5c075b 100644
--- a/services/self-service/pom.xml
+++ b/services/self-service/pom.xml
@@ -257,6 +257,17 @@
                         <exclude>**/*Module.*</exclude>
                         <exclude>**/*Form.*</exclude>
                         <exclude>com/epam/dlab/dto/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/auth/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/conf/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/domain/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/dropwizard/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/healthcheck/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/modules/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/resources/dto/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/roles/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/servlet/guacamole/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/util/**/*</exclude>
+                        <exclude>com/epam/dlab/backendapi/validation/**/*</exclude>
                     </excludes>
                 </configuration>
             </plugin>
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java
index 5a1e5d4..0ce3414 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.annotation;
 
 import java.lang.annotation.ElementType;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java
index 5c24010..4b39290 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java
@@ -1,15 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.auth;
 
 import com.epam.dlab.auth.UserInfo;
 import de.ahus1.keycloak.dropwizard.AbstractKeycloakAuthenticator;
 import de.ahus1.keycloak.dropwizard.KeycloakConfiguration;
-import io.dropwizard.auth.AuthenticationException;
 import org.keycloak.KeycloakSecurityContext;
 import org.keycloak.representations.AccessToken;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.List;
-import java.util.Optional;
 
 import static java.util.Collections.emptyList;
 
@@ -22,16 +39,10 @@
 	}
 
 	@Override
-	public Optional<UserInfo> authenticate(HttpServletRequest request) throws AuthenticationException {
-		return super.authenticate(request);
-
-	}
-
-	@Override
 	@SuppressWarnings("unchecked")
 	protected UserInfo prepareAuthentication(KeycloakSecurityContext keycloakSecurityContext,
-											 HttpServletRequest httpServletRequest,
-											 KeycloakConfiguration keycloakConfiguration) {
+	                                         HttpServletRequest httpServletRequest,
+	                                         KeycloakConfiguration keycloakConfiguration) {
 		final AccessToken token = keycloakSecurityContext.getToken();
 		final UserInfo userInfo = new UserInfo(token.getPreferredUsername(),
 				keycloakSecurityContext.getTokenString());
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java
index 8c72669..df6f5fa 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.auth.filters;
 
 import org.keycloak.adapters.AdapterDeploymentContext;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
index bdc6ba5..2693e4b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
@@ -1,9 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.conf;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 @Data
 public class CloudConfiguration {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java
index b252de9..212d565 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.conf;
 
 import lombok.Data;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
index 1106fdb..9886449 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
@@ -57,7 +57,7 @@
 import static com.mongodb.client.model.Filters.lte;
 
 public class AuditDAOImpl extends BaseDAO implements AuditDAO {
-    private final static String AUDIT_COLLECTION = "audit";
+    private static final String AUDIT_COLLECTION = "audit";
     private static final String RESOURCE_NAME_FIELD = "resourceName";
     private static final String RESOURCE_TYPE_FIELD = "type";
     private static final String TIMESTAMP_FIELD = "timestamp";
@@ -86,8 +86,8 @@
             countPipeline.add(match);
         }
         countPipeline.add(count());
-        valuesPipeline.addAll(Arrays.asList(skip(pageSize * (pageNumber - 1)), limit(pageSize)));
         valuesPipeline.add(sortCriteria());
+        valuesPipeline.addAll(Arrays.asList(skip(pageSize * (pageNumber - 1)), limit(pageSize)));
 
         List<Bson> userFilter = Collections.singletonList(group(getGroupingFields(USER)));
         List<Bson> projectFilter = Collections.singletonList(group(getGroupingFields(PROJECT)));
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAO.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAO.java
index e48c5ea..1a2a11c 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAO.java
@@ -26,7 +26,7 @@
 import java.util.List;
 import java.util.Optional;
 
-public interface BackupDao {
+public interface BackupDAO {
 	void createOrUpdate(EnvBackupDTO dto, String user, EnvBackupStatus status);
 
 	List<BackupInfoRecord> getBackups(String userName);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAOImpl.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAOImpl.java
index f1b599c..4ed2788 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAOImpl.java
@@ -34,7 +34,7 @@
 import static com.mongodb.client.model.Filters.eq;
 
 @Singleton
-public class BackupDaoImpl extends BaseDAO implements BackupDao {
+public class BackupDAOImpl extends BaseDAO implements BackupDAO {
 	@Override
 	public void createOrUpdate(EnvBackupDTO dto, String user, EnvBackupStatus status) {
 		final Document idField = backupId(user, dto.getId());
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
index 7975eeb..56a77a0 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
@@ -25,6 +25,7 @@
 import com.google.inject.Inject;
 import com.mongodb.client.model.Aggregates;
 import com.mongodb.client.model.Filters;
+import com.mongodb.client.model.Sorts;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -48,6 +49,7 @@
 import static com.mongodb.client.model.Accumulators.sum;
 import static com.mongodb.client.model.Aggregates.group;
 import static com.mongodb.client.model.Aggregates.match;
+import static com.mongodb.client.model.Aggregates.sort;
 import static com.mongodb.client.model.Filters.and;
 import static com.mongodb.client.model.Filters.eq;
 import static com.mongodb.client.model.Filters.gte;
@@ -152,6 +154,7 @@
 			pipeline.add(Aggregates.match(Filters.and(matchCriteria)));
 		}
 		pipeline.add(groupCriteria());
+		pipeline.add(usageDateSort());
 		return StreamSupport.stream(getCollection(BILLING).aggregate(pipeline).spliterator(), false)
 				.map(this::toBillingReport)
 				.collect(Collectors.toList());
@@ -187,6 +190,10 @@
 				.orElse(BigDecimal.ZERO.doubleValue());
 	}
 
+	private Bson usageDateSort() {
+		return sort(Sorts.descending(USAGE_DATE));
+	}
+
 	private Bson groupCriteria() {
 		return group(getGroupingFields(USER, DLAB_ID, RESOURCE_TYPE, RESOURCE_NAME, PROJECT, PRODUCT, CURRENCY, SHAPE, EXPLORATORY),
 				sum(COST, "$" + COST),
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java
index 7fbb47a..d96f069 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java
@@ -22,6 +22,7 @@
 import com.epam.dlab.backendapi.util.DateRemoverUtil;
 import com.epam.dlab.dto.exploratory.LibInstallDTO;
 import com.epam.dlab.dto.exploratory.LibInstallStatusDTO;
+import com.epam.dlab.dto.exploratory.LibStatus;
 import com.epam.dlab.exceptions.DlabException;
 import com.epam.dlab.model.ResourceType;
 import com.epam.dlab.model.library.Library;
@@ -394,6 +395,7 @@
 		return ((List<Document>) libsDocument.getOrDefault(libFieldName, Collections.emptyList()))
 				.stream()
 				.map(d -> convertFromDocument(d, Library.class))
+				.filter(library -> LibStatus.INVALID_VERSION != library.getStatus())
 				.peek(l -> l.withType(libType).withResourceName(resourceName));
 	}
 }
\ No newline at end of file
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAO.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAO.java
index 2665d47..9bab74d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAO.java
@@ -28,7 +28,7 @@
 import java.util.List;
 import java.util.Optional;
 
-public interface ImageExploratoryDao {
+public interface ImageExploratoryDAO {
 
 	boolean exist(String image, String project);
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAOImpl.java
similarity index 90%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAOImpl.java
index 808dfbe..7aadcc4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAOImpl.java
@@ -28,15 +28,23 @@
 import org.bson.Document;
 import org.bson.conversions.Bson;
 
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
-import static com.mongodb.client.model.Filters.*;
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.in;
 import static com.mongodb.client.model.Projections.elemMatch;
-import static com.mongodb.client.model.Projections.*;
+import static com.mongodb.client.model.Projections.excludeId;
+import static com.mongodb.client.model.Projections.fields;
+import static com.mongodb.client.model.Projections.include;
 
 @Singleton
-public class ImageExploratoryDaoImpl extends BaseDAO implements ImageExploratoryDao {
+public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratoryDAO {
 
 	private static final String LIBRARIES = "libraries";
 	private static final String IMAGE_NAME = "name";
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java
index 9b7f0a0..24850cb 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.dao;
 
 import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java
index d438eb5..f08e3a3 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.dao;
 
 import com.epam.dlab.auth.UserInfo;
@@ -40,10 +59,10 @@
 	private static final String ENDPOINT_FIELD = "endpoints.$.";
 	private static final String ANYUSER = Pattern.quote("$anyuser");
 
-	private final UserGroupDao userGroupDao;
+	private final UserGroupDAO userGroupDao;
 
 	@Inject
-	public ProjectDAOImpl(UserGroupDao userGroupDao) {
+	public ProjectDAOImpl(UserGroupDAO userGroupDao) {
 		this.userGroupDao = userGroupDao;
 	}
 
@@ -56,15 +75,18 @@
 	@Override
 	public List<ProjectDTO> getProjectsWithEndpointStatusNotIn(UserInstanceStatus... statuses) {
 		final List<String> statusList =
-				Arrays.stream(statuses).map(UserInstanceStatus::name).collect(Collectors.toList());
+				Arrays.stream(statuses)
+						.map(UserInstanceStatus::name)
+						.collect(Collectors.toList());
 
 		return find(PROJECTS_COLLECTION, not(in(ENDPOINT_STATUS_FIELD, statusList)), ProjectDTO.class);
 	}
 
 	@Override
 	public List<ProjectDTO> getUserProjects(UserInfo userInfo, boolean active) {
-		final Set<String> groups = Stream.concat(userGroupDao.getUserGroups(userInfo.getName()).stream(),
-				userInfo.getRoles().stream())
+		Stream<String> userGroups = userGroupDao.getUserGroups(userInfo.getName()).stream();
+		Stream<String> roles = userInfo.getRoles().stream();
+		final Set<String> groups = Stream.concat(userGroups, roles)
 				.collect(Collectors.toSet());
 		return find(PROJECTS_COLLECTION, userProjectCondition(groups, active), ProjectDTO.class);
 	}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java
index 0c76422..a0ec24f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java
@@ -20,10 +20,8 @@
 package com.epam.dlab.backendapi.dao;
 
 import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.auth.dto.UserCredentialDTO;
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.exceptions.DlabException;
-import com.epam.dlab.util.UsernameUtils;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.mongodb.client.FindIterable;
@@ -31,35 +29,35 @@
 import org.bson.Document;
 import org.keycloak.representations.AccessTokenResponse;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 
-import static com.epam.dlab.backendapi.dao.MongoCollections.LOGIN_ATTEMPTS;
 import static com.epam.dlab.backendapi.dao.MongoCollections.ROLES;
-import static com.mongodb.client.model.Filters.*;
-import static com.mongodb.client.model.Projections.*;
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.gte;
+import static com.mongodb.client.model.Filters.ne;
+import static com.mongodb.client.model.Projections.exclude;
+import static com.mongodb.client.model.Projections.fields;
+import static com.mongodb.client.model.Projections.include;
 
 /**
  * DAO write the attempt of user login into DLab.
  */
 @Singleton
 public class SecurityDAO extends BaseDAO {
+	private static final String SECURITY_COLLECTION = "security";
+	private static final String TOKEN_RESPONSE = "tokenResponse";
+	private static final String LAST_ACCESS = "last_access";
 
 	@Inject
 	private SelfServiceApplicationConfiguration conf;
-	private static final String SECURITY_COLLECTION = "security";
-	private static final String TOKEN_RESPONSE = "tokenResponse";
-
-	/**
-	 * Write the attempt of user login into Mongo database.
-	 *
-	 * @param credentials user credentials.
-	 */
-	public void writeLoginAttempt(UserCredentialDTO credentials) {
-		insertOne(LOGIN_ATTEMPTS,
-				() -> new Document("login", credentials.getUsername()).append("iamlogin", UsernameUtils.removeDomain
-						(credentials.getUsername())));
-	}
 
 	/**
 	 * Return the roles or throw exception if roles collection does not exists.
@@ -83,7 +81,7 @@
 						new Document()
 								.append(ID, userName)
 								.append("created", new Date())
-								.append("last_access", new Date())
+								.append(LAST_ACCESS, new Date())
 								.append(TOKEN_RESPONSE, convertToBson(accessTokenResponse))),
 				true);
 	}
@@ -93,15 +91,15 @@
 				new Document(SET,
 						new Document()
 								.append(ID, userName)
-								.append("last_access", new Date())
+								.append(LAST_ACCESS, new Date())
 								.append(TOKEN_RESPONSE, convertToBson(accessTokenResponse))));
 	}
 
 	public Optional<UserInfo> getUser(String token) {
 		return Optional.ofNullable(mongoService.getCollection(SECURITY_COLLECTION)
-				.findOneAndUpdate(and(eq(TOKEN_RESPONSE + ".access_token", token), gte("last_access",
+				.findOneAndUpdate(and(eq(TOKEN_RESPONSE + ".access_token", token), gte(LAST_ACCESS,
 						new Date(new Date().getTime() - conf.getInactiveUserTimeoutMillSec()))), new Document("$set",
-						new Document("last_access", new Date()))))
+						new Document(LAST_ACCESS, new Date()))))
 				.map(d -> new UserInfo(d.getString(ID), token));
 	}
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAO.java
similarity index 93%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAO.java
index 85ec7ae..9d6b72b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAO.java
@@ -20,7 +20,7 @@
 
 import java.util.Set;
 
-public interface UserGroupDao {
+public interface UserGroupDAO {
 	void addUsers(String group, Set<String> users);
 
 	void updateUsers(String group, Set<String> users);
@@ -29,5 +29,5 @@
 
 	Set<String> getUserGroups(String user);
 
-    Set<String> getUsers(String group);
+	Set<String> getUsers(String group);
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAOImpl.java
similarity index 96%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAOImpl.java
index ac66946..39fc11a 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAOImpl.java
@@ -32,7 +32,7 @@
 import static com.mongodb.client.model.Filters.eq;
 
 @Singleton
-public class UserGroupDaoImpl extends BaseDAO implements UserGroupDao {
+public class UserGroupDAOImpl extends BaseDAO implements UserGroupDAO {
 
 	private static final String USERS_FIELD = "users";
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAO.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAO.java
index 48abb54..5de090c 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAO.java
@@ -26,7 +26,7 @@
 import java.util.List;
 import java.util.Set;
 
-public interface UserRoleDao {
+public interface UserRoleDAO {
 	List<UserRoleDto> findAll();
 
 	void insert(UserRoleDto dto);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAOImpl.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAOImpl.java
index e95a41b..2eced33 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAOImpl.java
@@ -27,6 +27,7 @@
 import com.google.inject.Singleton;
 import com.mongodb.client.model.BsonField;
 import com.mongodb.client.result.UpdateResult;
+import lombok.extern.slf4j.Slf4j;
 import org.bson.Document;
 import org.bson.conversions.Bson;
 
@@ -53,7 +54,8 @@
 import static java.util.stream.Collectors.toList;
 
 @Singleton
-public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao {
+@Slf4j
+public class UserRoleDAOImpl extends BaseDAO implements UserRoleDAO {
 	private static final ObjectMapper MAPPER = new ObjectMapper();
 	private static final String[] DEFAULT_AWS_SHAPES = {"nbShapes_t2.medium_fetching", "compShapes_c4.xlarge_fetching"};
 	private static final String[] DEFAULT_GCP_SHAPES = {"compShapes_n1-standard-2_fetching", "nbShapes_n1-standard-2_fetching"};
@@ -177,6 +179,7 @@
 			return MAPPER.readValue(is, new TypeReference<List<UserRoleDto>>() {
 			});
 		} catch (IOException e) {
+			log.error("Can not marshall dlab roles due to: {}", e.getMessage(), e);
 			throw new IllegalStateException("Can not marshall dlab roles due to: " + e.getMessage());
 		}
 	}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java
index dafb21f..b92d480 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.domain;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java
index f288a68..fcf2475 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java
@@ -24,7 +24,6 @@
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
 import org.hibernate.validator.constraints.NotBlank;
-import org.hibernate.validator.constraints.NotEmpty;
 import org.hibernate.validator.constraints.URL;
 
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java
index 32e67ec..a8b30f2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.domain;
 
 import com.epam.dlab.dto.UserInstanceStatus;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java
index 5a2f2ba..66b1dac 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.domain;
 
 import com.epam.dlab.dto.UserInstanceStatus;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java
index bf94438..472d34b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.domain;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java
index e4070bb..4622ac5 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.domain;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java
index 5089c1c..b963160 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.dropwizard.bundles;
 
 import com.epam.dlab.auth.UserInfo;
@@ -9,7 +28,6 @@
 import de.ahus1.keycloak.dropwizard.KeycloakConfiguration;
 import io.dropwizard.auth.Authenticator;
 import io.dropwizard.auth.Authorizer;
-import io.dropwizard.setup.Environment;
 
 import java.security.Principal;
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java
index d25e2dd..d029e86 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java
@@ -1,9 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.dropwizard.listeners;
 
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.EndpointDAO;
 import com.epam.dlab.backendapi.dao.SettingsDAO;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
 import com.epam.dlab.backendapi.resources.dto.UserRoleDto;
 import com.epam.dlab.cloud.CloudProvider;
 import com.fasterxml.jackson.core.type.TypeReference;
@@ -32,14 +51,14 @@
 
 	private static final String ROLES_FILE_FORMAT = "/mongo/%s/mongo_roles.json";
 	private static final ObjectMapper MAPPER = new ObjectMapper();
-	private final UserRoleDao userRoleDao;
+	private final UserRoleDAO userRoleDao;
 	private final SelfServiceApplicationConfiguration configuration;
 	private final SettingsDAO settingsDAO;
 	private final EndpointDAO endpointDAO;
 
 	@Inject
-	public MongoStartupListener(UserRoleDao userRoleDao, SelfServiceApplicationConfiguration configuration,
-								SettingsDAO settingsDAO, EndpointDAO endpointDAO) {
+	public MongoStartupListener(UserRoleDAO userRoleDao, SelfServiceApplicationConfiguration configuration,
+	                            SettingsDAO settingsDAO, EndpointDAO endpointDAO) {
 		this.userRoleDao = userRoleDao;
 		this.configuration = configuration;
 		this.settingsDAO = settingsDAO;
@@ -71,7 +90,7 @@
 			return MAPPER.readValue(is, new TypeReference<List<UserRoleDto>>() {
 			});
 		} catch (IOException e) {
-			log.error("Can not marshall dlab roles due to: {}", e.getMessage());
+			log.error("Can not marshall dlab roles due to: {}", e.getMessage(), e);
 			throw new IllegalStateException("Can not marshall dlab roles due to: " + e.getMessage());
 		}
 	}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java
index 0de166c..a92cae5 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java
@@ -44,7 +44,7 @@
 			endpointService.getEndpointsWithStatus(EndpointDTO.EndpointStatus.ACTIVE)
 					.forEach(e -> provisioningService.post(e.getUrl() + "/handler/restore", StringUtils.EMPTY, Object.class));
 		} catch (Exception e) {
-			log.error("Exception occurred during restore handler request: {}", e.getMessage());
+			log.error("Exception occurred during restore handler request: {}", e.getMessage(), e);
 		}
 	}
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java
index 262671c..5ce1b28 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java
@@ -38,7 +38,7 @@
 		try {
 			mongoService.ping();
 		} catch (Exception e) {
-			log.error("Mongo is unavailable {}", e.getMessage());
+			log.error("Mongo is unavailable {}", e.getMessage(), e);
 			return Result.unhealthy(e.getMessage());
 		}
 		return Result.healthy();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java
index ce32e10..a9058bd 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java
@@ -19,7 +19,6 @@
 
 package com.epam.dlab.backendapi.interceptor;
 
-import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.annotation.Project;
 import com.epam.dlab.backendapi.dao.BillingDAO;
 import com.epam.dlab.backendapi.service.BillingService;
@@ -31,7 +30,6 @@
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
-import java.util.Arrays;
 import java.util.Objects;
 import java.util.stream.IntStream;
 
@@ -53,15 +51,6 @@
 		}
 	}
 
-	private Boolean userQuoteReached(MethodInvocation mi) {
-		return Arrays.stream(mi.getArguments())
-				.filter(arg -> arg.getClass().equals(UserInfo.class))
-				.findAny()
-				.map(u -> ((UserInfo) u).getName())
-				.map(billingDAO::isUserQuoteReached)
-				.orElse(Boolean.FALSE);
-	}
-
 	private Boolean projectQuoteReached(MethodInvocation mi) {
 
 		final Parameter[] parameters = mi.getMethod().getParameters();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java
index 5c8f9bf..c0c0912 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java
@@ -25,20 +25,20 @@
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.AuditDAO;
 import com.epam.dlab.backendapi.dao.AuditDAOImpl;
-import com.epam.dlab.backendapi.dao.BackupDao;
-import com.epam.dlab.backendapi.dao.BackupDaoImpl;
+import com.epam.dlab.backendapi.dao.BackupDAO;
+import com.epam.dlab.backendapi.dao.BackupDAOImpl;
 import com.epam.dlab.backendapi.dao.BaseBillingDAO;
 import com.epam.dlab.backendapi.dao.BillingDAO;
 import com.epam.dlab.backendapi.dao.EndpointDAO;
 import com.epam.dlab.backendapi.dao.EndpointDAOImpl;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDaoImpl;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAOImpl;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
 import com.epam.dlab.backendapi.dao.ProjectDAOImpl;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserGroupDaoImpl;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
-import com.epam.dlab.backendapi.dao.UserRoleDaoImpl;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserGroupDAOImpl;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAOImpl;
 import com.epam.dlab.backendapi.service.AccessKeyService;
 import com.epam.dlab.backendapi.service.ApplicationSettingService;
 import com.epam.dlab.backendapi.service.ApplicationSettingServiceImpl;
@@ -145,9 +145,9 @@
 				.toInstance(configuration.getBillingFactory()
 						.build(environment, ServiceConsts.BILLING_SERVICE_NAME));
 		bind(ImageExploratoryService.class).to(ImageExploratoryServiceImpl.class);
-		bind(ImageExploratoryDao.class).to(ImageExploratoryDaoImpl.class);
+		bind(ImageExploratoryDAO.class).to(ImageExploratoryDAOImpl.class);
 		bind(BackupService.class).to(BackupServiceImpl.class);
-		bind(BackupDao.class).to(BackupDaoImpl.class);
+		bind(BackupDAO.class).to(BackupDAOImpl.class);
 		bind(ExploratoryService.class).to(ExploratoryServiceImpl.class);
 		bind(TagService.class).to(TagServiceImpl.class);
 		bind(InactivityService.class).to(InactivityServiceImpl.class);
@@ -166,8 +166,8 @@
 		bind(SystemInfoService.class).to(SystemInfoServiceImpl.class);
 		bind(UserGroupService.class).to(UserGroupServiceImpl.class);
 		bind(UserRoleService.class).to(UserRoleServiceImpl.class);
-		bind(UserRoleDao.class).to(UserRoleDaoImpl.class);
-		bind(UserGroupDao.class).to(UserGroupDaoImpl.class);
+		bind(UserRoleDAO.class).to(UserRoleDAOImpl.class);
+		bind(UserGroupDAO.class).to(UserGroupDAOImpl.class);
 		bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class);
 		bind(UserSettingService.class).to(UserSettingServiceImpl.class);
 		bind(GuacamoleService.class).to(GuacamoleServiceImpl.class);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java
index 901a61f..2581026 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java
@@ -24,20 +24,20 @@
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.AuditDAO;
 import com.epam.dlab.backendapi.dao.AuditDAOImpl;
-import com.epam.dlab.backendapi.dao.BackupDao;
-import com.epam.dlab.backendapi.dao.BackupDaoImpl;
+import com.epam.dlab.backendapi.dao.BackupDAO;
+import com.epam.dlab.backendapi.dao.BackupDAOImpl;
 import com.epam.dlab.backendapi.dao.BaseBillingDAO;
 import com.epam.dlab.backendapi.dao.BillingDAO;
 import com.epam.dlab.backendapi.dao.EndpointDAO;
 import com.epam.dlab.backendapi.dao.EndpointDAOImpl;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDaoImpl;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAOImpl;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
 import com.epam.dlab.backendapi.dao.ProjectDAOImpl;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserGroupDaoImpl;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
-import com.epam.dlab.backendapi.dao.UserRoleDaoImpl;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserGroupDAOImpl;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAOImpl;
 import com.epam.dlab.backendapi.service.AccessKeyService;
 import com.epam.dlab.backendapi.service.ApplicationSettingService;
 import com.epam.dlab.backendapi.service.ApplicationSettingServiceImpl;
@@ -136,9 +136,9 @@
 				.toInstance(configuration.getBillingFactory()
 						.build(environment, ServiceConsts.BILLING_SERVICE_NAME));
 		bind(ImageExploratoryService.class).to(ImageExploratoryServiceImpl.class);
-		bind(ImageExploratoryDao.class).to(ImageExploratoryDaoImpl.class);
+		bind(ImageExploratoryDAO.class).to(ImageExploratoryDAOImpl.class);
 		bind(BackupService.class).to(BackupServiceImpl.class);
-		bind(BackupDao.class).to(BackupDaoImpl.class);
+		bind(BackupDAO.class).to(BackupDAOImpl.class);
 		bind(ExploratoryService.class).to(ExploratoryServiceImpl.class);
 		bind(Authorizer.class).to(SelfServiceSecurityAuthorizer.class);
 		bind(AccessKeyService.class).to(AccessKeyServiceImpl.class);
@@ -154,8 +154,8 @@
 		bind(SystemInfoService.class).to(SystemInfoServiceImpl.class);
 		bind(UserGroupService.class).to(UserGroupServiceImpl.class);
 		bind(UserRoleService.class).to(UserRoleServiceImpl.class);
-		bind(UserRoleDao.class).to(UserRoleDaoImpl.class);
-		bind(UserGroupDao.class).to(UserGroupDaoImpl.class);
+		bind(UserRoleDAO.class).to(UserRoleDAOImpl.class);
+		bind(UserGroupDAO.class).to(UserGroupDAOImpl.class);
 		bind(InactivityService.class).to(InactivityServiceImpl.class);
 		bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class);
 		bind(UserSettingService.class).to(UserSettingServiceImpl.class);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
index 282e1c6..e43f8c4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
@@ -53,7 +53,7 @@
 @Produces(MediaType.APPLICATION_JSON)
 @Slf4j
 public class ImageExploratoryResource {
-	private final static String AUDIT_MESSAGE = "Create image: %s";
+	private static final String AUDIT_MESSAGE = "Create image: %s";
 
 	private final ImageExploratoryService imageExploratoryService;
 	private final RequestId requestId;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
index e7f8836..612a797 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources;
 
 import com.epam.dlab.auth.UserInfo;
@@ -11,6 +30,7 @@
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.inject.Inject;
 import io.dropwizard.auth.Auth;
+import lombok.extern.slf4j.Slf4j;
 import org.keycloak.representations.AccessTokenResponse;
 
 import javax.ws.rs.GET;
@@ -27,6 +47,7 @@
 import static java.lang.String.format;
 
 @Path("/oauth")
+@Slf4j
 public class KeycloakResource {
 	private static final String LOGIN_URI_FORMAT = "%s/realms/%s/protocol/openid-connect/auth?client_id=%s" +
 			"&redirect_uri=%s&response_type=code";
@@ -42,7 +63,7 @@
 
 	@Inject
 	public KeycloakResource(SecurityService securityService, SelfServiceApplicationConfiguration configuration,
-							SecurityDAO securityDAO, KeycloakService keycloakService) {
+	                        SecurityDAO securityDAO, KeycloakService keycloakService) {
 		this.securityDAO = securityDAO;
 		this.defaultAccess = configuration.getRoleDefaultAccess();
 		final KeycloakConfiguration keycloakConfiguration = configuration.getKeycloakConfiguration();
@@ -97,6 +118,7 @@
 		try {
 			tokenResponse = keycloakService.generateAccessToken(refreshToken);
 		} catch (DlabException e) {
+			log.error("Cannot refresh token due to: {}", e.getMessage(), e);
 			return Response.status(Response.Status.BAD_REQUEST)
 					.location(new URI(logoutUri))
 					.build();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
index 2244460..1e4ee7b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
@@ -60,7 +60,6 @@
 @Produces(MediaType.APPLICATION_JSON)
 @Slf4j
 public class LibExploratoryResource {
-	private static final String DROPWIZARD_ARTIFACT = "io.dropwizard:dropwizard-core:1.3.5";
 	private static final String AUDIT_MESSAGE = "Install libs: %s";
 
 	private final ExternalLibraryService externalLibraryService;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
index 3d6a394..5b6a241 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources;
 
 import com.epam.dlab.auth.UserInfo;
@@ -73,7 +92,7 @@
 	@Consumes(MediaType.APPLICATION_JSON)
 	@RolesAllowed("/api/project/create")
 	public Response createProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
-								  @Valid CreateProjectDTO projectDTO) {
+	                              @Valid CreateProjectDTO projectDTO) {
 		List<ProjectEndpointDTO> projectEndpointDTOS = projectDTO.getEndpoints()
 				.stream()
 				.map(e -> new ProjectEndpointDTO(e, UserInstanceStatus.CREATING, null))
@@ -100,7 +119,7 @@
 	@Consumes(MediaType.APPLICATION_JSON)
 	@RolesAllowed("/api/project")
 	public Response startProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
-								 @NotNull @Valid ProjectActionFormDTO startProjectDto) {
+	                             @NotNull @Valid ProjectActionFormDTO startProjectDto) {
 		projectService.start(userInfo, startProjectDto.getEndpoints(), startProjectDto.getProjectName());
 		return Response
 				.accepted()
@@ -119,7 +138,7 @@
 	@Consumes(MediaType.APPLICATION_JSON)
 	@RolesAllowed("/api/project")
 	public Response stopProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
-								@NotNull @Valid ProjectActionFormDTO stopProjectDTO) {
+	                            @NotNull @Valid ProjectActionFormDTO stopProjectDTO) {
 		projectService.stopWithResources(userInfo, stopProjectDTO.getEndpoints(), stopProjectDTO.getProjectName());
 		return Response
 				.accepted()
@@ -140,8 +159,8 @@
 	@Produces(MediaType.APPLICATION_JSON)
 	@RolesAllowed("/api/project")
 	public Response getProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
-							   @Parameter(description = "Project name")
-							   @PathParam("name") String name) {
+	                           @Parameter(description = "Project name")
+	                           @PathParam("name") String name) {
 		return Response
 				.ok(projectService.get(name))
 				.build();
@@ -172,7 +191,7 @@
 	@Path("/me")
 	@Produces(MediaType.APPLICATION_JSON)
 	public Response getUserProjects(@Parameter(hidden = true) @Auth UserInfo userInfo,
-									@QueryParam("active") @DefaultValue("false") boolean active) {
+	                                @QueryParam("active") @DefaultValue("false") boolean active) {
 		return Response
 				.ok(projectService.getUserProjects(userInfo, active))
 				.build();
@@ -206,7 +225,7 @@
 	@Path("terminate")
 	@RolesAllowed("/api/project")
 	public Response removeProjectEndpoint(@Parameter(hidden = true) @Auth UserInfo userInfo,
-										  @NotNull @Valid ProjectActionFormDTO projectActionDTO) {
+	                                      @NotNull @Valid ProjectActionFormDTO projectActionDTO) {
 		projectService.terminateEndpoint(userInfo, projectActionDTO.getEndpoints(), projectActionDTO.getProjectName());
 		return Response.ok().build();
 	}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java
index 5570232..3ef98c2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java
@@ -19,13 +19,11 @@
 
 package com.epam.dlab.backendapi.resources.callback;
 
-import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.domain.RequestId;
 import com.epam.dlab.dto.UserInstanceStatus;
 import com.epam.dlab.dto.exploratory.ExploratoryStatusDTO;
 import com.epam.dlab.rest.contracts.ApiCallbacks;
 import com.google.inject.Inject;
-import io.dropwizard.auth.Auth;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.ws.rs.Consumes;
@@ -54,7 +52,6 @@
     @Path(ApiCallbacks.STATUS_URI)
     public Response status(ExploratoryStatusDTO dto) {
         if (UserInstanceStatus.CREATED != UserInstanceStatus.of(dto.getStatus())) {
-            //TODO Handle error status?
             log.error("Git creds has not been updated for exploratory environment {} for user {}, status is {}",
                     dto.getExploratoryName(), dto.getUser(), dto.getStatus());
         } else {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java
index be8c2f1..6eaedf9 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java
@@ -19,7 +19,6 @@
 
 package com.epam.dlab.backendapi.resources.callback;
 
-import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
 import com.epam.dlab.backendapi.domain.ExploratoryLibCache;
 import com.epam.dlab.backendapi.domain.RequestId;
@@ -28,7 +27,6 @@
 import com.epam.dlab.dto.exploratory.LibListStatusDTO;
 import com.epam.dlab.exceptions.DlabException;
 import com.google.inject.Inject;
-import io.dropwizard.auth.Auth;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.ws.rs.Consumes;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java
index 59c31da..4500e5e 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources.callback;
 
 import com.epam.dlab.backendapi.dao.ProjectDAO;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java
index 837498a..51324a4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java
@@ -19,12 +19,10 @@
 
 package com.epam.dlab.backendapi.resources.callback;
 
-import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.domain.RequestId;
 import com.epam.dlab.backendapi.service.ReuploadKeyService;
 import com.epam.dlab.dto.reuploadkey.ReuploadKeyStatusDTO;
 import com.google.inject.Inject;
-import io.dropwizard.auth.Auth;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.ws.rs.Consumes;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java
index 8093fc9..6f4e021 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources.dto;
 
 import lombok.AllArgsConstructor;
@@ -6,7 +25,7 @@
 @AllArgsConstructor
 @Data
 public class KeysDTO {
-    private String publicKey;
-    private String privateKey;
-    private String username;
+	private String publicKey;
+	private String privateKey;
+	private String username;
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
index 24d8342..ccdd3c4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources.dto;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java
index e5343dd..bb16414 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java
@@ -120,8 +120,12 @@
 
 	@Override
 	public boolean equals(Object o) {
-		if (this == o) return true;
-		if (o == null || getClass() != o.getClass()) return false;
+		if (this == o) {
+			return true;
+		}
+		if (o == null || getClass() != o.getClass()) {
+			return false;
+		}
 		UserRole userRole = (UserRole) o;
 		return this.id.equals(userRole.getId()) && this.type.equals(userRole.getType()) && this.name.equals(userRole.getName());
 	}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
index 45563a2..ad3ffcc 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
@@ -46,7 +46,7 @@
         try {
             billingService.updateRemoteBillingData(securityService.getServiceAccountInfo("admin"));
         } catch (Exception e) {
-            log.error("Something went wrong {}", e.getMessage());
+            log.error("Something went wrong {}", e.getMessage(), e);
         }
     }
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java
index 5707553..02d109d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java
@@ -50,7 +50,7 @@
         try {
             endpointService.checkUrl(serviceUser, endpoint.getUrl());
         } catch (Exception e) {
-            log.warn("Failed connecting to endpoint {}, url: '{}'. {}", endpoint.getName(), endpoint.getUrl(), e.getMessage());
+            log.warn("Failed connecting to endpoint {}, url: '{}'. {}", endpoint.getName(), endpoint.getUrl(), e.getMessage(), e);
             return endpoint.getStatus() == EndpointDTO.EndpointStatus.ACTIVE;
         }
         return endpoint.getStatus() == EndpointDTO.EndpointStatus.INACTIVE;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java
index c037285..2c84226 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java
@@ -22,7 +22,7 @@
 import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.resources.dto.KeysDTO;
 
+@FunctionalInterface
 public interface AccessKeyService {
-
 	KeysDTO generateKeys(UserInfo userInfo);
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java
index 24fcddd..e30c46e 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java
index 9298c5c..2ecd82a 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java
@@ -21,6 +21,7 @@
 
 import com.epam.dlab.backendapi.resources.dto.LibraryDTO;
 
+@FunctionalInterface
 public interface ExternalLibraryService {
 
 	LibraryDTO getLibrary(String groupId, String artifactId, String version);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java
index 06dc8b1..68df4b1 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java
@@ -1,8 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
 import org.apache.guacamole.net.GuacamoleTunnel;
 
+@FunctionalInterface
 public interface GuacamoleService {
 
 	GuacamoleTunnel getTunnel(UserInfo userInfo, String host, String endpoint);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java
index e55b0cc..b62de5f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java
@@ -1,10 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import org.keycloak.representations.AccessTokenResponse;
 
 public interface KeycloakService {
 	AccessTokenResponse getToken(String code);
+
 	AccessTokenResponse refreshToken(String refreshToken);
+
 	AccessTokenResponse generateAccessToken(String refreshToken);
+
 	AccessTokenResponse generateServiceAccountToken();
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java
index b7c508a..871839d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
@@ -20,6 +39,7 @@
 public class KeycloakServiceImpl implements KeycloakService {
 
 	private static final String URI = "/realms/%s/protocol/openid-connect/token";
+	private static final String GRANT_TYPE = "grant_type";
 	private final Client httpClient;
 	private final KeycloakConfiguration conf;
 	private final SecurityDAO securityDAO;
@@ -61,8 +81,8 @@
 				String.valueOf(conf.getCredentials().get("secret"))));
 		final Response response =
 				httpClient.target(conf.getAuthServerUrl() + String.format(URI, conf.getRealm())).request()
-				.header(HttpHeaders.AUTHORIZATION, "Basic " + credentials)
-				.post(Entity.form(requestForm));
+						.header(HttpHeaders.AUTHORIZATION, "Basic " + credentials)
+						.post(Entity.form(requestForm));
 		if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) {
 
 			log.error("Error getting token:code {}, body {}", response.getStatus(), response.readEntity(String.class));
@@ -73,19 +93,19 @@
 
 	private Form accessTokenRequestForm(String code) {
 		return new Form()
-				.param("grant_type", "authorization_code")
+				.param(GRANT_TYPE, "authorization_code")
 				.param("code", code)
 				.param("redirect_uri", redirectUri);
 	}
 
 	private Form refreshTokenRequestForm(String refreshToken) {
 		return new Form()
-				.param("grant_type", "refresh_token")
+				.param(GRANT_TYPE, "refresh_token")
 				.param("refresh_token", refreshToken);
 	}
 
 	private Form serviceAccountRequestForm() {
 		return new Form()
-				.param("grant_type", "client_credentials");
+				.param(GRANT_TYPE, "client_credentials");
 	}
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
index e6745db..2656e48 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
@@ -18,25 +37,25 @@
 
 	void create(UserInfo userInfo, ProjectDTO projectDTO, String resourceName);
 
-    ProjectDTO get(String name);
+	ProjectDTO get(String name);
 
-    void terminateEndpoint(UserInfo userInfo, String endpoint, String name);
+	void terminateEndpoint(UserInfo userInfo, String endpoint, String name);
 
-    void terminateEndpoint(UserInfo userInfo, List<String> endpoints, String name);
+	void terminateEndpoint(UserInfo userInfo, List<String> endpoints, String name);
 
-    void start(UserInfo userInfo, String endpoint, String name);
+	void start(UserInfo userInfo, String endpoint, String name);
 
-    void start(UserInfo userInfo, List<String> endpoints, String name);
+	void start(UserInfo userInfo, List<String> endpoints, String name);
 
-    void stop(UserInfo userInfo, String endpoint, String name, String auditInfo);
+	void stop(UserInfo userInfo, String endpoint, String name, String auditInfo);
 
-    void stopWithResources(UserInfo userInfo, List<String> endpoints, String projectName);
+	void stopWithResources(UserInfo userInfo, List<String> endpoints, String projectName);
 
-    void update(UserInfo userInfo, UpdateProjectDTO projectDTO, String projectName);
+	void update(UserInfo userInfo, UpdateProjectDTO projectDTO, String projectName);
 
-    void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> projects);
+	void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> projects);
 
-    boolean isAnyProjectAssigned(UserInfo userInfo);
+	boolean isAnyProjectAssigned(UserInfo userInfo);
 
-    boolean checkExploratoriesAndComputationalProgress(String projectName, List<String> endpoints);
+	boolean checkExploratoriesAndComputationalProgress(String projectName, List<String> endpoints);
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java
index 0c2b199..25d2cc0 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java
@@ -19,10 +19,9 @@
 
 package com.epam.dlab.backendapi.service;
 
-import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.dto.reuploadkey.ReuploadKeyStatusDTO;
-import com.epam.dlab.model.ResourceData;
 
+@FunctionalInterface
 public interface ReuploadKeyService {
 
 	void updateResourceData(ReuploadKeyStatusDTO dto);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java
index 6f78ad2..c30a670 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
index b405db8..73dc677 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java
index b3802ce..6e6a576 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java
@@ -20,6 +20,7 @@
 
 import com.epam.dlab.backendapi.resources.dto.SystemInfoDto;
 
+@FunctionalInterface
 public interface SystemInfoService {
 
 	SystemInfoDto getSystemInfo();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java
index f436f6d..b5451ca 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java
@@ -1,9 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
 
 import java.util.Map;
 
+@FunctionalInterface
 public interface TagService {
 	Map<String, String> getResourceTags(UserInfo userInfo, String endpoint, String project, String customTag);
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java
index 5f1504c..3b281fd 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.auth.UserInfo;
@@ -12,7 +31,7 @@
 
 	@Override
 	public Map<String, String> getResourceTags(UserInfo userInfo, String endpoint, String project,
-											   String customTag) {
+	                                           String customTag) {
 		Map<String, String> tags = new HashMap<>();
 		tags.put("user_tag", userInfo.getName());
 		tags.put("endpoint_tag", endpoint);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java
index 92e0afb..5f3f6a3 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java
@@ -18,7 +18,7 @@
  */
 package com.epam.dlab.backendapi.service;
 
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
 import com.epam.dlab.backendapi.resources.dto.UserRoleDto;
 import com.epam.dlab.exceptions.ResourceNotFoundException;
 import com.google.inject.Inject;
@@ -33,7 +33,7 @@
 	private static final String ROLE_NOT_FOUND_MSG = "Any of role : %s were not found";
 
 	@Inject
-	private UserRoleDao userRoleDao;
+	private UserRoleDAO userRoleDao;
 
 	@Override
 	public List<UserRoleDto> getUserRoles() {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java
index b50b0ae..1a93470 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java
@@ -20,7 +20,7 @@
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.backendapi.dao.BackupDao;
+import com.epam.dlab.backendapi.dao.BackupDAO;
 import com.epam.dlab.backendapi.resources.dto.BackupInfoRecord;
 import com.epam.dlab.backendapi.service.BackupService;
 import com.epam.dlab.constants.ServiceConsts;
@@ -43,7 +43,7 @@
 	private RESTService provisioningService;
 
 	@Inject
-	private BackupDao backupDao;
+	private BackupDAO backupDao;
 
 	@Override
 	public String createBackup(EnvBackupDTO dto, UserInfo user) {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
index 2bcf644..2810a33 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
@@ -22,7 +22,7 @@
 import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.BillingDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
 import com.epam.dlab.backendapi.domain.BillingReport;
 import com.epam.dlab.backendapi.domain.BillingReportLine;
@@ -83,14 +83,14 @@
     private final ExploratoryService exploratoryService;
     private final SelfServiceApplicationConfiguration configuration;
     private final RESTService provisioningService;
-    private final ImageExploratoryDao imageExploratoryDao;
+    private final ImageExploratoryDAO imageExploratoryDao;
     private final BillingDAO billingDAO;
     private final String sbn;
 
     @Inject
     public BillingServiceImpl(ProjectService projectService, ProjectDAO projectDAO, EndpointService endpointService,
                               ExploratoryService exploratoryService, SelfServiceApplicationConfiguration configuration,
-                              @Named(ServiceConsts.BILLING_SERVICE_NAME) RESTService provisioningService, ImageExploratoryDao imageExploratoryDao,
+                              @Named(ServiceConsts.BILLING_SERVICE_NAME) RESTService provisioningService, ImageExploratoryDAO imageExploratoryDao,
                               BillingDAO billingDAO) {
         this.projectService = projectService;
         this.projectDAO = projectDAO;
@@ -116,12 +116,12 @@
         final double sum = billingReportLines.stream().mapToDouble(BillingReportLine::getCost).sum();
         final String currency = billingReportLines.stream().map(BillingReportLine::getCurrency).distinct().count() == 1 ? billingReportLines.get(0).getCurrency() : null;
         return BillingReport.builder()
-                .name("Billing report")
-                .sbn(sbn)
-                .reportLines(billingReportLines)
-                .usageDateFrom(min)
-                .usageDateTo(max)
-                .totalCost(new BigDecimal(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
+		        .name("Billing report")
+		        .sbn(sbn)
+		        .reportLines(billingReportLines)
+		        .usageDateFrom(min)
+		        .usageDateTo(max)
+		        .totalCost(BigDecimal.valueOf(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
                 .currency(currency)
                 .isReportHeaderCompletable(hasUserBillingRole(user))
                 .build();
@@ -155,9 +155,9 @@
                 .collect(Collectors.toList());;
         final String currency = billingData.stream().map(BillingReportLine::getCurrency).distinct().count() == 1 ? billingData.get(0).getCurrency() : null;
         return BillingReport.builder()
-                .name(exploratoryName)
-                .reportLines(billingData)
-                .totalCost(new BigDecimal(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
+		        .name(exploratoryName)
+		        .reportLines(billingData)
+		        .totalCost(BigDecimal.valueOf(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
                 .currency(currency)
                 .build();
     }
@@ -297,16 +297,16 @@
         billingDAO.save(billingReportLines);
     }
 
-    private List<BillingData> getBillingData(UserInfo userInfo, EndpointDTO e) {
-        try {
-            return provisioningService.get(getBillingUrl(e.getUrl(), BILLING_PATH), userInfo.getAccessToken(),
-                    new GenericType<List<BillingData>>() {
-                    });
-        } catch (Exception ex) {
-            log.error("Cannot retrieve billing information for {}. {}", e.getName(), ex.getMessage());
-            return Collections.emptyList();
-        }
-    }
+	private List<BillingData> getBillingData(UserInfo userInfo, EndpointDTO endpointDTO) {
+		try {
+			return provisioningService.get(getBillingUrl(endpointDTO.getUrl(), BILLING_PATH), userInfo.getAccessToken(),
+					new GenericType<List<BillingData>>() {
+					});
+		} catch (Exception e) {
+			log.error("Cannot retrieve billing information for {} . Reason {}.", endpointDTO.getName(), e.getMessage(), e);
+			return Collections.emptyList();
+		}
+	}
 
     private String getBillingUrl(String endpointUrl, String path) {
         URI uri;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java
index 0d27a86..8049857 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java
@@ -66,6 +66,7 @@
     private static final String BUCKET_UPLOAD_FOLDER = "%sbucket/folder/upload";
     private static final String BUCKET_DOWNLOAD_OBJECT = "%sbucket/%s/object/%s/download";
     private static final String BUCKET_DELETE_OBJECT = "%sbucket/objects/delete";
+    private static final String SOMETHING_WENT_WRONG_MESSAGE = "Something went wrong. Response status is %s ";
 
     private final EndpointService endpointService;
     private final RESTService provisioningService;
@@ -83,7 +84,7 @@
             return provisioningService.get(String.format(BUCKET_GET_OBJECTS, endpointDTO.getUrl(), bucket), userInfo.getAccessToken(), new GenericType<List<BucketDTO>>() {
             });
         } catch (Exception e) {
-            log.error("Cannot get objects from bucket {} for user {}, endpoint {}. Reason {}", bucket, userInfo.getName(), endpoint, e.getMessage());
+            log.error("Cannot get objects from bucket {} for user {}, endpoint {}. Reason {}", bucket, userInfo.getName(), endpoint, e.getMessage(), e);
             throw new DlabException(String.format("Cannot get objects from bucket %s for user %s, endpoint %s. Reason %s", bucket, userInfo.getName(), endpoint, e.getMessage()));
         }
     }
@@ -97,10 +98,10 @@
             FormDataMultiPart formData = getFormDataMultiPart(bucket, object, inputStream, contentType, fileSize);
             Response response = provisioningService.postForm(String.format(BUCKET_UPLOAD_OBJECT, endpointDTO.getUrl()), userInfo.getAccessToken(), formData, Response.class);
             if (response.getStatus() != HttpStatus.SC_OK) {
-                throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus()));
+                throw new DlabException(String.format(SOMETHING_WENT_WRONG_MESSAGE, response.getStatus()));
             }
         } catch (Exception e) {
-            log.error("Cannot upload object {} to bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage());
+	        log.error("Cannot upload object {} to bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
             throw new DlabException(String.format("Cannot upload object %s to bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage()));
         }
         log.info("Finished uploading file {} for user {} to bucket {}", object, userInfo.getName(), bucket);
@@ -118,10 +119,10 @@
             FolderUploadDTO dto = new FolderUploadDTO(bucket, folder);
             Response response = provisioningService.post(String.format(BUCKET_UPLOAD_FOLDER, endpointDTO.getUrl()), userInfo.getAccessToken(), dto, Response.class);
             if (response.getStatus() != HttpStatus.SC_OK) {
-                throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus()));
+                throw new DlabException(String.format(SOMETHING_WENT_WRONG_MESSAGE, response.getStatus()));
             }
         } catch (Exception e) {
-            log.error("Cannot upload folder {} to bucket {} for user {}, endpoint {}. Reason {}", folder, bucket, userInfo.getName(), endpoint, e.getMessage());
+	        log.error("Cannot upload folder {} to bucket {} for user {}, endpoint {}. Reason {}", folder, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
             throw new DlabException(String.format("Cannot upload object %s to bucket %s for user %s, endpoint %s. Reason %s", folder, bucket, userInfo.getName(), endpoint, e.getMessage()));
         }
         log.info("Finished uploading folder {} for user {} to bucket {}", folder, userInfo.getName(), bucket);
@@ -137,7 +138,7 @@
             IOUtils.copyLarge(inputStream, outputStream);
             log.info("Finished downloading file {} for user {} from bucket {}", object, userInfo.getName(), bucket);
         } catch (Exception e) {
-            log.error("Cannot upload object {} from bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage());
+	        log.error("Cannot upload object {} from bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
             throw new DlabException(String.format("Cannot download object %s from bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage()));
         }
     }
@@ -150,10 +151,10 @@
             BucketDeleteDTO bucketDeleteDTO = new BucketDeleteDTO(bucket, objects);
             Response response = provisioningService.post(String.format(BUCKET_DELETE_OBJECT, endpointDTO.getUrl()), userInfo.getAccessToken(), bucketDeleteDTO, Response.class);
             if (response.getStatus() != HttpStatus.SC_OK) {
-                throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus()));
+                throw new DlabException(String.format(SOMETHING_WENT_WRONG_MESSAGE, response.getStatus()));
             }
         } catch (Exception e) {
-            log.error("Cannot delete objects {} from bucket {} for user {}, endpoint {}. Reason {}", objects, bucket, userInfo.getName(), endpoint, e.getMessage());
+	        log.error("Cannot delete objects {} from bucket {} for user {}, endpoint {}. Reason {}", objects, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
             throw new DlabException(String.format("Cannot delete objects %s from bucket %s for user %s, endpoint %s. Reason %s", objects, bucket, userInfo.getName(), endpoint, e.getMessage()));
         }
     }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java
index 1bfd0b7..0a87667 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java
@@ -340,8 +340,7 @@
 		try {
 			return Optional.of(computationalDAO.fetchComputationalFields(user, project, exploratoryName, computationalName));
 		} catch (DlabException e) {
-			log.warn("Computational resource {} affiliated with exploratory {} for user {} not found.",
-					computationalName, exploratoryName, user);
+			log.warn("Computational resource {} affiliated with exploratory {} for user {} not found.", computationalName, exploratoryName, user, e);
 		}
 		return Optional.empty();
 	}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java
index e3ad62c..cbb7bd1 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.auth.UserInfo;
@@ -6,7 +25,7 @@
 import com.epam.dlab.backendapi.annotation.User;
 import com.epam.dlab.backendapi.dao.EndpointDAO;
 import com.epam.dlab.backendapi.dao.ExploratoryDAO;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.domain.EndpointResourcesDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
@@ -43,12 +62,12 @@
 	private final ProjectService projectService;
 	private final ExploratoryDAO exploratoryDAO;
 	private final RESTService provisioningService;
-	private final UserRoleDao userRoleDao;
+	private final UserRoleDAO userRoleDao;
 
 	@Inject
 	public EndpointServiceImpl(EndpointDAO endpointDAO, ProjectService projectService, ExploratoryDAO exploratoryDAO,
-							   @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
-							   UserRoleDao userRoleDao) {
+	                           @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+	                           UserRoleDAO userRoleDao) {
 
 		this.endpointDAO = endpointDAO;
 		this.projectService = projectService;
@@ -83,26 +102,26 @@
 				.orElseThrow(() -> new ResourceNotFoundException("Endpoint with name " + name + " not found"));
 	}
 
-    /**
-     * Create new endpoint object in the System.
-     * The Endpoint objects should contain Unique values of the 'url' and 'name' fields,
-     * i.e two objects with same URLs should not be created in the system.
-     *
-     * @param userInfo     user properties
-     * @param resourceName name of the endpoint
-     * @param endpointDTO  object with endpoint fields
-     */
-    @Audit(action = CONNECT, type = ENDPOINT)
-    @Override
-    public void create(@User UserInfo userInfo, @ResourceName String resourceName, EndpointDTO endpointDTO) {
-        if (endpointDAO.get(endpointDTO.getName()).isPresent()) {
-            throw new ResourceConflictException("The Endpoint with this name exists in system");
-        }
-        if (endpointDAO.getEndpointWithUrl(endpointDTO.getUrl()).isPresent()) {
-            throw new ResourceConflictException("The Endpoint URL with this address exists in system");
-        }
-        CloudProvider cloudProvider = checkUrl(userInfo, endpointDTO.getUrl());
-        if (Objects.isNull(cloudProvider)) {
+	/**
+	 * Create new endpoint object in the System.
+	 * The Endpoint objects should contain Unique values of the 'url' and 'name' fields,
+	 * i.e two objects with same URLs should not be created in the system.
+	 *
+	 * @param userInfo     user properties
+	 * @param resourceName name of the endpoint
+	 * @param endpointDTO  object with endpoint fields
+	 */
+	@Audit(action = CONNECT, type = ENDPOINT)
+	@Override
+	public void create(@User UserInfo userInfo, @ResourceName String resourceName, EndpointDTO endpointDTO) {
+		if (endpointDAO.get(endpointDTO.getName()).isPresent()) {
+			throw new ResourceConflictException("The Endpoint with this name exists in system");
+		}
+		if (endpointDAO.getEndpointWithUrl(endpointDTO.getUrl()).isPresent()) {
+			throw new ResourceConflictException("The Endpoint URL with this address exists in system");
+		}
+		CloudProvider cloudProvider = checkUrl(userInfo, endpointDTO.getUrl());
+		if (Objects.isNull(cloudProvider)) {
 			throw new DlabException("CloudProvider cannot be null");
 		}
 		endpointDAO.create(new EndpointDTO(endpointDTO.getName(), endpointDTO.getUrl(), endpointDTO.getAccount(),
@@ -113,26 +132,26 @@
 	@Override
 	public void updateEndpointStatus(String name, EndpointDTO.EndpointStatus status) {
 		endpointDAO.updateEndpointStatus(name, status.name());
-    }
+	}
 
-    @Override
-    public void remove(UserInfo userInfo, String name) {
-        EndpointDTO endpointDTO = endpointDAO.get(name).orElseThrow(() -> new ResourceNotFoundException(String.format("Endpoint %s does not exist", name)));
-        List<ProjectDTO> projects = projectService.getProjectsByEndpoint(name);
-        checkProjectEndpointResourcesStatuses(projects, name);
-        CloudProvider cloudProvider = endpointDTO.getCloudProvider();
-        removeEndpoint(userInfo, name, cloudProvider, projects);
-    }
+	@Override
+	public void remove(UserInfo userInfo, String name) {
+		EndpointDTO endpointDTO = endpointDAO.get(name).orElseThrow(() -> new ResourceNotFoundException(String.format("Endpoint %s does not exist", name)));
+		List<ProjectDTO> projects = projectService.getProjectsByEndpoint(name);
+		checkProjectEndpointResourcesStatuses(projects, name);
+		CloudProvider cloudProvider = endpointDTO.getCloudProvider();
+		removeEndpoint(userInfo, name, cloudProvider, projects);
+	}
 
 	@Audit(action = DISCONNECT, type = ENDPOINT)
-    public void removeEndpoint(@User UserInfo userInfo, @ResourceName String name, CloudProvider cloudProvider, List<ProjectDTO> projects) {
-        removeEndpointInAllProjects(userInfo, name, projects);
-        endpointDAO.remove(name);
-        List<CloudProvider> remainingProviders = endpointDAO.getEndpoints()
-                .stream()
-                .map(EndpointDTO::getCloudProvider)
-                .collect(Collectors.toList());
-        userRoleDao.removeUnnecessaryRoles(cloudProvider, remainingProviders);
+	public void removeEndpoint(@User UserInfo userInfo, @ResourceName String name, CloudProvider cloudProvider, List<ProjectDTO> projects) {
+		removeEndpointInAllProjects(userInfo, name, projects);
+		endpointDAO.remove(name);
+		List<CloudProvider> remainingProviders = endpointDAO.getEndpoints()
+				.stream()
+				.map(EndpointDTO::getCloudProvider)
+				.collect(Collectors.toList());
+		userRoleDao.removeUnnecessaryRoles(cloudProvider, remainingProviders);
 	}
 
 	@Override
@@ -148,9 +167,9 @@
 			response = provisioningService.get(url + HEALTH_CHECK, userInfo.getAccessToken(), Response.class);
 			cloudProvider = response.readEntity(CloudProvider.class);
 		} catch (Exception e) {
-            log.error("Cannot connect to url '{}'. {}", url, e.getMessage());
-            throw new DlabException(String.format("Cannot connect to url '%s'.", url));
-        }
+			log.error("Cannot connect to url '{}'. {}", url, e.getMessage(), e);
+			throw new DlabException(String.format("Cannot connect to url '%s'.", url));
+		}
 		if (response.getStatus() != 200) {
 			log.warn("Endpoint url {} is not valid", url);
 			throw new ResourceNotFoundException(String.format("Endpoint url '%s' is not valid", url));
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
index e89eda3..cdafb03 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
@@ -30,7 +30,7 @@
 import com.epam.dlab.backendapi.dao.ComputationalDAO;
 import com.epam.dlab.backendapi.dao.ExploratoryDAO;
 import com.epam.dlab.backendapi.dao.GitCredsDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
 import com.epam.dlab.backendapi.domain.AuditActionEnum;
 import com.epam.dlab.backendapi.domain.AuditDTO;
 import com.epam.dlab.backendapi.domain.AuditResourceTypeEnum;
@@ -101,7 +101,7 @@
 	private final ExploratoryDAO exploratoryDAO;
 	private final ComputationalDAO computationalDAO;
 	private final GitCredsDAO gitCredsDAO;
-	private final ImageExploratoryDao imageExploratoryDao;
+	private final ImageExploratoryDAO imageExploratoryDao;
 	private final RESTService provisioningService;
 	private final RequestBuilder requestBuilder;
 	private final RequestId requestId;
@@ -112,9 +112,9 @@
 
 	@Inject
 	public ExploratoryServiceImpl(ProjectService projectService, ExploratoryDAO exploratoryDAO, ComputationalDAO computationalDAO, GitCredsDAO gitCredsDAO,
-								  ImageExploratoryDao imageExploratoryDao, @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
-								  RequestBuilder requestBuilder, RequestId requestId, TagService tagService, EndpointService endpointService, AuditService auditService,
-								  SelfServiceApplicationConfiguration configuration) {
+	                              ImageExploratoryDAO imageExploratoryDao, @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+	                              RequestBuilder requestBuilder, RequestId requestId, TagService tagService, EndpointService endpointService, AuditService auditService,
+	                              SelfServiceApplicationConfiguration configuration) {
 		this.projectService = projectService;
 		this.exploratoryDAO = exploratoryDAO;
 		this.computationalDAO = computationalDAO;
@@ -229,7 +229,7 @@
 		try {
 			return Optional.of(exploratoryDAO.fetchExploratoryFields(user, project, exploratoryName));
 		} catch (DlabException e) {
-			log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user);
+			log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user, e);
 		}
 		return Optional.empty();
 	}
@@ -239,7 +239,7 @@
 		try {
 			return Optional.of(exploratoryDAO.fetchExploratoryFields(user, project, exploratoryName, includeCompResources));
 		} catch (DlabException e) {
-			log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user);
+			log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user, e);
 		}
 		return Optional.empty();
 	}
@@ -460,7 +460,8 @@
 
 	private LibInstallDTO toLibInstallDto(Library l) {
 		return new LibInstallDTO(l.getGroup(), l.getName(), l.getVersion())
-				.withStatus(l.getStatus().toString())
+				.withStatus(String.valueOf(l.getStatus()))
+				.withAddedPackages(l.getAddedPackages())
 				.withErrorMessage(l.getErrorMessage());
 	}
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java
index 2394595..e94bf91 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.auth.UserInfo;
@@ -35,8 +54,8 @@
 
 	@Inject
 	public GuacamoleServiceImpl(SelfServiceApplicationConfiguration conf,
-								@Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
-								EndpointService endpointService) {
+	                            @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+	                            EndpointService endpointService) {
 		this.conf = conf;
 		this.provisioningService = provisioningService;
 		this.endpointService = endpointService;
@@ -61,7 +80,7 @@
 	}
 
 	private GuacamoleConfiguration getGuacamoleConfig(String privateKeyContent, Map<String, String> guacamoleParams,
-													  String host) {
+	                                                  String host) {
 		GuacamoleConfiguration guacamoleConfiguration = new GuacamoleConfiguration();
 		guacamoleConfiguration.setProtocol(guacamoleParams.get(CONNECTION_PROTOCOL_PARAM));
 		guacamoleConfiguration.setParameters(guacamoleParams);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java
index 10e5126..4aae5b1 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java
@@ -27,7 +27,7 @@
 import com.epam.dlab.backendapi.annotation.User;
 import com.epam.dlab.backendapi.dao.ExploratoryDAO;
 import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.resources.dto.ImageInfoRecord;
@@ -64,24 +64,24 @@
 @Singleton
 @Slf4j
 public class ImageExploratoryServiceImpl implements ImageExploratoryService {
-    private static final String IMAGE_EXISTS_MSG = "Image with name %s is already exist in project %s";
-    private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found for user %s";
+	private static final String IMAGE_EXISTS_MSG = "Image with name %s is already exist in project %s";
+	private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found for user %s";
 
-    @Inject
-    private ExploratoryDAO exploratoryDAO;
-    @Inject
-    private ImageExploratoryDao imageExploratoryDao;
-    @Inject
-    private ExploratoryLibDAO libDAO;
-    @Inject
-    @Named(ServiceConsts.PROVISIONING_SERVICE_NAME)
-    private RESTService provisioningService;
-    @Inject
-    private RequestBuilder requestBuilder;
-    @Inject
-    private EndpointService endpointService;
-    @Inject
-    private ProjectService projectService;
+	@Inject
+	private ExploratoryDAO exploratoryDAO;
+	@Inject
+	private ImageExploratoryDAO imageExploratoryDao;
+	@Inject
+	private ExploratoryLibDAO libDAO;
+	@Inject
+	@Named(ServiceConsts.PROVISIONING_SERVICE_NAME)
+	private RESTService provisioningService;
+	@Inject
+	private RequestBuilder requestBuilder;
+	@Inject
+	private EndpointService endpointService;
+	@Inject
+	private ProjectService projectService;
 
     @Audit(action = CREATE, type = IMAGE)
     @Override
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java
index 9f3f05f..03f093b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java
@@ -23,7 +23,7 @@
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
 import com.epam.dlab.backendapi.dao.SettingsDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.resources.dto.SparkStandaloneConfiguration;
 import com.epam.dlab.backendapi.resources.dto.aws.AwsEmrConfiguration;
@@ -52,6 +52,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static com.epam.dlab.cloud.CloudProvider.AZURE;
 import static com.epam.dlab.rest.contracts.DockerAPI.DOCKER_COMPUTATIONAL;
 import static com.epam.dlab.rest.contracts.DockerAPI.DOCKER_EXPLORATORY;
 
@@ -67,7 +68,7 @@
 	@Inject
 	private EndpointService endpointService;
 	@Inject
-	private UserGroupDao userGroupDao;
+	private UserGroupDAO userGroupDao;
 
 
 	@Inject
@@ -144,7 +145,7 @@
 	 * Temporary filter for creation of exploratory env due to Azure issues
 	 */
 	private boolean exploratoryGpuIssuesAzureFilter(ExploratoryMetadataDTO e, CloudProvider cloudProvider) {
-		return (!"redhat".equals(settingsDAO.getConfOsFamily()) || cloudProvider != CloudProvider.AZURE) ||
+		return (!"redhat".equals(settingsDAO.getConfOsFamily()) || cloudProvider != AZURE) ||
 				!(e.getImage().endsWith("deeplearning") || e.getImage().endsWith("tensor"));
 	}
 
@@ -203,7 +204,8 @@
 								.minDataprocPreemptibleInstanceCount(configuration.getMinDataprocPreemptibleCount())
 								.build());
 			case AZURE:
-				log.error("Dataengine service is not supported currently for {}", cloudProvider);
+				log.error("Dataengine service is not supported currently for {}", AZURE);
+				throw new UnsupportedOperationException("Dataengine service is not supported currently for " + AZURE);
 			default:
 				throw new UnsupportedOperationException("Dataengine service is not supported currently for " + cloudProvider);
 		}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java
index b7cbce8..13d0c86 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java
@@ -32,7 +32,6 @@
 import javax.inject.Inject;
 import java.net.URI;
 
-import static java.lang.String.format;
 import static java.lang.String.join;
 
 @Singleton
@@ -41,7 +40,7 @@
 
 	private static final String QUOTE_ENCODED = "%22";
 	private static final String SEARCH_API_QUERY_FORMAT = "/solrsearch/select?q=%s&rows=20&wt=json&core=gav&p=jar";
-	private static final String LIB_NOT_FOUND_MSG = "Artifact with id=%s, groupId=%s and version %s not found";
+	private static final String LIB_NOT_FOUND_MSG = "No matches found";
 	private final RESTService restClient;
 
 	@Inject
@@ -63,8 +62,7 @@
 				.stream()
 				.findFirst()
 				.map(artifact -> new LibraryDTO(join(":", groupId, artifactId), version))
-				.orElseThrow(() -> new ResourceNotFoundException(format(LIB_NOT_FOUND_MSG, artifactId, groupId,
-						version)));
+				.orElseThrow(() -> new ResourceNotFoundException(LIB_NOT_FOUND_MSG));
 	}
 
 	private String groupQuery(String groupId) {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
index a6a51bf..7ee90ba 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.auth.UserInfo;
@@ -11,7 +30,7 @@
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.ExploratoryDAO;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
 import com.epam.dlab.backendapi.domain.BudgetDTO;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
@@ -36,7 +55,6 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
@@ -70,7 +88,7 @@
 
 	private final ProjectDAO projectDAO;
 	private final ExploratoryService exploratoryService;
-	private final UserGroupDao userGroupDao;
+	private final UserGroupDAO userGroupDao;
 	private final RESTService provisioningService;
 	private final RequestId requestId;
 	private final RequestBuilder requestBuilder;
@@ -81,10 +99,10 @@
 
 	@Inject
 	public ProjectServiceImpl(ProjectDAO projectDAO, ExploratoryService exploratoryService,
-							  UserGroupDao userGroupDao,
-							  @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
-							  RequestId requestId, RequestBuilder requestBuilder, EndpointService endpointService,
-							  ExploratoryDAO exploratoryDAO, SelfServiceApplicationConfiguration configuration) {
+	                          UserGroupDAO userGroupDao,
+	                          @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+	                          RequestId requestId, RequestBuilder requestBuilder, EndpointService endpointService,
+	                          ExploratoryDAO exploratoryDAO, SelfServiceApplicationConfiguration configuration) {
 		this.projectDAO = projectDAO;
 		this.exploratoryService = exploratoryService;
 		this.userGroupDao = userGroupDao;
@@ -136,13 +154,13 @@
 				.orElseThrow(projectNotFound());
 	}
 
-    @Audit(action = TERMINATE, type = EDGE_NODE)
-    @Override
-    public void terminateEndpoint(@User UserInfo userInfo, @ResourceName String endpoint, @Project String name) {
-	    projectActionOnCloud(userInfo, name, TERMINATE_PRJ_API, endpoint);
-	    projectDAO.updateEdgeStatus(name, endpoint, UserInstanceStatus.TERMINATING);
-	    exploratoryService.updateProjectExploratoryStatuses(userInfo, name, endpoint, UserInstanceStatus.TERMINATING);
-    }
+	@Audit(action = TERMINATE, type = EDGE_NODE)
+	@Override
+	public void terminateEndpoint(@User UserInfo userInfo, @ResourceName String endpoint, @Project String name) {
+		projectActionOnCloud(userInfo, name, TERMINATE_PRJ_API, endpoint);
+		projectDAO.updateEdgeStatus(name, endpoint, UserInstanceStatus.TERMINATING);
+		exploratoryService.updateProjectExploratoryStatuses(userInfo, name, endpoint, UserInstanceStatus.TERMINATING);
+	}
 
 	@ProjectAdmin
 	@Override
@@ -179,15 +197,15 @@
 		List<ProjectEndpointDTO> endpointDTOs = getProjectEndpointDTOS(endpoints, projectName);
 		checkProjectRelatedResourcesInProgress(projectName, endpointDTOs, STOP_ACTION);
 
-        endpointDTOs
-                .stream()
-                .filter(e -> !Arrays.asList(UserInstanceStatus.TERMINATED, UserInstanceStatus.TERMINATING, UserInstanceStatus.STOPPED,
-                        UserInstanceStatus.FAILED).contains(e.getStatus()))
-                .forEach(e -> stop(userInfo, e.getName(), projectName, null));
+		endpointDTOs
+				.stream()
+				.filter(e -> !Arrays.asList(UserInstanceStatus.TERMINATED, UserInstanceStatus.TERMINATING, UserInstanceStatus.STOPPED,
+						UserInstanceStatus.FAILED).contains(e.getStatus()))
+				.forEach(e -> stop(userInfo, e.getName(), projectName, null));
 
-        exploratoryDAO.fetchRunningExploratoryFieldsForProject(projectName,
-                endpointDTOs
-                        .stream()
+		exploratoryDAO.fetchRunningExploratoryFieldsForProject(projectName,
+				endpointDTOs
+						.stream()
 						.map(ProjectEndpointDTO::getName)
 						.collect(Collectors.toList()))
 				.forEach(e -> exploratoryService.stop(userInfo, e.getUser(), projectName, e.getExploratoryName(), null));
@@ -196,39 +214,39 @@
 	@ProjectAdmin
 	@Override
 	public void update(@User UserInfo userInfo, UpdateProjectDTO projectDTO, @Project String projectName) {
-        final ProjectDTO project = projectDAO.get(projectDTO.getName()).orElseThrow(projectNotFound());
-        final Set<String> endpoints = project.getEndpoints()
-                .stream()
-                .map(ProjectEndpointDTO::getName)
-                .collect(toSet());
-        final Set<String> newEndpoints = new HashSet<>(projectDTO.getEndpoints());
-        newEndpoints.removeAll(endpoints);
-        final String projectUpdateAudit = updateProjectAudit(projectDTO, project, newEndpoints);
-        updateProject(userInfo, projectName, projectDTO, project, newEndpoints, projectUpdateAudit);
-    }
+		final ProjectDTO project = projectDAO.get(projectDTO.getName()).orElseThrow(projectNotFound());
+		final Set<String> endpoints = project.getEndpoints()
+				.stream()
+				.map(ProjectEndpointDTO::getName)
+				.collect(toSet());
+		final Set<String> newEndpoints = new HashSet<>(projectDTO.getEndpoints());
+		newEndpoints.removeAll(endpoints);
+		final String projectUpdateAudit = updateProjectAudit(projectDTO, project, newEndpoints);
+		updateProject(userInfo, projectName, projectDTO, project, newEndpoints, projectUpdateAudit);
+	}
 
-    @Audit(action = UPDATE, type = PROJECT)
-    public void updateProject(@User UserInfo userInfo, @Project @ResourceName String projectName, UpdateProjectDTO projectDTO, ProjectDTO project, Set<String> newEndpoints,
-                              @Info String projectAudit) {
-	    final List<ProjectEndpointDTO> endpointsToBeCreated = newEndpoints
-			    .stream()
-			    .map(e -> new ProjectEndpointDTO(e, UserInstanceStatus.CREATING, null))
-			    .collect(Collectors.toList());
-	    project.getEndpoints().addAll(endpointsToBeCreated);
-	    projectDAO.update(new ProjectDTO(project.getName(), projectDTO.getGroups(), project.getKey(),
-			    project.getTag(), project.getBudget(), project.getEndpoints(), projectDTO.isSharedImageEnabled()));
-	    endpointsToBeCreated.forEach(e -> createEndpoint(userInfo, projectName, project, e.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
-    }
+	@Audit(action = UPDATE, type = PROJECT)
+	public void updateProject(@User UserInfo userInfo, @Project @ResourceName String projectName, UpdateProjectDTO projectDTO, ProjectDTO project, Set<String> newEndpoints,
+	                          @Info String projectAudit) {
+		final List<ProjectEndpointDTO> endpointsToBeCreated = newEndpoints
+				.stream()
+				.map(e -> new ProjectEndpointDTO(e, UserInstanceStatus.CREATING, null))
+				.collect(Collectors.toList());
+		project.getEndpoints().addAll(endpointsToBeCreated);
+		projectDAO.update(new ProjectDTO(project.getName(), projectDTO.getGroups(), project.getKey(),
+				project.getTag(), project.getBudget(), project.getEndpoints(), projectDTO.isSharedImageEnabled()));
+		endpointsToBeCreated.forEach(e -> createEndpoint(userInfo, projectName, project, e.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
+	}
 
-    @Override
-    public void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> dtos) {
-	    final List<ProjectDTO> projects = dtos
-			    .stream()
-			    .map(this::getUpdateProjectDTO)
-			    .collect(Collectors.toList());
+	@Override
+	public void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> dtos) {
+		final List<ProjectDTO> projects = dtos
+				.stream()
+				.map(this::getUpdateProjectDTO)
+				.collect(Collectors.toList());
 
-	    projects.forEach(p -> updateBudget(userInfo, p.getName(), p.getBudget(), getUpdateBudgetAudit(p)));
-    }
+		projects.forEach(p -> updateBudget(userInfo, p.getName(), p.getBudget(), getUpdateBudgetAudit(p)));
+	}
 
 	@Audit(action = UPDATE, type = PROJECT)
 	public void updateBudget(@User UserInfo userInfo, @Project @ResourceName String name, BudgetDTO budget, @Info String updateBudgetAudit) {
@@ -258,7 +276,7 @@
 		try {
 			project.getEndpoints().forEach(e -> createEndpoint(user, project.getName(), project, e.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
 		} catch (Exception e) {
-			log.error("Can not create project due to: {}", e.getMessage());
+			log.error("Can not create project due to: {}", e.getMessage(), e);
 			projectDAO.updateStatus(project.getName(), ProjectDTO.Status.FAILED);
 		}
 	}
@@ -278,17 +296,17 @@
 					requestBuilder.newProjectAction(user, projectName, endpointDTO), String.class);
 			requestId.put(user.getName(), uuid);
 		} catch (Exception e) {
-			log.error("Can not terminate project due to: {}", e.getMessage());
+			log.error("Can not terminate project due to: {}", e.getMessage(), e);
 			projectDAO.updateStatus(projectName, ProjectDTO.Status.FAILED);
 		}
 	}
 
 	private void checkProjectRelatedResourcesInProgress(String projectName, List<ProjectEndpointDTO> endpoints, String action) {
-        boolean edgeProgress = endpoints
+		boolean edgeProgress = endpoints
 				.stream()
 				.anyMatch(e ->
-                Arrays.asList(UserInstanceStatus.CREATING, UserInstanceStatus.STARTING, UserInstanceStatus.STOPPING,
-                        UserInstanceStatus.TERMINATING).contains(e.getStatus()));
+						Arrays.asList(UserInstanceStatus.CREATING, UserInstanceStatus.STARTING, UserInstanceStatus.STOPPING,
+								UserInstanceStatus.TERMINATING).contains(e.getStatus()));
 
 		List<String> endpointNames = endpoints
 				.stream()
@@ -323,6 +341,9 @@
 	}
 
 	private String getUpdateBudgetAudit(ProjectDTO p) {
+		if (!configuration.isAuditEnabled()) {
+			return null;
+		}
 		Integer value = Optional.ofNullable(get(p.getName()).getBudget())
 				.map(BudgetDTO::getValue)
 				.orElse(null);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java
index 5b5b7e5..0475492 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java
@@ -24,8 +24,8 @@
 import com.epam.dlab.backendapi.annotation.User;
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
 import com.epam.dlab.backendapi.domain.AuditDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.resources.dto.UserGroupDto;
@@ -65,17 +65,18 @@
 	private static final String ROLE_NOT_FOUND_MSG = "Any of role : %s were not found";
 	private static final String ADMIN = "admin";
 	private static final String PROJECT_ADMIN = "projectAdmin";
+	private static final String INAPPROPRIATE_PERMISSION = "User %s doesn't have appropriate permission";
 
-	private final UserGroupDao userGroupDao;
-	private final UserRoleDao userRoleDao;
+	private final UserGroupDAO userGroupDao;
+	private final UserRoleDAO userRoleDao;
 	private final ProjectDAO projectDAO;
 	private final ProjectService projectService;
 	private final AuditService auditService;
 	private final SelfServiceApplicationConfiguration configuration;
 
 	@Inject
-	public UserGroupServiceImpl(UserGroupDao userGroupDao, UserRoleDao userRoleDao, ProjectDAO projectDAO, ProjectService projectService, AuditService auditService,
-								SelfServiceApplicationConfiguration configuration) {
+	public UserGroupServiceImpl(UserGroupDAO userGroupDao, UserRoleDAO userRoleDao, ProjectDAO projectDAO, ProjectService projectService, AuditService auditService,
+	                            SelfServiceApplicationConfiguration configuration) {
 		this.userGroupDao = userGroupDao;
 		this.userRoleDao = userRoleDao;
 		this.projectDAO = projectDAO;
@@ -103,10 +104,10 @@
 					.flatMap(Collection::stream)
 					.filter(g -> g.equalsIgnoreCase(group))
 					.findAny()
-					.orElseThrow(() -> new DlabException(String.format("User %s doesn't have appropriate permission", userInfo.getName())));
+					.orElseThrow(() -> new DlabException(String.format(INAPPROPRIATE_PERMISSION, userInfo.getName())));
 			updateGroup(userInfo.getName(), group, roles, users);
 		} else {
-			throw new DlabException(String.format("User %s doesn't have appropriate permission", userInfo.getName()));
+			throw new DlabException(String.format(INAPPROPRIATE_PERMISSION, userInfo.getName()));
 		}
 	}
 
@@ -140,7 +141,7 @@
 					.filter(userGroup -> groups.contains(userGroup.getGroup()) && !containsAdministrationPermissions(userGroup))
 					.collect(Collectors.toList());
 		} else {
-			throw new DlabException(String.format("User %s doesn't have appropriate permission", user.getName()));
+			throw new DlabException(String.format(INAPPROPRIATE_PERMISSION, user.getName()));
 		}
 	}
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java
index d74c68d..aa7995f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.servlet.guacamole;
 
 import com.epam.dlab.auth.UserInfo;
@@ -8,6 +27,7 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.inject.Inject;
 import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.guacamole.net.GuacamoleTunnel;
 import org.apache.guacamole.servlet.GuacamoleHTTPTunnelServlet;
@@ -19,6 +39,7 @@
 import javax.ws.rs.core.HttpHeaders;
 import java.io.IOException;
 
+@Slf4j
 public class GuacamoleServlet extends GuacamoleHTTPTunnelServlet {
 	private static final String UNAUTHORIZED_MSG = "User is not authenticated";
 	private static final String DLAB_PREFIX = "DLab-";
@@ -39,12 +60,11 @@
 		try {
 			final String authorization = request.getHeader(DLAB_PREFIX + HttpHeaders.AUTHORIZATION);
 			final String credentials = StringUtils.substringAfter(authorization, AUTH_HEADER_PREFIX);
-			final UserInfo userInfo =
-					securityDAO.getUser(credentials)
-							.orElseThrow(() -> new DlabAuthenticationException(UNAUTHORIZED_MSG));
+			final UserInfo userInfo = getUserInfo(credentials);
 			final CreateTerminalDTO createTerminalDTO = mapper.readValue(request.getReader(), CreateTerminalDTO.class);
 			return guacamoleService.getTunnel(userInfo, createTerminalDTO.getHost(), createTerminalDTO.getEndpoint());
 		} catch (IOException e) {
+			log.error("Cannot read request body. Reason {}", e.getMessage(), e);
 			throw new DlabException("Can not read request body: " + e.getMessage(), e);
 		}
 	}
@@ -54,10 +74,21 @@
 		try {
 			super.handleTunnelRequest(request, response);
 		} catch (DlabAuthenticationException e) {
+			log.error(UNAUTHORIZED_MSG, e);
 			sendError(response, HttpStatus.SC_UNAUTHORIZED, HttpStatus.SC_UNAUTHORIZED, UNAUTHORIZED_MSG);
 		}
 	}
 
+	private UserInfo getUserInfo(String credentials) {
+		try {
+			return securityDAO.getUser(credentials)
+					.orElseThrow(() -> new DlabAuthenticationException(UNAUTHORIZED_MSG));
+		} catch (DlabAuthenticationException e) {
+			log.error(UNAUTHORIZED_MSG, e);
+			throw new DlabException(UNAUTHORIZED_MSG);
+		}
+	}
+
 	@Data
 	private static class CreateTerminalDTO {
 		private String host;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java
index 7f0bbf7..a42a76d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java
@@ -22,21 +22,21 @@
 import java.util.List;
 
 public class CSVFormatter {
+	public static final char SEPARATOR = ',';
 
-    private CSVFormatter() {
-    }
+	private CSVFormatter() {
+	}
 
-    public static final char SEPARATOR = ',';
 
-    public static String formatLine(List<String> values, char separator) {
-        boolean first = true;
-        StringBuilder builder = new StringBuilder();
-        for (String value : values) {
-            if (!first) {
-                builder.append(separator);
-            }
-            builder.append(followCsvStandard(value));
-            first = false;
+	public static String formatLine(List<String> values, char separator) {
+		boolean first = true;
+		StringBuilder builder = new StringBuilder();
+		for (String value : values) {
+			if (!first) {
+				builder.append(separator);
+			}
+			builder.append(followCsvStandard(value));
+			first = false;
         }
         return builder.append(System.lineSeparator()).toString();
     }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
index 63fc62c..94e1957 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.util;
 
 import com.epam.dlab.exceptions.DlabException;
@@ -7,16 +26,16 @@
 
 public class KeycloakUtil {
 
-    public static IDToken parseToken(String encoded) {
-        try {
-            String[] parts = encoded.split("\\.");
-            if (parts.length < 2 || parts.length > 3) {
-                throw new IllegalArgumentException("Parsing error");
-            }
-            byte[] bytes = Base64Url.decode(parts[1]);
-            return JsonSerialization.readValue(bytes, IDToken.class);
-        } catch (Exception e) {
-            throw new DlabException("Can not parse token due to: " + e.getMessage());
-        }
-    }
+	public static IDToken parseToken(String encoded) {
+		try {
+			String[] parts = encoded.split("\\.");
+			if (parts.length < 2 || parts.length > 3) {
+				throw new IllegalArgumentException("Parsing error");
+			}
+			byte[] bytes = Base64Url.decode(parts[1]);
+			return JsonSerialization.readValue(bytes, IDToken.class);
+		} catch (Exception e) {
+			throw new DlabException("Can not parse token due to: " + e.getMessage(), e);
+		}
+	}
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java
index 1e8be9b..fb10ed2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java
@@ -34,8 +34,7 @@
 public @interface LibNameValid {
 
 
-	String message() default "Wrong library name format. Should be <groupId>:<artifactId>:<versionId>. E.g. io" +
-			".dropwizard:dropwizard-core:1.3.5";
+	String message() default "Wrong library name format. Should be <groupId>:<artifactId>:<versionId>";
 
 	Class<?>[] groups() default {};
 
diff --git a/services/self-service/src/main/resources/webapp/browserslist b/services/self-service/src/main/resources/webapp/browserslist
index 8084853..6382d82 100644
--- a/services/self-service/src/main/resources/webapp/browserslist
+++ b/services/self-service/src/main/resources/webapp/browserslist
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
 # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
 # For additional information regarding the format and rule options, please see:
 # https://github.com/browserslist/browserslist#queries
@@ -9,4 +30,4 @@
 last 2 versions
 Firefox ESR
 not dead
-not IE 9-11 # For IE 9-11 support, remove 'not'.
\ No newline at end of file
+not IE 9-11 # For IE 9-11 support, remove 'not'.
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html
index c555280..591cdee 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html
@@ -49,8 +49,13 @@
                   <input type="number" (keypress)="CheckUtils.numberOnly($event)" min="0"
                     placeholder="Enter limit, in USD" formControlName="budget">
                   <span class="error"
-                    *ngIf="manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('overrun')">Per-user
-                    quotes cannot be greater than total budget</span>
+                    *ngIf="manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('overrun') &&
+                     !manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('max')"
+                  >
+                    Projects budget cannot be higher than total budget
+                  </span>
+                  <span class="error"
+                        *ngIf="manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('max')">Project budget cannot be higher than 1000000000</span>
                 </div>
               </mat-list-item>
             </div>
@@ -60,10 +65,15 @@
                 <div class="username ellipsis">
                   <span class="ellipsis">Total budget</span>
                 </div>
+                <div class="period">
+                </div>
                 <div class="quotes">
                   <input type="number" (keypress)="CheckUtils.numberOnly($event)" formControlName="total"
                          placeholder="Enter total budget, in USD">
-                  <span class="error" *ngIf="manageUsersForm?.controls['total'].hasError('overrun')">Total budget cannot be lower than a sum of users quotes</span>
+                  <span class="error" *ngIf="manageUsersForm?.controls['total'].hasError('overrun')
+                  && !manageUsersForm?.controls['total'].hasError('max')">Total budget cannot be lower than a sum of projects quotes</span>
+                  <span class="error"
+                        *ngIf="manageUsersForm?.controls['total'].hasError('max')">Total budget cannot be higher than 1000000000</span>
                 </div>
               </mat-list-item>
             </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss
index 4e1aadf..1cea435 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss
@@ -50,8 +50,9 @@
     .error {
       position: absolute;
       left: 0;
-      top: 34px;
+      top: 37px;
       font-family: 'Open Sans', sans-serif;
+      font-size: 11px;
     }
   }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts
index 848daf7..4aa2871 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts
@@ -60,10 +60,12 @@
       this.isFormChanged = JSON.stringify(this.initialFormState) === JSON.stringify(this.manageUsersForm.value);
       if ((this.getCurrentTotalValue() && this.getCurrentTotalValue() >= this.getCurrentUsersTotal())) {
         this.manageUsersForm.controls['projects']['controls'].forEach(v => {
-            v.controls['budget'].setErrors(null);
+            v.controls['budget'].errors &&
+            'max' in v.controls['budget'].errors ? null : v.controls['budget'].setErrors(null);
         }
         );
-        this.manageUsersForm.controls['total'].setErrors(null);
+        this.manageUsersForm.controls['total'].errors &&
+        this.manageUsersForm.controls['total'].errors ? null : this.manageUsersForm.controls['total'].setErrors(null);
       }
     });
   }
@@ -99,14 +101,14 @@
     this.manageUsersForm.setControl('projects',
       this._fb.array((this.data.projectsList || []).map((x: any) => this._fb.group({
         project: x.name,
-        budget: [x.budget.value, [ this.userValidityCheck.bind(this)]],
+        budget: [x.budget.value, [ Validators.max(1000000000), this.userValidityCheck.bind(this)]],
         monthlyBudget: x.budget.monthlyBudget,
       }))));
   }
 
   private initForm(): void {
     this.manageUsersForm = this._fb.group({
-      total: [null, [Validators.min(0), this.totalValidityCheck.bind(this)]],
+      total: [null, [Validators.min(0), this.totalValidityCheck.bind(this), Validators.max(1000000000)]],
       projects: this._fb.array([this._fb.group({ project: '', budget: null, status: '' })])
     });
   }
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html
index bf3ef16..8d2df70 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html
@@ -122,7 +122,7 @@
             <span [hidden]="filtering && filterForm.statuses.length > 0 && !collapsedFilterRow">more_vert</span>
           </i>
         </button> </th>
-      <td mat-cell *matCellDef="let element" class="ani status label-header" >
+      <td mat-cell *matCellDef="let element" class="ani status" >
         <span ngClass="{{element.status || ''}}">{{ element.status }}</span>
       </td>
     </ng-container>
@@ -231,7 +231,7 @@
     </ng-container>
     <ng-container matColumnDef="type-filter" sticky>
       <th mat-header-cell *matHeaderCellDef class="filter-row-item">
-        <input placeholder="Filter by environment type" type="text" class="form-control filter-field"
+        <input placeholder="Filter by environment name" type="text" class="form-control filter-field"
           [value]="filterForm.type" (input)="filterForm.type = $event.target['value']"/>
       </th>
     </ng-container>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss
index 00f13e0..9d9f4b5 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss
@@ -19,13 +19,17 @@
 
 .data-grid {
   &.management {
+    .filter-row-item{
+      padding: 5px;
+    }
+
     .settings{
       min-width: 7%;
     }
     .mat-column-checkbox{
       padding-left: 10px;
       padding-right: 0px;
-      min-width: 68px;
+      min-width: 38px;
       &.label-header{
 
       }
@@ -57,7 +61,6 @@
 
     .resources {
       width: 24%;
-      padding: 5px;
     }
 
     .settings {
@@ -67,6 +70,7 @@
     }
     .actions {
       margin-top: 0px;
+      padding-right: 10px;
       .label{
         padding-right: 5px;
       }
@@ -76,6 +80,53 @@
 
     }
 
+    .label-header{
+      padding-left: 15px;
+      height: 56px;
+
+      .ar{
+        left: 21px;
+        top: 2px;
+      }
+      .settings{
+        min-width: 7%;
+      }
+      &.mat-column-checkbox{
+        z-index: 12 !important;
+        padding-left: 10px;
+        .ar{
+          position: absolute;
+          top: 10px;
+        }
+      }
+      &.user{
+        z-index: 11 !important;
+      }
+      &.type{
+        z-index: 10 !important;
+      }
+
+      &.project {
+        z-index: 9 !important;
+      }
+
+      &.shape {
+        z-index: 8 !important;
+      }
+
+      &.status {
+        z-index: 7 !important;
+      }
+
+      &.resources {
+        z-index: 6 !important;
+      }
+
+      &.actions {
+        z-index: 5 !important;
+      }
+    }
+
     .dashboard_table_body {
       td:first-child {
         cursor: default;
@@ -105,6 +156,7 @@
 
   td:not(.info) {
     padding: 5px;
+    padding-left: 20px;
   }
 
   .header-row {
@@ -114,7 +166,6 @@
       padding-top: 14px;
       vertical-align: super !important;
       padding-left: 5px;
-      font-size: 12px;
     }
     .actions {
       text-align: right;
@@ -127,6 +178,11 @@
 
   .filter-row {
     background: inherit;
+
+    .filter-field{
+      font-size: 13px;
+      padding-left: 15px;
+    }
   }
 }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html
index 02ab5b9..187a3ee 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html
@@ -67,7 +67,7 @@
       </button> -->
     </div>
     <button mat-raised-button class="butt" (click)="refreshGrid()">
-      <i class="material-icons">autorenew</i>Refresh
+      <i class="material-icons refresh-icon">autorenew</i>Refresh
     </button>
   </div>
   <mat-divider></mat-divider>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
index b985d94..9050ff6 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
@@ -26,7 +26,15 @@
 
   .name {
     width: 25%;
-    padding: 10px 0 10px 24px;
+    padding: 20px 0 10px 24px;
+  }
+
+  th.name{
+    padding-top: 10px;
+  }
+
+  .mat-header-row{
+    padding-top: 12px;
   }
 
   .endpoints {
@@ -77,7 +85,6 @@
 
     &.mat-header-cell{
       padding-top: 19px;
-      padding-right: 13px;
       color: rgba(0,0,0,.54);
     }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
index 3be7a10..98ea6aa 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
@@ -39,7 +39,7 @@
         </span>
       </button>
       <button mat-raised-button class="butt" (click)="refreshGrid()" [hidden]="!projectList.length">
-        <i class="material-icons">autorenew</i>Refresh
+        <i class="material-icons refresh-icon">autorenew</i>Refresh
       </button>
     </div>
   </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts b/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts
index 4ae3899..d1ae984 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts
@@ -18,7 +18,7 @@
  */
 
 import { Injectable } from '@angular/core';
-import { BehaviorSubject } from 'rxjs';
+import {BehaviorSubject} from 'rxjs';
 import {
   HttpInterceptor,
   HttpRequest,
@@ -47,6 +47,7 @@
   intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
     return next.handle(request).pipe(
       catchError(error => {
+        if (error.error && error.error.message && error.error.message.indexOf('query param artifact') !== -1) return _throw(error);
         if (error instanceof HttpErrorResponse) {
           switch ((<HttpErrorResponse>error).status) {
             case HTTP_STATUS_CODES.UNAUTHORIZED:
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts
index 5fe18ad..8c6fb0b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts
@@ -22,7 +22,7 @@
 @Pipe({ name: 'keys' })
 
 export class KeysPipe implements PipeTransform {
-  transform(value, args: string[]): any {
+  transform(value): any {
     const keys = [];
     for (const key in value) {
       keys.push({ key: key, value: value[key]});
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts
index a21da90..32670b0 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts
@@ -22,7 +22,7 @@
 @Pipe({ name: 'underscoreless' })
 
 export class UnderscorelessPipe implements PipeTransform {
-  transform(value, args: string[]): any {
+  transform(value): any {
     return value.replace(/_/g, ' ');
   }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
index 2c0e661..39e92af 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
@@ -78,6 +78,7 @@
   private static readonly ENDPOINT = 'endpoint';
   private static readonly ENDPOINT_CONNECTION = 'endpoint_connection';
   private static readonly AUDIT = 'audit';
+  private static readonly QUOTA = 'quota';
 
   private requestRegistry: Dictionary<string>;
 
@@ -307,6 +308,13 @@
       data);
   }
 
+  public buildGetQuotaStatus(): Observable<any> {
+    return this.buildRequest(HTTPMethod.GET,
+      this.requestRegistry.Item(ApplicationServiceFacade.QUOTA),
+        null
+    );
+  }
+
   public buildRunEdgeNodeRequest(): Observable<any> {
     return this.buildRequest(HTTPMethod.POST,
       this.requestRegistry.Item(ApplicationServiceFacade.EDGE_NODE_START),
@@ -723,6 +731,7 @@
     // billing report
     this.requestRegistry.Add(ApplicationServiceFacade.BILLING, '/api/billing/report');
     this.requestRegistry.Add(ApplicationServiceFacade.DOWNLOAD_REPORT, '/api/billing/report/download');
+    this.requestRegistry.Add(ApplicationServiceFacade.QUOTA, '/api/billing/quota');
 
     // project
     this.requestRegistry.Add(ApplicationServiceFacade.PROJECT, '/api/project');
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts
index 1d54792..520f623 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { Injectable } from '@angular/core';
 import {ApplicationServiceFacade} from './applicationServiceFacade.service';
 import {catchError, map} from 'rxjs/operators';
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
index 4d2fe83..45982eb 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { Injectable } from '@angular/core';
 import {Observable} from 'rxjs';
 import {catchError, map} from 'rxjs/operators';
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
index 02004f3..09f902e 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
@@ -84,6 +84,14 @@
         catchError(ErrorUtils.handleServiceError));
   }
 
+  public getQuotaStatus(): Observable<{}> {
+    return this.applicationServiceFacade
+      .buildGetQuotaStatus()
+      .pipe(
+        map(response => response),
+        catchError(ErrorUtils.handleServiceError));
+  }
+
   public runEdgeNode(): Observable<{}> {
     return this.applicationServiceFacade
       .buildRunEdgeNodeRequest()
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts
index 2119b1a..38d18bc 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts
@@ -49,7 +49,6 @@
 
   public getAvailableDependencies(data): Observable<{}> {
     const body = `/maven?artifact=${data}`;
-
     return this.applicationServiceFacade
       .buildGetAvailableDependenciest(body)
       .pipe(
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts b/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts
index 8246bba..981e661 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts
@@ -24,6 +24,6 @@
   url: '[a-zA-Z0-9.://%#&\\.@:%-_\+~#=]*\.[^\s]*[a-zA-Z0-9]/+',
   nodeCountPattern: '^[1-9]\\d*$',
   integerRegex: '^[0-9]*$',
-  folderRegex: /^[a-zA-Z0-9!@$%^&*()_+\-=\[\]{};':|,.<>~` ]*$/,
+  folderRegex: /^[a-zA-Z0-9!@$^&*()_+\-=\[\]{};':|,.<>~` ]*$/,
   fullUrl: /^(http?|ftp|https):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+([.:])(\d{4}|com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*\/$/
 };
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html
index a6125f9..cfdaa59 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html
@@ -17,11 +17,25 @@
   ~ under the License.
   -->
 
-<section class="audit-table-wrapper">
+<section class="audit-table-wrapper" id="scrolling">
   <table mat-table [dataSource]="auditData" class="data-grid audit mat-elevation-z6">
 
+    <ng-container matColumnDef="date">
+      <th mat-header-cell *matHeaderCellDef class="th_date label-header">
+        <div class="label"><span class="text">Date</span></div>
+        <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+          <i class="material-icons">
+            <span>more_vert</span>
+          </i>
+        </button>
+      </th>
+      <td mat-cell *matCellDef="let element"> {{element.timestamp | date: 'dd/MM/yyyy hh:mm:ss aa'}} </td>
+      <td mat-footer-cell *matFooterCellDef class="table-footer">
+      </td>
+    </ng-container>
+
     <ng-container matColumnDef="user">
-      <th mat-header-cell *matHeaderCellDef class="th_user label-header">
+      <th mat-header-cell *matHeaderCellDef class="th_user label-header" [ngStyle]="{'z-index': 99}">
         <div class="label"><span class="audit-user"> User</span></div>
         <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
           <i class="material-icons">
@@ -34,6 +48,28 @@
       <td mat-footer-cell *matFooterCellDef class="table-footer"></td>
     </ng-container>
 
+    <ng-container matColumnDef="action">
+      <th mat-header-cell *matHeaderCellDef class="th_action label-header" [ngStyle]="{'zIndex': 98, 'display': 'sticky'}">
+        <div class="label">
+          <span class="text"> Action </span>
+        </div>
+        <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+          <i class="material-icons">
+            <span>more_vert</span>
+          </i>
+        </button>
+      </th>
+      <td mat-cell *matCellDef=" let element" class="th_action">
+        <div class="action-wrapper">
+          <span class="ellipsis">{{element.action | convertaction }}</span>
+          <div class="audit-info" (click)="openActionInfo(element)" *ngIf="element.info">
+            <i class="material-icons">info</i>
+          </div>
+        </div>
+      </td>
+      <td mat-footer-cell *matFooterCellDef  class="table-footer"></td>
+    </ng-container>
+
     <ng-container matColumnDef="project">
       <th mat-header-cell *matHeaderCellDef class="th_project label-header">
         <div class="label"><span class="text">Project</span></div>
@@ -125,32 +161,6 @@
       </td>
     </ng-container>
 
-    <ng-container matColumnDef="action">
-      <th mat-header-cell *matHeaderCellDef class="th_action label-header">
-        <div class="label">
-          <span class="text"> Action </span>
-        </div>
-      </th>
-      <td mat-cell *matCellDef=" let element">
-        <div class="action-wrapper">
-          <span>{{element.action | convertaction }}</span>
-          <div class="audit-info" (click)="openActionInfo(element)" *ngIf="element.info">
-            <i class="material-icons">info</i>
-          </div>
-        </div>
-      </td>
-      <td mat-footer-cell *matFooterCellDef  class="table-footer"></td>
-    </ng-container>
-
-    <ng-container matColumnDef="date">
-      <th mat-header-cell *matHeaderCellDef class="th_date label-header">
-        <div class="label"><span class="text">Date</span></div>
-      </th>
-      <td mat-cell *matCellDef="let element"> {{element.timestamp | date: 'dd/MM/yyyy hh:mm:ss aa'}} </td>
-      <td mat-footer-cell *matFooterCellDef class="table-footer">
-      </td>
-    </ng-container>
-
     <ng-container matColumnDef="buttons">
       <th mat-header-cell *matHeaderCellDef class="th_buttons label-header"></th>
       <td mat-cell *matCellDef="let element"></td>
@@ -189,16 +199,17 @@
 
     <ng-container matColumnDef="actions-filter">
       <th mat-header-cell *matHeaderCellDef class="filter-row-item">
+
       </th>
     </ng-container>
 
-    <ng-container matColumnDef="action-filter" stickyEnd>
-      <th mat-header-cell *matHeaderCellDef>
+    <ng-container matColumnDef="date-filter">
+      <th mat-header-cell *matHeaderCellDef class="filter-row-item">
       </th>
     </ng-container>
 
     <ng-container matColumnDef="filter-buttons" stickyEnd>
-      <th mat-header-cell *matHeaderCellDef>
+      <th mat-header-cell *matHeaderCellDef class="filter-row-item">
         <div class="actions audit-actions">
           <button mat-icon-button class="btn reset" (click)="resetFilterConfigurations()">
             <i class="material-icons">close</i>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss
index 29250ea..493e094 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss
@@ -19,12 +19,16 @@
 
 .audit-table-wrapper {
   width: 100%;
+  max-height: calc(100vh - 130px);
+  overflow: auto;
+  box-shadow: 0 3px 5px -1px rgba(0,0,0,.2), 0 6px 10px 0 rgba(0,0,0,.14), 0 1px 18px 0 rgba(0,0,0,.12);
 
   .audit {
     width: 100%;
     min-width: 1100px;
     overflow: auto;
     border-collapse: inherit;
+    box-shadow: none;
 
     .mat-cell {
       vertical-align: middle;
@@ -33,36 +37,39 @@
     tr {
       .th_user {
         width: 19%;
+        z-index: 9 !important;
       }
 
       .th_action {
         width: 11%;
-        .label{
-          padding-bottom: 10px;
-        }
+        z-index: 8 !important;
+        max-width: 250px;
       }
 
       .th_date {
         width: 14%;
-        .label{
-          padding-bottom: 10px;
-        }
+        z-index: 10 !important;
+        padding-left: 0;
       }
 
-      .th_project{
+      .th_project {
         width: 11%;
+        z-index: 7 !important;
       }
 
-      .th_resource{
+      .th_resource {
         width: 14%;
+        z-index: 5 !important;
       }
 
-      .th_resource-type{
+      .th_resource-type {
         width: 14%;
+        z-index: 6 !important;
       }
 
-      .th_buttons{
+      .th_buttons {
         width: 6%;
+        z-index: 4 !important;
       }
 
       th {
@@ -76,7 +83,7 @@
 
       td {
         font-size: 13px;
-        padding-left: 15px;
+        padding-left: 20px;
 
         &.info {
           z-index: 1 !important;
@@ -189,7 +196,7 @@
         vertical-align: super !important;
 
         .text {
-          padding-left: 15px;
+          padding-left: 20px;
         }
       }
 
@@ -222,10 +229,16 @@
     }
   }
 
-  .action-wrapper{
+  .action-wrapper {
     display: flex;
     align-items: center;
-    .audit-info{
+    justify-content: space-between;
+    padding-right: 10px;
+    span{
+      max-width: 85%;
+    }
+
+    .audit-info {
       color: lightgray;
       cursor: pointer;
       margin-left: 5px;
@@ -239,48 +252,56 @@
 
     .dropdown-multiselect {
       button {
-        font-size: 14px;
+        font-size: 13px;
         height: 34px;
         padding: 7px 20px;
       }
     }
   }
-  .user-col{
-    padding-left: 5px;
-  }
 }
 
-.selected-items-wrapper{
+.selected-items-wrapper {
   display: flex;
   align-items: center;
-  .select-wrapper{
+
+  .select-wrapper {
     margin-left: 20px;
     width: 80px;
   }
 }
 
-.pagination-wrapper{
+.pagination-wrapper {
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding-right: 30px;
-  .navigation-butts{
-    cursor: pointer;
-    .not-active{
+
+  .not-active {
+    .navigation-butts {
       color: lightgray;
     }
   }
-}
 
-.audit-actions{
+    .navigation-butts {
+      cursor: pointer;
+      color: #35afd5;
+
+      .not-active {
+        color: lightgray;
+      }
+    }
+  }
+
+
+.audit-actions {
   text-align: right;
 }
 
-.audit-user{
-  padding-left: 19px;
+.audit-user {
+  padding-left: 20px;
 }
 
-.table-footer{
+.table-footer {
   position: sticky;
   bottom: 0;
   background: inherit;
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
index 4dc5aae..953aeae 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import {Component, Inject, OnInit} from '@angular/core';
+import {Component, EventEmitter, Inject, OnInit, Output} from '@angular/core';
 import {FilterAuditModel} from '../filter-audit.model';
 import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';
 import {AuditService} from '../../../core/services/audit.service';
@@ -43,7 +43,7 @@
 export class AuditGridComponent implements OnInit {
   public auditData: Array<AuditItem>;
   public displayedColumns: string[] = ['date', 'user', 'action', 'project', 'resource-type', 'resource', 'buttons'];
-  public displayedFilterColumns: string[] = ['action-filter', 'user-filter', 'actions-filter',  'project-filter', 'resource-type-filter', 'resource-filter', 'filter-buttons'];
+  public displayedFilterColumns: string[] = ['date-filter', 'user-filter', 'actions-filter',  'project-filter', 'resource-type-filter', 'resource-filter', 'filter-buttons'];
   public collapseFilterRow: boolean = false;
   public filterConfiguration: FilterAuditModel = new FilterAuditModel([], [], [], [], [], '', '');
   public filterAuditData: FilterAuditModel = new FilterAuditModel([], [], [], [], [], '', '');
@@ -55,6 +55,8 @@
   private copiedFilterAuditData: FilterAuditModel;
   public isNavigationDisabled: boolean;
 
+  @Output() resetDateFilter: EventEmitter<any> = new EventEmitter();
+
 
   constructor(
     public dialogRef: MatDialogRef<AuditInfoDialogComponent>,
@@ -157,6 +159,7 @@
 
   public resetFilterConfigurations(): void {
     this.filterAuditData = FilterAuditModel.getDefault();
+    this.resetDateFilter.emit();
     this.buildAuditGrid(true);
   }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html
index 3562b08..468ebb3 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html
@@ -16,7 +16,7 @@
   ~ specific language governing permissions and limitations
   ~ under the License.
   -->
-<section class="toolbar">
+<section class="audit-toolbar">
   <div class="info_color">
     <div class="general" *ngIf="reportData">
       <div><span>Service base name: </span><strong>{{ reportData.sbn }}</strong></div>
@@ -35,7 +35,7 @@
   </div>
   <div class="action-butt">
     <button mat-raised-button class="butt" (click)="rebuild($event)">
-      <i class="material-icons">autorenew</i>Refresh
+      <i class="material-icons refresh-icon">autorenew</i>Refresh
     </button>
   </div>
 </section>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss
index 744bfdc..0bf0071 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-section.toolbar {
+section.audit-toolbar {
   display: flex;
   justify-content: space-between;
   font-weight: 300;
@@ -62,79 +62,5 @@
   }
 }
 
-/* daterangepicker themes */
-#range-picker {
-  margin-top: 5px;
-}
 
-#range-picker path#Shape {
-  fill: #36afd5;
-}
 
-#range-picker .ng-daterangepicker,
-#range-picker .ng-daterangepicker.is-active,
-#range-picker .ng-daterangepicker .calendar {
-  border: none;
-  border-radius: 0;
-  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
-}
-
-#range-picker .ng-daterangepicker .calendar::after {
-  border-top: 1px solid rgba(234, 234, 234, 0.64);
-  border-left: 1px solid rgba(234, 234, 234, 0.64);
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button {
-  background: #fff;
-  color: #718ba6;
-  border: none;
-  border-radius: 0px;
-  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12)
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active,
-#range-picker .ng-daterangepicker .input-section .label-txt {
-  color: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-num.is-active,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days .day-num:hover {
-  background: #35afd5;
-  background-clip: padding-box;
-
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-names,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days {
-  width: 310px;
-}
-
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-first-weekday,
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-last-weekday {
-  background-clip: padding-box;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day.is-within-range {
-  background: #e9f8fc
-}
-
-#range-picker .ng-daterangepicker .input-section .cal-icon svg path {
-  fill: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt {
-  color: #718ba6;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched,
-#range-picker .ng-daterangepicker .input-section .label-txt.untouched {
-  color: #fff;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched::after {
-  content: 'Select date';
-  position: absolute;
-  top: 22px;
-  left: 34px;
-  color: #718ba6;
-}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts
index cc4933e..f1a889a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts
@@ -61,31 +61,37 @@
   }
 
   ngOnInit() {
-    // if (localStorage.getItem('report_period')) {
-    //   const availableRange = JSON.parse(localStorage.getItem('report_period'));
-    //   this.availablePeriodFrom = availableRange.start_date;
-    //   this.availablePeriodTo = availableRange.end_date;    }
-    // this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
-    //   this.healthStatus = result;
-    // }));
+    this.setInitDatapickerConfig();
   }
 
   ngAfterViewInit() {
     this.clearRangePicker();
   }
 
+  private setInitDatapickerConfig() {
+    const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+    const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
+    labels[0].innerHTML = 'From date';
+    labels[1].innerHTML = 'To date';
+    for (let label = 0; label < rangeLabels.length; ++label) {
+      rangeLabels[label].classList.add('d-none');
+      rangeLabels[label].classList.add('untouched');
+    }
+  }
+
   setDateRange() {
     const availableRange = JSON.parse(localStorage.getItem('report_period'));
+    const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
+    for (let label = 0; label < rangeLabels.length; ++label) {
+      rangeLabels[label].classList.remove('d-none');
 
+    }
     this.availablePeriodFrom = availableRange.start_date;
     this.availablePeriodTo = availableRange.end_date;
   }
 
   clearRangePicker(): void {
-    const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
-
-    for (let label = 0; label < rangeLabels.length; ++label)
-      rangeLabels[label].classList.add('untouched');
+    this.setInitDatapickerConfig();
   }
 
   onChange(dateRange: string): void {
@@ -94,8 +100,14 @@
     for (let label = 0; label < rangeLabels.length; ++label)
       if (rangeLabels[label].classList.contains('untouched')) {
         rangeLabels[label].classList.remove('untouched');
+        rangeLabels[label].classList.remove('d-none');
       }
 
+
+    const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+    labels[0].innerHTML = 'From:';
+    labels[1].innerHTML = 'To:';
+
     const reportDateRange = dateRange.split('-');
     this.setRangeOption.emit({
       start_date: reportDateRange[0].split('/').join('-'),
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts
index 6f48b71..af3919d 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts
@@ -42,7 +42,7 @@
     <audit-toolbar (rebuildAudit)="rebuildAuditGrid()" (setRangeOption) = setRangeOption($event)>
     </audit-toolbar>
     <mat-divider></mat-divider>
-    <dlab-audit-grid></dlab-audit-grid>
+    <dlab-audit-grid (resetDateFilter)="resetDatepicker()"></dlab-audit-grid>
   </div>
 
   `,
@@ -96,6 +96,10 @@
   }
 
   public setRangeOption(event) {
-    this.auditGrid.setAvaliblePeriod(event)
+    this.auditGrid.setAvaliblePeriod(event);
+  }
+
+  public resetDatepicker() {
+    this.auditToolbar.clearRangePicker();
   }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts
index b4b6845..b1b6a65 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 export class FilterAuditModel {
 
   static getDefault(): FilterAuditModel {
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html
index 9366725..1481d53 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html
@@ -17,8 +17,22 @@
   ~ under the License.
   -->
 
-<section class="table-wrapper">
-  <table mat-table [dataSource]="reportData" class="data-grid reporting mat-elevation-z6">
+<div class="wrapper">
+<section class="table-wrapper" id="scrolling" #tableWrapper (scroll)="scrollTable($event)">
+
+<!--  <div class="navigation-btn">-->
+<!--    <div class="left">-->
+<!--      <button mat-fab aria-label="Scroll left">-->
+<!--        <mat-icon>keyboard_arrow_left</mat-icon>-->
+<!--      </button>-->
+<!--    </div>-->
+<!--    <div class="right">-->
+<!--      <button mat-fab aria-label="Scroll right">-->
+<!--        <mat-icon>keyboard_arrow_right</mat-icon>-->
+<!--      </button>-->
+<!--    </div>-->
+<!--  </div>-->
+  <table mat-table [dataSource]="reportData" class="data-grid reporting mat-elevation-z6" #table>
 
     <ng-container matColumnDef="name">
       <th mat-header-cell *matHeaderCellDef class="env_name label-header">
@@ -36,13 +50,15 @@
 
     <ng-container matColumnDef="user">
       <th mat-header-cell *matHeaderCellDef class="th_user label-header">
-        <div class="sort">
-          <div class="sort-arrow up" (click)="sortBy('user', 'down')" [ngClass]="{'active': !!this.active['userdown']}"></div>
-          <div class="sort-arrow down" (click)="sortBy('user', 'up')" [ngClass]="{'active': !!this.active['userup']}"></div>
-        </div>
+
         <div class="label">
+          <div class="sort sort-user">
+            <div class="sort-arrow up" (click)="sortBy('user', 'down')" [ngClass]="{'active': !!this.active['userdown']}"></div>
+            <div class="sort-arrow down" (click)="sortBy('user', 'up')" [ngClass]="{'active': !!this.active['userup']}"></div>
+          </div>
           <span class="text"> User </span>
         </div>
+
         <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
           <i class="material-icons">
             <span *ngIf="filteredReportData.users.length > 0; else user_filtered">filter_list</span>
@@ -56,11 +72,15 @@
 
     <ng-container matColumnDef="project">
       <th mat-header-cell *matHeaderCellDef class="th_project label-header">
-        <div class="sort">
-          <div class="sort-arrow up" (click)="sortBy('project', 'down')" [ngClass]="{'active': !!this.active['projectdown']}"></div>
-          <div class="sort-arrow down" (click)="sortBy('project', 'up')" [ngClass]="{'active': !!this.active['projectup']}"></div>
+
+        <div class="label">
+          <div class="sort sort-project">
+            <div class="sort-arrow up" (click)="sortBy('project', 'down')" [ngClass]="{'active': !!this.active['projectdown']}"></div>
+            <div class="sort-arrow down" (click)="sortBy('project', 'up')" [ngClass]="{'active': !!this.active['projectup']}"></div>
+          </div>
+          <span class="text">Project</span>
         </div>
-        <div class="label"><span class="text">Project</span></div>
+
         <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
           <i class="material-icons">
             <span *ngIf="filteredReportData.projects.length > 0; else project_filtered">filter_list</span>
@@ -141,6 +161,21 @@
       <td mat-footer-cell *matFooterCellDef class="table-footer"></td>
     </ng-container>
 
+    <ng-container matColumnDef="empty">
+      <th mat-header-cell *matHeaderCellDef class="th_empty label-header">
+      </th>
+      <td mat-cell *matCellDef="let element">
+      </td>
+      <td mat-footer-cell *matFooterCellDef class="table-footer total-cost" [colSpan]="2">
+        <span class="strong">
+            Total <span *ngIf="reportData?.length"> {{ fullReport['total_cost'] }}
+          {{ fullReport['currency'] }}</span>
+        </span>
+      </td>
+    </ng-container>
+
+
+
     <ng-container matColumnDef="charge" stickyEnd>
       <th mat-header-cell *matHeaderCellDef class="th_charges label-header">
         <div class="label">
@@ -155,17 +190,17 @@
       <td mat-cell *matCellDef="let element">
         {{ element.cost }} {{ element['currency'] }}
       </td>
-      <td mat-footer-cell *matFooterCellDef class="table-footer total-cost">
-        Total <span *ngIf="reportData?.length"> {{ fullReport['total_cost'] }}
-          {{ fullReport['currency'] }}</span>
+      <td mat-footer-cell *matFooterCellDef class="table-footer total-cost d-none">
       </td>
     </ng-container>
 
     <!-- ----------------FILTER -->
     <ng-container matColumnDef="name-filter">
       <th mat-header-cell *matHeaderCellDef class="filter-row-item">
-        <input #nameFilter type="text" placeholder="Filter by environment name" class="form-control filter-field"
-          [value]="filtered?.dlab_id" (input)="filteredReportData.dlab_id = $event.target['value']" />
+        <div class="input-wrapper">
+          <input #nameFilter type="text" placeholder="Filter by environment name" class="form-control filter-field"
+                 [value]="filtered?.dlab_id" (input)="filteredReportData.dlab_id = $event.target['value']" />
+        </div>
       </th>
     </ng-container>
     <ng-container matColumnDef="user-filter">
@@ -200,6 +235,12 @@
           [model]="filteredReportData['shapes']"></multi-select-dropdown>
       </th>
     </ng-container>
+
+    <ng-container matColumnDef="empty-filter">
+      <th mat-header-cell *matHeaderCellDef class="filter-row-item">
+      </th>
+    </ng-container>
+
     <ng-container matColumnDef="service-filter">
       <th mat-header-cell *matHeaderCellDef class="filter-row-item">
         <multi-select-dropdown *ngIf="filterConfiguration" (selectionChange)="onUpdate($event)"
@@ -210,7 +251,7 @@
     </ng-container>
     <ng-container matColumnDef="actions" stickyEnd>
       <th mat-header-cell *matHeaderCellDef class="filter-row-item">
-        <div class="actions th_charges">
+        <div class="actions">
           <button mat-icon-button class="btn reset" (click)="resetFiltering(); isFiltered = !isFiltered">
             <i class="material-icons">close</i>
           </button>
@@ -222,8 +263,8 @@
       </th>
     </ng-container>
     <ng-container matColumnDef="placeholder">
-      <td mat-footer-cell *matFooterCellDef colspan="8" class="info">
-        No data available
+      <td mat-footer-cell *matFooterCellDef colspan="9" class="info">
+        <span>No data available</span>
       </td>
     </ng-container>
 
@@ -238,3 +279,19 @@
     <tr [hidden]="reportData?.length" mat-footer-row *matFooterRowDef="['placeholder']"></tr>
   </table>
 </section>
+  <div class="buttons" *ngIf="isScrollButtonsVisible && reportData?.length">
+    <div class="button-container">
+      <button mat-mini-fab aria-label="Scroll left" (click)="sctollTo('left')" [ngClass]="{'not-allowed': tableWrapper.scrollLeft === 0 }">
+        <mat-icon [ngClass]="{'highlight': tableWrapper.scrollLeft !== 0}">keyboard_arrow_left</mat-icon>
+      </button>
+    </div>
+    <div class="button-container">
+      <button mat-mini-fab aria-label="Scroll right"
+              (click)="sctollTo('right')"
+              [ngClass]="{'not-allowed': !isMaxRight }"
+             >
+        <mat-icon [ngClass]="{'highlight': isMaxRight }">keyboard_arrow_right</mat-icon>
+      </button>
+    </div>
+  </div>
+</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss
index 9c4f819..253d354 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss
@@ -19,9 +19,40 @@
 
 .table-wrapper {
   width: 100%;
-
+  display: block;
+  max-height: calc(100vh - 130px);
+  overflow: auto;
+  position: relative;
+  scroll-behavior: smooth;
+  box-shadow: 0 3px 5px -1px rgba(0,0,0,.2), 0 6px 10px 0 rgba(0,0,0,.14), 0 1px 18px 0 rgba(0,0,0,.12);
 }
 
+.wrapper{
+  position: relative;
+
+  .buttons{
+    position: absolute;
+    display: flex;
+    justify-content: space-around;
+    z-index: 1000;
+    bottom: 9px;
+    left: 0;
+    right: 0;
+
+    button{
+      background-color: #fff;
+      box-shadow: none;
+      mat-icon{
+        color: lightgrey;
+        &.highlight{
+          color: #35afd5;
+        }
+      }
+    }
+  }
+}
+
+
 .reporting {
   width: 100%;
   min-width: 1100px;
@@ -35,15 +66,14 @@
   tr {
     th {
       padding-right: 5px;
-      z-index: 2 !important;
       &.th_charges{
-        z-index: 3 !important;
+        z-index: 16 !important;
       }
     }
 
     td {
       font-size: 13px;
-      padding-left: 15px;
+      padding-left: 20px;
 
       &.info {
         z-index: 1 !important;
@@ -66,17 +96,20 @@
 
     &.header-row {
       th {
-        font-size: 11px;
+
         .label{
           padding-left: 0;
+          position: relative;
+          font-size: 13px;
         }
       }
     }
   }
 
   .th_shape {
-    width: 10%;
+    width: 12%;
     min-width: 150px;
+    z-index: 10 !important;
   }
 
   .th_user,
@@ -85,10 +118,13 @@
   .tags {
     width: 15%;
     min-width: 150px;
-    overflow: hidden;
     word-wrap: break-word;
   }
 
+  .service{
+    width: 10%;
+  }
+
   .tags {
     .label {
       padding-top: 0;
@@ -97,30 +133,45 @@
 
   .service {
     min-width: 175px;
+    z-index: 9 !important;
   }
 
   .env_name {
-    width: 16%;
+    width: 21%;
     min-width: 200px;
+    z-index: 15 !important;
+    padding-left: 0;
+  }
+
+  .th_user{
+    z-index: 14 !important;
+  }
+
+  .th_empty {
+    width: 1%;
+    z-index: 4 !important;
   }
 
   .th_project{
     width: 12%;
+    z-index: 13 !important;
+    min-width: 150px;
   }
 
   .th_type {
-    width: 10%;
-    min-width: 150px;
+    width: 12%;
+    min-width: 170px;
+    z-index: 12 !important;
   }
 
   .th_status {
     width: 8%;
     min-width: 150px;
+    z-index: 11 !important;
   }
 
   .th_charges {
-    width: 10%;
-    min-width: 155px;
+    min-width: 135px;
     text-align: right;
 
     .label {
@@ -128,10 +179,6 @@
     }
   }
 
-  .th_project {
-    min-width: 150px;
-  }
-
   .tags-col {
     padding: 5px;
 
@@ -148,8 +195,11 @@
     }
   }
 
-  .mat-column-charge {
+  .mat-column-charge,
+  .filter-row-item:last-child,
+  .table-footer.mat-column-charge{
     text-align: right;
+    background-color: #f8f8f8;
   }
 
   .header-row {
@@ -159,7 +209,12 @@
       padding-top: 0;
 
       .label {
-        padding-top: 12px;
+        padding-top: 10px;
+      }
+
+      &.label-header{
+        box-shadow: none;
+        border-bottom: 1px solid lightgrey !important;
       }
     }
 
@@ -169,13 +224,18 @@
       vertical-align: super !important;
 
       .text{
-     padding-left: 15px;
+     padding-left: 20px;
       }
     }
 
     .sort{
       position: absolute;
-      bottom: 20px;
+      bottom: 2px;
+
+      &-user,
+      &-project{
+        right: -15px;
+      }
 
       &-arrow{
         width: 6px;
@@ -201,11 +261,13 @@
     }
   }
 
-
-
   .filter-row {
     .actions {
       text-align: right;
+
+      button{
+        background: inherit;
+      }
     }
   }
 
@@ -245,9 +307,22 @@
   &.total-cost{
     min-width: 140px;
     padding-left: 0 !important;
+    text-align: right;
+    padding-right: 25px;
+    position: sticky;
+    right: 0;
+    z-index: 17;
   }
 }
 
+  .left {
+  }
+
+  .right {
+    position: absolute;
+    right: 0;
+  }
+
 @media screen and (max-width: 1280px) {
   .dashboard_table.reporting {
     .env_name,
@@ -261,10 +336,6 @@
       width: 12%;
     }
 
-    .th_charges {
-      width: 6%;
-    }
-
     .user-field {
       word-wrap: break-word;
     }
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts
index 9c88f27..bf25aae 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import {Component, OnInit, Output, EventEmitter, ViewChild, Input} from '@angular/core';
+import {Component, OnInit, Output, EventEmitter, ViewChild, Input, HostListener, AfterViewInit, ChangeDetectorRef} from '@angular/core';
 import { ReportingConfigModel } from '../../../../dictionary/global.dictionary';
 
 @Component({
@@ -27,7 +27,7 @@
     '../../../resources/resources-grid/resources-grid.component.scss'],
 
 })
-export class ReportingGridComponent implements OnInit {
+export class ReportingGridComponent implements OnInit, AfterViewInit {
 
   filterConfiguration: ReportingConfigModel;
   // filteredReportData: ReportingConfigModel = new ReportingConfigModel([], [], [], [], [], '', '', '', []);
@@ -36,18 +36,45 @@
   fullReport: Array<any>;
   isFiltered: boolean = false;
   active: object = {};
+  public isScrollButtonsVisible: boolean;
 
   @ViewChild('nameFilter', { static: false }) filter;
+  @ViewChild('tableWrapper', { static: false }) tableWrapper;
 
+  @ViewChild('table', { static: false }) table;
   @Output() filterReport: EventEmitter<{}> = new EventEmitter();
   @Output() resetRangePicker: EventEmitter<boolean> = new EventEmitter();
   @Input() filteredReportData: ReportingConfigModel;
-  displayedColumns: string[] = ['name', 'user', 'project', 'type', 'status', 'shape', 'service', 'charge'];
-  displayedFilterColumns: string[] = ['name-filter', 'user-filter', 'project-filter', 'type-filter', 'status-filter', 'shape-filter', 'service-filter', 'actions'];
+
+  @HostListener('window:resize', ['$event'])
+  onResize(event) {
+    this.isScrollButtonsVisible = this.tableWrapper.nativeElement.offsetWidth - this.table._elementRef.nativeElement.offsetWidth < 0;
+    this.isMaxRight = this.checkMaxRight();
+  }
+  @HostListener('scroll', ['$event'])
+  scrollTable($event: Event) {
+    this.isMaxRight = this.checkMaxRight();
+  }
+
+
+
+  displayedColumns: string[] = ['name', 'user', 'project', 'type', 'status', 'shape', 'service', 'empty', 'charge'];
+  displayedFilterColumns: string[] = ['name-filter', 'user-filter', 'project-filter', 'type-filter', 'status-filter', 'shape-filter',  'service-filter', 'empty-filter', 'actions'];
   filtered: any;
+  isMaxRight: boolean;
+
+  constructor(private changeDetector: ChangeDetectorRef) {
+  }
 
   ngOnInit() {}
 
+  ngAfterViewInit() {
+    window.setTimeout(() => {
+      this.isScrollButtonsVisible = this.tableWrapper.nativeElement.offsetWidth - this.table._elementRef.nativeElement.offsetWidth < 0;
+      this.isMaxRight = this.checkMaxRight();
+    }, 500);
+  }
+
   onUpdate($event): void {
     this.filteredReportData[$event.type] = $event.model;
   }
@@ -116,4 +143,18 @@
   shapeSplit(shape) {
     return shape.split(/(?=Slave)/g);
   }
+
+  public sctollTo(direction: string) {
+    if (direction === 'left') {
+      this.tableWrapper.nativeElement.scrollLeft = 0;
+    } else {
+      this.tableWrapper.nativeElement.scrollLeft = this.tableWrapper.nativeElement.offsetWidth;
+    }
+  }
+
+  private checkMaxRight() {
+    return this.isMaxRight = this.tableWrapper.nativeElement.offsetWidth +
+      this.tableWrapper.nativeElement.scrollLeft + 2 <= this.table._elementRef.nativeElement.offsetWidth;
+  }
+
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html
index 7979849..d7da74b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html
@@ -38,7 +38,7 @@
       <i class="material-icons">file_download</i>Export
     </button>
     <button mat-raised-button class="butt" (click)="rebuild($event)">
-      <i class="material-icons">autorenew</i>Refresh
+      <i class="material-icons refresh-icon">autorenew</i>Refresh
     </button>
   </div>
 </section>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss
index 4a150bf..f23b8a9 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss
@@ -62,79 +62,3 @@
   }
 }
 
-/* daterangepicker themes */
-#range-picker {
-  margin-top: 5px;
-}
-
-#range-picker path#Shape {
-  fill: #36afd5;
-}
-
-#range-picker .ng-daterangepicker,
-#range-picker .ng-daterangepicker.is-active,
-#range-picker .ng-daterangepicker .calendar {
-  border: none;
-  border-radius: 0;
-  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
-}
-
-#range-picker .ng-daterangepicker .calendar::after {
-  border-top: 1px solid rgba(234, 234, 234, 0.64);
-  border-left: 1px solid rgba(234, 234, 234, 0.64);
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button {
-  background: #fff;
-  color: #718ba6;
-  border: none;
-  border-radius: 0px;
-  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12)
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active,
-#range-picker .ng-daterangepicker .input-section .label-txt {
-  color: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-num.is-active,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days .day-num:hover {
-  background: #35afd5;
-  background-clip: padding-box;
-
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-names,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days {
-  width: 310px;
-}
-
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-first-weekday,
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-last-weekday {
-  background-clip: padding-box;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day.is-within-range {
-  background: #e9f8fc
-}
-
-#range-picker .ng-daterangepicker .input-section .cal-icon svg path {
-  fill: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt {
-  color: #718ba6;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched,
-#range-picker .ng-daterangepicker .input-section .label-txt.untouched {
-  color: #fff;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched::after {
-  content: 'Select date';
-  position: absolute;
-  top: 22px;
-  left: 34px;
-  color: #718ba6;
-}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts
index 503ffaa..aa4a962 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts
@@ -61,31 +61,42 @@
   }
 
   ngOnInit() {
-    if (localStorage.getItem('report_period')) {
-      const availableRange = JSON.parse(localStorage.getItem('report_period'));
-      this.availablePeriodFrom = availableRange.start_date;
-      this.availablePeriodTo = availableRange.end_date;    }
+    // if (localStorage.getItem('report_period')) {
+    //   const availableRange = JSON.parse(localStorage.getItem('report_period'));
+    //   this.availablePeriodFrom = availableRange.start_date;
+    //   this.availablePeriodTo = availableRange.end_date;
+    // } else {
+
+    // }
     this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
       this.healthStatus = result;
     }));
+    this.setInitDatapickerConfig();
   }
 
   ngAfterViewInit() {
     this.clearRangePicker();
   }
 
+  private setInitDatapickerConfig() {
+    const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+    const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
+    labels[0].innerHTML = 'From date';
+    labels[1].innerHTML = 'To date';
+    for (let label = 0; label < rangeLabels.length; ++label) {
+      rangeLabels[label].classList.add('untouched');
+      rangeLabels[label].classList.add('d-none');
+    }
+  }
+
   setDateRange() {
     const availableRange = JSON.parse(localStorage.getItem('report_period'));
-
     this.availablePeriodFrom = availableRange.start_date;
     this.availablePeriodTo = availableRange.end_date;
   }
 
   clearRangePicker(): void {
-    const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
-
-    for (let label = 0; label < rangeLabels.length; ++label)
-      rangeLabels[label].classList.add('untouched');
+    this.setInitDatapickerConfig();
   }
 
   onChange(dateRange: string): void {
@@ -94,7 +105,11 @@
     for (let label = 0; label < rangeLabels.length; ++label)
       if (rangeLabels[label].classList.contains('untouched')) {
         rangeLabels[label].classList.remove('untouched');
+        rangeLabels[label].classList.remove('d-none');
       }
+    const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+    labels[0].innerHTML = 'From:';
+    labels[1].innerHTML = 'To:';
 
     const reportDateRange = dateRange.split('-');
     this.setRangeOption.emit({
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
index bb769aa..c1e3be4 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
@@ -95,7 +95,7 @@
         (click)="refreshBucket()"
         [disabled]="allDisable"
       >
-        <i class="material-icons">autorenew</i>Refresh
+        <i class="material-icons refresh-icon">autorenew</i>Refresh
       </button>
     </div>
     <p class="path"><span>Bucket path:</span>
@@ -190,7 +190,8 @@
                 </span>
               </div>
               <div class="size">{{file.object?.size | convertFileSize}}</div>
-              <div class="date" *ngIf="!file.isDownloading">{{convertDate(file.object?.lastModifiedDate) | date: 'dd/MM/yyyy hh:mm:ss aa'  }}</div>
+<!--              <div class="date" *ngIf="!file.isDownloading">{{convertDate(file.object?.lastModifiedDate) | date: 'dd/MM/yyyy hh:mm:ss aa'  }}</div>-->
+              <div class="date" *ngIf="!file.isDownloading">{{file.object?.lastModifiedDate}}</div>
               <div class="progress-wrapper" *ngIf="file.isDownloading">
                 <div class="progres">
                   <span class="progress-bar-text">{{file.progress || 0}}% Downloading...</span>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
index fbdf05b..2cf6731 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
@@ -105,15 +105,20 @@
       direction: rtl;
 
      &-folder{
-       padding-left: 5px;
+       padding-left: 20px;
        padding-right: 5px;
        color: #00bcd4;
        cursor: pointer;
+
+       &:first-of-type{
+         padding-left: 5px;
+       }
      }
 
       &-icon i{
-        transform: translateY(2px);
+        transform: translateY(1px);
         font-size: 15px;
+        position: absolute;
       }
     }
   }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
index 3ffcada..2be3dad 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { Component, OnInit, ViewChild, Inject } from '@angular/core';
+import {Component, OnInit, ViewChild, Inject, OnDestroy} from '@angular/core';
 import { FormGroup, FormBuilder } from '@angular/forms';
 import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
 import { ToastrService } from 'ngx-toastr';
@@ -31,13 +31,16 @@
 import {logger} from 'codelyzer/util/logger';
 import {HttpEventType, HttpResponse} from '@angular/common/http';
 import {CopyPathUtils} from '../../core/util/copyPathUtils';
+import {Subject} from 'rxjs';
+import {takeUntil} from 'rxjs/operators';
 
 @Component({
   selector: 'dlab-bucket-browser',
   templateUrl: './bucket-browser.component.html',
   styleUrls: ['./bucket-browser.component.scss']
 })
-export class BucketBrowserComponent implements OnInit {
+export class BucketBrowserComponent implements OnInit, OnDestroy {
+  private unsubscribe$ = new Subject();
   public addedFiles = [];
   public folderItems = [];
   public originFolderItems = [];
@@ -92,6 +95,11 @@
     this.cloud = this.getCloud();
   }
 
+  ngOnDestroy() {
+    this.unsubscribe$.next();
+    this.unsubscribe$.complete();
+  }
+
   public getTokenValidTime() {
     const token = JSON.parse(atob(this.storage.getToken().split('.')[1]));
     return token.exp * 1000 - new Date().getTime();
@@ -99,7 +107,11 @@
 
   private refreshToken() {
     this.isTokenRefreshing = true;
-    this.auth.refreshToken().subscribe(tokens => {
+    this.auth.refreshToken()
+      .pipe(
+        takeUntil(this.unsubscribe$)
+      )
+      .subscribe(tokens => {
       this.storage.storeTokens(tokens);
       this.isTokenRefreshing = false;
       this.sendFile();
@@ -152,7 +164,11 @@
          if (res) {
            if (this.refreshTokenLimit > this.getTokenValidTime()) {
              this.isTokenRefreshing = true;
-             this.auth.refreshToken().subscribe(v => {
+             this.auth.refreshToken()
+               .pipe(
+                 takeUntil(this.unsubscribe$)
+               )
+               .subscribe(v => {
                this.uploadingQueue(files);
                this.isTokenRefreshing = false;
              });
@@ -164,7 +180,11 @@
       } else {
         if (this.refreshTokenLimit > this.getTokenValidTime()) {
           this.isTokenRefreshing = true;
-          this.auth.refreshToken().subscribe(v => {
+          this.auth.refreshToken()
+            .pipe(
+              takeUntil(this.unsubscribe$)
+            )
+            .subscribe(v => {
             this.uploadingQueue(files);
             this.isTokenRefreshing = false;
           });
@@ -371,6 +391,9 @@
       selected[0]['isDownloading'] = true;
       this.folderItems.forEach(item => item.isSelected = false);
       this.bucketBrowserService.downloadFile(`/${this.bucketName}/object/${path}/endpoint/${this.endpoint}/download`)
+        .pipe(
+          takeUntil(this.unsubscribe$)
+        )
         .subscribe(event =>  {
             if (event['type'] === HttpEventType.DownloadProgress) {
               selected[0].progress = Math.round(100 * event['loaded'] / selected[0].object.size);
@@ -402,7 +425,11 @@
         !res && this.clearSelection();
         res && this.bucketBrowserService.deleteFile({
           bucket: this.bucketName, endpoint: this.endpoint, 'objects': dataForServer
-        }).subscribe(() => {
+        })
+          .pipe(
+            takeUntil(this.unsubscribe$)
+          )
+          .subscribe(() => {
             this.bucketDataService.refreshBucketdata(this.bucketName, this.endpoint);
             this.toastr.success('Objects successfully deleted!', 'Success!');
             this.clearSelection();
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
index 5dae6b4..700005f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
@@ -30,8 +30,13 @@
 export class BucketDataService {
   public _bucketData = new BehaviorSubject<any>(null);
   public serverData: any = [];
-  get data(): TodoItemNode[] { return this._bucketData.value; }
+
+  get data(): TodoItemNode[] {
+    return this._bucketData.value;
+  }
+
   emptyFolder = null;
+
   constructor(
     private bucketBrowserService: BucketBrowserService,
   ) {
@@ -39,21 +44,25 @@
 
   public refreshBucketdata(bucket, endpoint) {
     let backetData = [];
-    this.bucketBrowserService.getBucketData(bucket, endpoint).subscribe(v => {
-      const copiedData = JSON.parse(JSON.stringify(v));
 
-      this.serverData = v;
-      if (this.emptyFolder) {
-        copiedData.unshift(this.emptyFolder);
-      }
-      backetData = this.convertToFolderTree(copiedData);
-      const data = this.buildFileTree({[bucket]: backetData}, 0);
-      this._bucketData.next(data);
-    });
-    // this.serverData = array;
-    // backetData = this.convertToFolderTree(array);
+    // this.bucketBrowserService.getBucketData(bucket, endpoint).subscribe(v => {
+    // const copiedData = JSON.parse(JSON.stringify(v));
+    // this.serverData = v;
+    // if (this.emptyFolder) {
+    //   copiedData.unshift(this.emptyFolder);
+    // }
+    //
+    // backetData = this.convertToFolderTree(copiedData);
     // const data = this.buildFileTree({[bucket]: backetData}, 0);
     // this._bucketData.next(data);
+    // });
+    if (this.emptyFolder) {
+      array.unshift(this.emptyFolder);
+    }
+    this.serverData = array;
+    backetData = this.convertToFolderTree(array);
+    const data = this.buildFileTree({[bucket]: backetData}, 0);
+    this._bucketData.next(data);
   }
 
   public buildFileTree(obj: {[key: string]: any}, level: number): TodoItemNode[] {
@@ -121,6 +130,7 @@
         if (!pointer.obj) {
           pointer.obj = object;
         }
+
       });
     };
 
@@ -138,4 +148,5 @@
       }
       return finalData;
     }
+
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
index 8d294a5..0da2a14 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
@@ -1,3 +1,22 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
 <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
   <mat-tree-node
     *matTreeNodeDef="let node"
@@ -13,7 +32,7 @@
       [matTooltipClass]="'bucket-item-tooltip'"
     >{{node.name}}</div>
   </mat-tree-node>
-  <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding  matTreeNodePaddingIndent="17">
+  <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="17">
     <button mat-icon-button matTreeNodeToggle
             [attr.aria-label]="'toggle ' + node.name">
       <mat-icon class="mat-icon-rtl-mirror">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
index fd06d7a..5bd774a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
@@ -1,4 +1,21 @@
-
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 .folder{
   padding-left: 5px;
   max-width: 350px;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
index ed222f6..cc8f5d8 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
 import {FlatTreeControl} from '@angular/cdk/tree';
 import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
index 2e8115f..6879271 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
@@ -1,3 +1,22 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
 <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
 
   <mat-tree-node
@@ -16,7 +35,7 @@
         <mat-label>New folder</mat-label>
         <input matInput #itemValue [formControl]="folderFormControl" [errorStateMatcher]="matcher">
         <mat-error *ngIf="!folderFormControl.hasError('required') && !folderFormControl.hasError('isDuplicate')">
-          The folder name can only contain Latin letters, numbers and special characters except for #, ?, /, \, "
+          The folder name can only contain Latin letters, numbers and special characters except for #, ?, /, \, %"
         </mat-error>
         <mat-error *ngIf="folderFormControl.hasError('required')">
           Folder name is <strong>required</strong>
@@ -39,7 +58,7 @@
     </form>
   </mat-tree-node>
 
-  <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding  matTreeNodePaddingIndent="17"  [ngClass]="{'cursor-not-allow': bucketDataService.emptyFolder}">
+  <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="17" [ngClass]="{'cursor-not-allow': bucketDataService.emptyFolder}">
     <button mat-icon-button matTreeNodeToggle
             [attr.aria-label]="'toggle ' + node.filename" [ngClass]="{'not-allowed': bucketDataService.emptyFolder}">
       <mat-icon class="mat-icon-rtl-mirror" [ngClass]="{'active-item': (selectedFolder === node && !bucketDataService.emptyFolder)}">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
index 22c36d0..fd962ad 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
@@ -1,3 +1,21 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 
 .folder{
   padding-left: 5px;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
index 1684b26..cd7d199 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import {Component, Output, EventEmitter, OnDestroy, Input, OnInit} from '@angular/core';
 import {FlatTreeControl} from '@angular/cdk/tree';
 import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
@@ -65,7 +84,7 @@
           if (this.selectedFolder && !this.bucketDataService.emptyFolder) {
             setTimeout(() => {
               const element = document.querySelector('.folder-item-line.active-item');
-              element && element.scrollIntoView({ block: 'center', behavior: 'smooth' });
+              element && element.scrollIntoView({ block: 'start', behavior: 'smooth' });
             }, 0);
           } else if (this.selectedFolder && this.bucketDataService.emptyFolder) {
             setTimeout(() => {
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html
index 94265fd..62ab6af 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html
@@ -149,7 +149,7 @@
           <label class="label">
             <input #preemptibleNode type="checkbox" (change)="selectPreemptibleNodes($event)" />
             <span>Preemptible node</span>
-            <span class="align" *ngIf="preemptible?.nativeElement['checked'] || false"> count</span>
+            <span class="align" [hidden]="!preemptible?.nativeElement['checked']"> count</span>
           </label>
           <div *ngIf="preemptible?.nativeElement['checked']" class="preemptible-details control"
             [ngClass]="{ show: preemptible?.nativeElement['checked'] || false}">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
index 8968a3a..9f319cc 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
@@ -134,7 +134,7 @@
   public createComputationalResource(data) {
     this.model.createComputationalResource(data, this.selectedImage, this.notebook_instance, this.spotInstance, this.PROVIDER.toLowerCase())
       .subscribe((response: any) => {
-        if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close();
+        if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close(true);
       }, error => this.toastr.error(error.message, 'Oops!'));
   }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss
index 2df7536..582f51f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss
@@ -17,10 +17,13 @@
  * under the License.
  */
 
+ :host{
+ width:100%;
+ }
+
  .source {
    .no-details {
      color: #bdc9d5;
-     padding-left: 10px;
    }
 
    .resource-wrap {
@@ -34,7 +37,6 @@
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
-       padding-left: 10px;
 
        .detailed-link {
          color: #35afd5;
@@ -109,23 +111,23 @@
      }
    }
  }
- @media screen and (max-width: 1520px) {
-   .resources,
-   managment {
-     .source {
-       .resource-wrap {
-         .resource-name {
-           width: 42%;
-         }
-
-         .resource-status {
-           width: 43%;
-         }
-
-         .resource-actions {
-           width: 15%;
-         }
-       }
-     }
-   }
- }
+ //@media screen and (max-width: 1520px) {
+ //  .resources,
+ //  managment {
+ //    .source {
+ //      .resource-wrap {
+ //        .resource-name {
+ //          width: 42%;
+ //        }
+ //
+ //        .resource-status {
+ //          width: 43%;
+ //        }
+ //
+ //        .resource-actions {
+ //          width: 15%;
+ //        }
+ //      }
+ //    }
+ //  }
+ //}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts
index e783951..92362f7 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts
@@ -57,7 +57,7 @@
 
   public assignChanges(data) {
     this._userResource.createAMI(data).subscribe(
-      response => response.status === HTTP_STATUS_CODES.ACCEPTED && this.dialogRef.close(),
+      response => response.status === HTTP_STATUS_CODES.ACCEPTED && this.dialogRef.close(true),
       error => this.toastr.error(error.message || `Image creation failed!`, 'Oops!'));
   }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html
index 17fe71a..d916d94 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html
@@ -33,7 +33,7 @@
       </table>
       <div class="billing-detail content-box">
         <mat-list>
-            <mat-list-item class="list-header">
+            <mat-list-item class="list-header" [ngClass]="{'pr-3': notebook.billing.report_lines.length > 6}">
               <div class="resource-name ellipsis" [ngClass]="{ 'wide-name-field' : provider === 'azure' }">Name</div>
               <div class="service">Product</div>
 <!--              <div class="resource-type" *ngIf="provider === 'aws'">Type</div>-->
@@ -55,6 +55,7 @@
                 <div class="cost-currency">{{ item.cost }} {{ item.currency }}</div>
               </mat-list-item>
             </div>
+
         </mat-list>
         <div class="total">
           <strong>Total: </strong>{{ notebook.cost }} {{ notebook.currency_code }}</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss
index 18998ea..a9d081a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss
@@ -67,14 +67,13 @@
   }
 }
 
-
 .scrolling-content {
   max-height: 285px;
   overflow-y: auto;
 }
 
 .mat-list-item-content {
-  font-size: 15px !important;
+  font-size: 14px !important;
   justify-content: space-between;
 }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
index 5d53b59..654f29b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
@@ -28,13 +28,14 @@
       <p class=" message">Cannot install libraries: Exploratory
         <strong>{{ notebook?.name }}</strong> is not running</p>
     </div>
-    <div class="loading-block" *ngIf="!libs_uploaded && uploading && data.status === 'running'">
+    <div *ngIf="notebook?.status === 'running'" class="top-wrapper">
+      <div class="loading-block" *ngIf="!libs_uploaded && uploading && data.status === 'running'">
       <div class="uploading">
         <p>Please wait until DLab loads full list of available libraries for you...</p>
         <img src="assets/img/gif-spinner.gif" alt="loading">
       </div>
     </div>
-    <div *ngIf="notebook?.status === 'running' && !uploading" class="lib-view-wrap">
+      <div *ngIf="notebook?.status === 'running' && !uploading" class="lib-view-wrap">
       <div class="search-box">
         <div class="search-form">
           <div>
@@ -48,65 +49,127 @@
               <label class="label">Select group</label>
               <div class="control">
                 <dropdown-list #groupSelect (selectedItem)="onUpdate($event)" (emitClick)="emitClick()"></dropdown-list>
-                <span class="error-message" *ngIf="!group && libSearch.value">Group field is required. Please choose appropriate group.</span>
+                <span class="error-message" *ngIf="!group && libSearch?.value">Group field is required. Please choose appropriate group.</span>
               </div>
             </div>
           </div>
-          <p class="other-message">
-            <span *ngIf="group === 'others'">Other group can include libs from Python 2 and Python 3 groups</span>
-          </p>
-          <div class="search">
-            <mat-form-field class="chip-list">
-              <input
-                type="text"
-                [placeholder]="group === 'java' ?
-                'Enter library name in <groupId>:<artifactId>:<versionId> format' :
-                'Enter library name in <name>:<version> format(version is not required)'"
-                matInput
-                #trigger="matAutocompleteTrigger"
-                [formControl]="libSearch"
-                [value]="query"
-                [matAutocomplete]="auto"
-              >
-<!--              <span class="add-icon" [matTooltip]="(isInSelectedList || isInstalled) ? 'Current library dosen\'t exist' : 'You have already added or installed current library'"-->
-<!--              matTooltipPosition="above"-->
-<!--              [matTooltipDisabled] = "isLibExist && (isInSelectedList || isInstalled)"-->
-              <span class="add-icon">
-                <button  mat-icon-button class="btn" [disabled]="!isLibExist || query.length < 1 ||
-                isDuplicated({name: query.slice(0, query.indexOf(':')), version: query.slice(query.indexOf(':') + 1) || 'N/A'})" (click)="addLibrary(query);$event.stopPropagation()">
-                  <mat-icon matSuffix >add</mat-icon>
-                </button>
-              </span>
-
+          <div class="m-top-20" *ngIf="group !== 'java'; else javaGroup">
+            <div class="control-group constol-select">
+              <label class="label">Library name</label>
+              <div class="control control-relative">
+                <span class="other-message" *ngIf="group === 'others'">Other group can include libs from Python 2 and Python 3 groups</span>
+                <input
+                  type="text" [placeholder]="'Enter library name'"
+                  [disabled]="!group"
+                  [matAutocomplete]="auto"
+                  [formControl]="libSearch"
+                  #trigger="matAutocompleteTrigger"
+                  (keyup.enter)="addLibrary(lib)"
+                  class="library-input"
+                >
+              </div>
               <mat-autocomplete #auto="matAutocomplete" class="suggestions" >
-                <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index" *ngIf="query.indexOf(':') === -1">
-                  <mat-option [ngClass]="{ 'not-allowed': isDuplicated(item) }">
-                    <div class="option" (click)="selectLibrary(item)">
-                      <a *ngIf="!isDuplicated(item)">
-                        <span [innerHTML]="item.name | highlight:query"></span>
-<!--                        <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>-->
+                <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index">
+                  <mat-option>
+                    <div class="option" (click)="selectLibrary(item);$event.stopPropagation()" [ngClass]="{'not-allow': item.isInSelectedList}">
+                      <a *ngIf="!item.isInSelectedList">
+                        <span [innerHTML]="item.name | highlight:lib.name"></span>
                       </a>
-                      <span *ngIf="isInSelectedList || isInstalled">{{ item.name }}
-                        <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>
-                      </span>
-
-                      <strong *ngIf="isInSelectedList">selected
+                      <span *ngIf="item.isInSelectedList">{{ item.name }}</span>
+                      <strong *ngIf="item.isInSelectedList">selected
                         <i class="material-icons">done</i>
                       </strong>
-                      <strong *ngIf="isInstalled">installed
+                      <strong *ngIf="item.isInstalled && !item.isInSelectedList">installed
                         <i class="material-icons">done</i>
                       </strong>
                     </div>
                   </mat-option>
                 </ng-template>
-                <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format && query.indexOf(':') === -1">
+                <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format">
                   <span class="configuring">No matches found</span>
                 </mat-option>
                 <mat-option *ngIf="validity_format?.length > 0">
-                  <span class="configuring" *ngIf="query.indexOf(':') === -1">{{ validity_format }}</span >
+                  <span class="configuring" >{{ validity_format }}</span >
                 </mat-option>
               </mat-autocomplete>
-            </mat-form-field>
+            </div>
+            <div class="control-group control-select">
+              <label class="label">Library version</label>
+              <div class="control control-relative">
+                <input
+                  type="text"
+                  class="library-input"
+                  [placeholder]="'Enter library version (optional)'"
+                  [(ngModel)]="lib.version"
+                  [disabled]="!lib.name"
+                  (keyup.enter)="addLibrary(lib)"
+                >
+                <span class="plus-icon"
+                      [ngClass]="{'not-allow': !this.selectedLib || this.selectedLib?.isInSelectedList}"
+                      matTooltip="Library is in selected list" matTooltipPosition="above" [matTooltipDisabled]="!this.selectedLib?.isInSelectedList"
+                >
+                  <mat-icon  (click)="addLibrary(lib)"  [ngClass]="{'not-allowed': !this.selectedLib || this.selectedLib?.isInSelectedList }">add</mat-icon>
+                </span>
+              </div>
+            </div>
+          </div>
+
+          <ng-template #javaGroup>
+            <div class="m-top-20">
+              <div class="control-group constol-select java-library-search">
+                <label class="label">Library</label>
+                <div class="control control-relative">
+<!--                 <span class="other-message" *ngIf="lib.name?.length && !this.selectedLib">groupId:artifactId:versionId</span>-->
+                 <input
+                    type="text" [placeholder]="'Enter library name in <groupId>:<artifactId>:<versionId> format'"
+                    class="library-input"
+                    [disabled]="!group"
+                    [matAutocomplete]="auto"
+                    [formControl]="libSearch"
+                    #trigger="matAutocompleteTrigger"
+                    (keyup.enter)="addLibrary(lib)"
+                  >
+                  <span
+                    class="plus-icon"
+                    [ngClass]="{'not-allow': !this.selectedLib || this.selectedLib?.isInSelectedList}"
+                    matTooltip="Library is in selected list" matTooltipPosition="above" [matTooltipDisabled]="!this.selectedLib?.isInSelectedList"
+                  >
+                  <mat-icon  (click)="addLibrary(lib)" (keyup.enter)="addLibrary(lib)" [ngClass]="{'not-allowed': !this.selectedLib || this.selectedLib?.isInSelectedList}">add</mat-icon>
+                </span>
+                </div>
+                <mat-autocomplete #auto="matAutocomplete" class="suggestions">
+                  <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index">
+                    <mat-option >
+                      <div class="option" (click)="selectLibrary(item);$event.stopPropagation()" [ngClass]="{'not-allow': item.isInSelectedList}">
+                        <a *ngIf="!item.isInSelectedList">
+                          <span [innerHTML]="item.name + ':' + item.version | highlight:item.name">
+                             <span>{{ item.version }}</span>
+                          </span>
+                        </a>
+                        <span *ngIf="item.isInSelectedList">{{ item.name }}
+                          <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>
+                      </span>
+                        <strong *ngIf="item.isInSelectedList">selected
+                          <i class="material-icons">done</i>
+                        </strong>
+                        <strong *ngIf="item.isInstalled && !item.isInSelectedList">installed
+                          <i class="material-icons">done</i>
+                        </strong>
+                      </div>
+                    </mat-option>
+                  </ng-template>
+                  <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format">
+                    <span class="configuring">No matches found</span>
+                  </mat-option>
+                  <mat-option *ngIf="validity_format?.length > 0">
+                    <span class="configuring" >{{ validity_format }}</span >
+                  </mat-option>
+                </mat-autocomplete>
+              </div>
+            </div>
+          </ng-template>
+
+          <div class="search">
             <div class="list-selected list-container" id='scrolling'>
               <mat-chip-list *ngIf="model.selectedLibs.length && libs_uploaded">
                 <mat-chip *ngFor="let item of model.selectedLibs">
@@ -121,6 +184,8 @@
         </div>
       </div>
     </div>
+    </div>
+
     <div class="libs-info">
       <mat-list>
         <mat-list-item class="list-header">
@@ -161,11 +226,17 @@
         </mat-list-item>
 
         <ng-container *ngIf="filtered" >
-         <mat-list-item class="lib-col filter-row">
-          <th class="lib-name lib-input">
-            <input placeholder="Filter by library name" [value]="filterModel.name" (input)="filterModel.name = $event.target['value']" type="text" class="form-control filter-field "/>
+         <mat-list-item class="filter-row">
+          <th class="lib-name filter-col">
+            <input
+              placeholder="Filter by library name"
+              [value]="filterModel.name"
+              (input)="filterModel.name = $event.target['value']"
+              type="text"
+              class="form-control filter-field"
+            />
           </th>
-          <th class="lib-group lib-col">
+          <th class="lib-group filter-col">
               <multi-select-dropdown
                 (selectionChange)="onFilterUpdate($event)"
                 [items]="this.filterConfiguration.group"
@@ -174,7 +245,7 @@
               >
               </multi-select-dropdown>
             </th>
-            <th class="lib-destination lib-col">
+            <th class="lib-destination filter-col">
               <multi-select-dropdown
                 (selectionChange)="onFilterUpdate($event)"
                 [items]="this.filterConfiguration.resource"
@@ -183,7 +254,7 @@
               >
               </multi-select-dropdown>
             </th>
-            <th class="lib-resource-type lib-col">
+            <th class="lib-resource-type filter-col">
               <multi-select-dropdown
                 (selectionChange)="onFilterUpdate($event)"
                 [items]="this.filterConfiguration.resourceType"
@@ -192,12 +263,13 @@
               >
               </multi-select-dropdown>
           </th>
-          <th class="lib-status lib-col">
+          <th class="lib-status filter-col">
             <multi-select-dropdown
               (selectionChange)="onFilterUpdate($event)"
               [items]="this.filterConfiguration.status"
               [type]="'status'"
-              [model]="this.filterModel.status">
+              [model]="this.filterModel.status"
+            >
             </multi-select-dropdown>
           </th>
            <ng-container matColumnDef="action-filter" stickyEnd>
@@ -208,7 +280,7 @@
                  </button>
 
                  <button mat-icon-button class="btn apply" (click)="filterLibs()">
-                   <i class="material-icons"  [ngClass]="{'not-allowed': filterModel.length === 0}">done</i>
+                   <i class="material-icons"  [ngClass]="{'not-allowed': filterModel['length'] === 0}">done</i>
                  </button>
                </div>
              </th>
@@ -222,9 +294,11 @@
 <!--          </div>-->
           <ng-container *ngFor="let lib of filtredNotebookLibs">
             <mat-list-item class="table-item">
-            <div class="lib-name ellipsis">
-              <strong>{{ lib.name }}</strong>&nbsp;
-              <span *ngIf="lib.version  && lib.version !== 'N/A'">{{ lib.version }}</span>
+            <div class="lib-name lib-name-col ellipsis" >
+              <span [matTooltip]="lib.name + ' ' + lib.version" matTooltipPosition="above" class="lib-name-wrapper">
+                <span class="stong" >{{ lib.name }}</span>&nbsp;
+                <span *ngIf="lib.version  && lib.version !== 'N/A'">{{ lib.version }}</span>
+              </span>
             </div>
             <div class="lib-group-col">{{ groupsListMap[lib.group] }}</div>
             <div class="st-group">
@@ -232,62 +306,40 @@
                 <div class="wrap-col">
                   <div class="lib-destination-col">{{ item.resource }}</div>
                   <div class="lib-resource-type-col">{{ item.resourceType }}</div>
-                  <div class="lib-status-col" ngClass="{{ item.status.toLowerCase() || 'failed' }}">{{ item.status }}
-                    <div class="warn-action" *ngIf="(item.status === 'failed' || item.status === 'invalid version') && notebook?.status === 'running'">
+                  <div class="lib-status-col" ngClass="{{ item.status.toLowerCase() || 'installation_error' }}">{{ item.status.replace('_', ' ') }}
+                    <div class="warn-action" *ngIf="(item.status === 'installation_error' || item.status.toLowerCase() === 'invalid_version' || item.add_pkgs?.length) && notebook?.status === 'running'">
                       <div *ngIf="!item.available_versions">
-                        <span *ngIf="!installingInProgress" (click)="reinstallLibrary(item, lib)" matTooltip="Retry installation" matTooltipPosition="above">
+                        <span *ngIf="!installingInProgress && item.status === 'installation_error'" (click)="reinstallLibrary(item, lib)" matTooltip="Retry installation" matTooltipPosition="above">
                           <i class="material-icons">replay</i>
                         </span>
-                        <span class="not-allowed" *ngIf="installingInProgress" matTooltip="You can't reinstall library until previous process will be completed"
+                        <span class="not-allow" *ngIf="installingInProgress && item.status === 'installation_error'" matTooltip="Please wait until lib installation completes"
                           matTooltipPosition="above">
-                          <i class="material-icons">replay</i>
+                          <i class="material-icons not-allowed">replay</i>
                         </span>
                       </div>
-                      <div *ngIf="item.status === 'failed' && item.error" class="lib-error" (click)="showErrorMessage(item)">
-                        <i class="material-icons">error_outline</i>
+                      <div *ngIf="item.status === 'installation_error' && item.error" class="lib-error" (click)="showErrorMessage(item)" matTooltip="Show error message" matTooltipPosition="above">
+                        <i class="material-icons terminated">error_outline</i>
                       </div>
                       <div class="lib-error"
-                           *ngIf="item.status === 'invalid version' && item.available_versions?.length" class="lib-error"
+                           *ngIf="item.status.toLowerCase() === 'invalid_version' && item.available_versions?.length"
                            (click)="openLibInfo(item, 'available');$event.stopPropagation()"
                            matTooltip="Show available version" matTooltipPosition="above"
                       >
-                        <i class="material-icons terminated">error_outline</i>
+                        <i class="material-icons">error_outline</i>
                       </div>
-                    </div>
-                    <div class="warn-action" matTooltip="Show installed dependency" matTooltipPosition="above" *ngIf="item.add_pkgs?.length">
+                      <div matTooltip="Show installed dependency" matTooltipPosition="above" *ngIf="item.add_pkgs?.length">
                         <span class="info-icon" (click)="openLibInfo(item, 'added');$event.stopPropagation() ">
                           <i class="material-icons">info</i>
                         </span>
+                      </div>
                     </div>
+
                   </div>
                 </div>
 
               </ng-template>
             </div>
           </mat-list-item>
-
-<!--          <mat-list-item  *ngIf="isLibInfoOpened[lib.name]">-->
-<!--            <div class="lib-info">-->
-<!--              <ul class="libs-version">-->
-
-<!--                <li class="dependency-list-header">-->
-<!--                  List of available version:-->
-<!--                </li>-->
-
-<!--&lt;!&ndash;                <div class="scrolling-content delete-list" id="scrolling">&ndash;&gt;-->
-
-<!--                  <li *ngFor="let object of [1,2,3]" class="delete-item list-item">-->
-<!--                    &lt;!&ndash;                        <div class="object">&ndash;&gt;-->
-<!--                    {{lib.name+lib.version}}-->
-<!--                    &lt;!&ndash;                        </div>&ndash;&gt;-->
-<!--                    &lt;!&ndash;                        <div class="size">v2.3.4</div>&ndash;&gt;-->
-<!--                    <button mat-raised-button type="button"  class="butt action">Install</button>-->
-<!--                  </li>-->
-
-<!--&lt;!&ndash;                </div>&ndash;&gt;-->
-<!--              </ul>-->
-<!--            </div>-->
-<!--          </mat-list-item>-->
           </ng-container>
           <div *ngIf="!filtredNotebookLibs.length && notebookLibs?.length" class="scrollingList info message">
             <p>No matches found</p>
@@ -299,8 +351,16 @@
       </mat-list>
     </div>
     <div class="m-top-15 actions" *ngIf="!uploading && notebook?.status === 'running'">
-      <button mat-raised-button type="button" class="butt action" (click)="dialogRef.close()">Close</button>
-      <button mat-raised-button type="submit" class="butt butt-success action" (click)="model.confirmAction()" [disabled]="!model.selectedLibs.length || installingInProgress || !destination">Install</button>
+      <button mat-raised-button type="button" class="butt action close-btn" (click)="dialogRef.close()">Close</button>
+      <span matTooltip="Please wait until lib installation completes" [matTooltipDisabled]="!installingInProgress" matTooltipPosition="above">
+        <button mat-raised-button type="submit"
+                class="butt butt-success action install-btn"
+                (click)="model.confirmAction()"
+                [disabled]="!model.selectedLibs.length || installingInProgress || !destination"
+        >
+          Install
+        </button>
+      </span>
     </div>
    </div>
   </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
index fd769f0..2b95c0b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
@@ -65,6 +65,10 @@
   height: 30%;
 }
 
+.top-wrapper{
+  height: 285px;
+}
+
 .install-libraries {
   height: 100%;
   padding-bottom: 130px;
@@ -78,7 +82,6 @@
   }
 
   .info {
-    height: 40%;
     display: flex;
     flex-direction: row;
     align-items: center;
@@ -87,19 +90,21 @@
 
   .mat-list-item {
     height: auto !important;
+    font-family: "Open Sans", sans-serif;
+    font-weight: 400;
 
     .mat-list-item-content {
       height: auto !important;
       min-height: 54px !important;
       border-bottom: 1px solid #edf1f5;
       padding-right: 10px;
+      padding-left: 0;
     }
   }
 
   .lib-view-wrap {
     display: flex;
     flex-direction: column;
-    height: 40%;
   }
 
   .error {
@@ -109,17 +114,34 @@
   .uploading {
     margin: 0 auto;
   }
+
+  .list-selected {
+    padding: 10px;
+    font-family: 'Open Sans', sans-serif;
+    height: 130px;
+    overflow-y: auto;
+
+    h4 {
+      margin-bottom: 20px;
+      font-size: 14px;
+      text-align: center;
+      font-weight: 400;
+      color: #718ba6;
+    }
+
+    mat-chip-list .mat-chip-list-wrapper {
+      overflow-y: auto;
+      padding: 3px;
+    }
+  }
 }
+
 .list-item{
   display: flex;
   width: 100%;
   padding-left: 20px;
 }
 
-.mat-list-base {
-  //padding: 40px 30px;
-}
-
 .object {
   width: 70%;
   display: flex;
@@ -130,6 +152,7 @@
 .size {
   width: 30%;
 }
+
 .scrolling-content.delete-list {
   max-height: 200px;
   overflow-y: auto;
@@ -140,7 +163,7 @@
   width: 100%;
   justify-content: center;
   color: #35afd5;
-  padding: 15px;
+  padding: 14px;
 }
 
 ul.resources{
@@ -148,8 +171,6 @@
 }
 
 .dependency-list-header {
-  //border-top: 1px solid #edf1f5;
-  //border-bottom: 1px solid #edf1f5;
   color: #577289;
   width: 100%;
   padding: 15px 0 5px 0;
@@ -184,27 +205,43 @@
       width: 50%;
       padding-bottom: 0;
 
+      &.java-library-search{
+        width: 100%;
+
+        .label{
+          width: 10%;
+        }
+
+        .control{
+          width: 85%;
+        }
+      }
+
+      .control{
+        width: 70%;
+
+        input{
+          font-size: 15px;
+          padding-left: 15px;
+        }
+
+        .dropdown-list button {
+          font-size: 14px;
+          padding-top: 0;
+        }
+      }
+
       .label {
         width: 20%;
       }
     }
 
-    .other-message{
-      height: 22px;
-      display: flex;
-      align-items: center;
-
-      span{
-        font-size: 12px;
-        color: $link-color;
-      }
-    }
-
     .search {
       flex-grow: 1;
       padding-bottom: 0;
       flex-direction: column;
       box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
+      margin-top: 25px;
 
       .mat-form-field-flex {
         padding-left: 15px;
@@ -214,9 +251,13 @@
         width: 100%;
         overflow-y: auto;
 
-        .mat-form-field {
+
+        &.mat-form-field {
           width: 100%;
-          padding: 5px 20px;
+
+          .mat-form-field-infix{
+            display: flex;
+          }
         }
 
         .mat-input-flex {
@@ -282,29 +323,9 @@
   }
 }
 
-.list-selected {
-  padding: 0 5px;
-  font-family: 'Open Sans', sans-serif;
-  height: 130px;
-  overflow-y: auto;
-
-  h4 {
-    margin-bottom: 20px;
-    font-size: 14px;
-    text-align: center;
-    font-weight: 400;
-    color: #718ba6;
-  }
-
-  mat-chip-list .mat-chip-list-wrapper {
-    overflow-y: auto;
-    padding: 3px;
-  }
-}
-
 .mat-list-item {
   color: #718ba6 !important;
-  font-size: 14px;
+  font-size: 13px !important;
   font-weight: 300;
 }
 
@@ -319,10 +340,6 @@
   line-height: 40px;
 }
 
-.list-header+div{
-  padding-left: 5px;
-}
-
 .mat-dialog-container {
   position: relative;
 }
@@ -331,8 +348,20 @@
   padding: 0 20px;
   display: flex;
   flex: 1 1 auto;
-  min-height: 0px;
-  height: 50%;
+  min-height: 0;
+
+  .filter-row {
+    .filter-col{
+      padding-left: 0;
+      &.lib-name{
+        padding-left: 5px;
+        .filter-field{
+          padding-left: 15px;
+        }
+      }
+    }
+  }
+
 
   .mat-list {
     width: 100%;
@@ -341,7 +370,7 @@
       max-height: 300px;
       height: 80%;
       overflow-y: auto;
-      overflow-x: hidden;
+      overflow-x: overlay;
 
       .info {
         p {
@@ -351,18 +380,20 @@
       }
     }
   }
-  .lib-col{
-    padding-left: 4px;
 
-  }
   .lib-name {
     width: 27%;
-    &.lib-input{
+    padding-right: 10px;
+    padding-left: 20px;
 
+    &-col{
+      display: flex;
     }
 
     .lib-name-wrapper{
+      overflow: hidden;
       display: block;
+      text-overflow: ellipsis;
     }
 
     strong {
@@ -373,21 +404,26 @@
   .lib-group,
   .lib-destination {
     width: 17%;
-    padding-left: 6px;
+    padding-left: 15px;
+    padding-right: 10px;
   }
 
   .lib-status {
     width: 17%;
-    padding-left: 6px;
+    padding-left: 15px;
+    padding-right: 10px;
   }
 
   .lib-resource-type {
     width: 17%;
-    padding-left: 6px;
+    padding-left: 15px;
+    padding-right: 10px;
   }
+
   .lib-group-col {
     width: 17%;
-    padding-left: 8px;
+    padding-left: 17px;
+    padding-right: 10px;
   }
 
   .st-group {
@@ -401,20 +437,19 @@
 
       .lib-destination-col {
         width: 33.3%;
-        padding-left: 8px;
+        padding-left: 15px;
       }
 
       .lib-resource-type-col {
         width: 33.3%;
         color: #36afd5;
-        padding-left: 8px;
+        padding-left: 15px;
       }
 
       .lib-status-col {
         position: relative;
         width: 33.3%;
-        padding-left: 8px;
-
+        padding-left: 15px;
 
         .warn-action {
           position: absolute;
@@ -457,15 +492,18 @@
   padding-bottom: 3px;
 }
 
-.mat-dialog-container.mat-dialog-container .install-libraries#dialog-box  {
+.mat-dialog-container.mat-dialog-container .install-libraries#dialog-box {
   .mat-header-cell{
     padding: 0;
     border: none;
+    position: absolute;
+    right: 10px;
   }
 
   .filter-actions {
     display: flex;
     margin-left: 6px;
+
     .btn {
       padding: 6px;
       height: auto;
@@ -476,6 +514,7 @@
         display: flex;
       }
     }
+
     .reset{
       &:hover {
         border-color: #f1696e;
@@ -483,6 +522,7 @@
         color: #f1696e;
       }
     }
+
     .apply:hover {
       border-color: #49af38;
       background: #f9fafb;
@@ -492,8 +532,10 @@
 }
 
 .install-libraries .dropdown-multiselect .list-menu li {
+
   a{
     font-size: 13px;
+
     &.list-item{
       color: #4a5c89 !important;
     }
@@ -532,12 +574,14 @@
 
 .lib-info{
   width: 100%;
+
   .delete-item {
     display: flex;
     justify-content: space-between;
     align-items: center;
     width: 100%;
     padding: 5px 10px;
+
     .butt.action{
       line-height: 26px;
     }
@@ -546,7 +590,37 @@
 
 .btn{
   line-height: 26px;
+
+  &.install-btn{
+    margin-left: 0;
+  }
 }
+
+.control-relative{
+  position: relative;
+
+  .plus-icon {
+    position: absolute;
+    right: -40px;
+    top: 5px;
+    color: #35afd5;
+    font-size: 27px;
+    cursor: pointer;
+
+    &.not-allow {
+      color: lightgray;
+    }
+  }
+
+  .other-message{
+    position: absolute;
+    font-size: 12px;
+    color: $link-color;
+    top: 40px;
+    left: 12px;
+  }
+}
+
   @media screen and (min-width: 1281px) {
   .libs-info {
     height: 60%;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
index 2f22fb9..94c7009 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
@@ -22,12 +22,13 @@
 import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
 import { FormControl } from '@angular/forms';
 import { ToastrService } from 'ngx-toastr';
-import { debounceTime } from 'rxjs/operators';
+import {debounceTime, take, takeUntil} from 'rxjs/operators';
 
 import { InstallLibrariesModel } from './install-libraries.model';
 import { LibrariesInstallationService } from '../../../core/services';
 import { SortUtils, HTTP_STATUS_CODES } from '../../../core/util';
 import {FilterLibsModel} from './filter-libs.model';
+import {Subject} from 'rxjs';
 
 interface Library {
   name: string;
@@ -42,22 +43,18 @@
   encapsulation: ViewEncapsulation.None
 })
 export class InstallLibrariesComponent implements OnInit, OnDestroy {
-
+  private unsubscribe$ = new Subject();
   public model: InstallLibrariesModel;
   public notebook: any;
-  public filteredList: any;
+  public filteredList: any = [];
   public groupsList: Array<string>;
   public notebookLibs: Array<any> = [];
-  public notebookFailedLibs: Array<any> = [];
   public loadLibsTimer: any;
-
-  public query: string = '';
   public group: string;
   public destination: any;
   public uploading: boolean = false;
   public libs_uploaded: boolean = false;
   public validity_format: string = '';
-
   public isInstalled: boolean = false;
   public isInSelectedList: boolean = false;
   public installingInProgress: boolean = false;
@@ -82,8 +79,9 @@
   @ViewChild('groupSelect', { static: false }) group_select;
   @ViewChild('resourceSelect', { static: false }) resource_select;
   @ViewChild('trigger', { static: false }) matAutoComplete;
-  public isLibInfoOpened = {  };
   private isLibExist: boolean;
+  public lib: Library = {name: '', version: ''};
+  private selectedLib: any = null;
 
   constructor(
     @Inject(MAT_DIALOG_DATA) public data: any,
@@ -98,10 +96,14 @@
 
   ngOnInit() {
     this.open(this.data);
-    this.libSearch.valueChanges.pipe(
-      debounceTime(1000))
-      .subscribe(newValue => {
-        this.query = newValue || '';
+    this.libSearch.valueChanges
+      .pipe(
+      debounceTime(1000),
+      takeUntil(this.unsubscribe$)
+      )
+      .subscribe(value => {
+        this.lib.name = value;
+        this.isDuplicated(this.lib);
         this.filterList();
       });
   }
@@ -109,12 +111,17 @@
   ngOnDestroy() {
     window.clearTimeout(this.loadLibsTimer);
     window.clearTimeout(this.clear);
+    this.unsubscribe$.next();
+    this.unsubscribe$.complete();
   }
 
   uploadLibGroups(): void {
     this.libs_uploaded = false;
     this.uploading = true;
     this.librariesInstallationService.getGroupsList(this.notebook.project, this.notebook.name, this.model.computational_name)
+      .pipe(
+        takeUntil(this.unsubscribe$)
+      )
       .subscribe(
         response => {
           this.libsUploadingStatus(response);
@@ -145,7 +152,7 @@
 
   public filterList(): void {
     this.validity_format = '';
-    (this.query.length >= 2 && this.group) ? this.getFilteredList() : this.filteredList = null;
+    (this.lib.name && this.lib.name.length >= 2 && this.group ) ? this.getFilteredList() : this.filteredList = null;
   }
 
   public filterGroups(groupsList) {
@@ -160,6 +167,10 @@
   public onUpdate($event) {
     if ($event.model.type === 'group_lib') {
       this.group = $event.model.value;
+      if (this.group) {
+        this.libSearch.enable();
+      }
+      this.lib = {name: '', version: ''};
     } else if ($event.model.type === 'destination') {
       this.resetDialog();
       this.destination = $event.model.value;
@@ -168,6 +179,7 @@
         : this.model.computational_name = null;
       this.uploadLibGroups();
       this.getInstalledLibsByResource();
+      this.libSearch.disable();
     }
     this.filterList();
   }
@@ -177,37 +189,52 @@
   }
 
   public isDuplicated(item) {
-    const select = { group: this.group, name: item.name, version: item.version };
-
-    this.isInSelectedList = this.model.selectedLibs.filter(el => JSON.stringify(el) === JSON.stringify(select)).length > 0;
-
-    if (this.destination && this.destination.libs)
-      this.isInstalled = this.destination.libs.findIndex(libr => {
-        return select.group !== 'java'
-          ? select.name === libr.name && select.group === libr.group && select.version === libr.version
-          : select.name === libr.name && select.group === libr.group;
-      }) >= 0;
-
-    return this.isInSelectedList || this.isInstalled;
+    if (this.filteredList) {
+      if (this.group !== 'java') {
+        this.selectedLib = this.filteredList.find(lib => lib.name.toLowerCase() === item.name.toLowerCase());
+      } else {
+        this.selectedLib = this.filteredList.find(lib => {
+          return lib.name.toLowerCase() === item.name.substring(0, item.name.lastIndexOf(':')).toLowerCase();
+        });
+      }
+    } else {
+      this.selectedLib = null;
+    }
   }
 
   public addLibrary(item): void {
-    const lib = item.split(':').filter(v => !!v);
-    this.model.selectedLibs.push({ group: this.group, name: lib[0], version: lib[1] || 'N/A' });
-    this.query = '';
-    this.libSearch.setValue('');
-    this.filteredList = null;
+    if (this.selectedLib && !this.selectedLib.isInSelectedList) {
+      if (this.group !== 'java') {
+        this.model.selectedLibs.push({ group: this.group, name: item.name, version: item.version || 'N/A' });
+      } else {
+        this.model.selectedLibs.push({
+          group: this.group, name: item.name.substring(0, item.name.lastIndexOf(':')),
+          version: item.name.substring(item.name.lastIndexOf(':') + 1) || 'N/A'
+        });
+      }
+      this.libSearch.setValue('');
+      this.lib = {name: '', version: ''};
+      this.filteredList = null;
+    }
   }
 
   public selectLibrary(item): void {
-    // this.model.selectedLibs.push({ group: this.group, name: item.name, version: item.version });
-    // this.query = '';
-    this.libSearch.setValue(item.name + ':');
-    this.filteredList = null;
+    if (item.isInSelectedList) {
+      return;
+    }
+    if (this.group === 'java') {
+      this.libSearch.setValue(item.name + ':' + item.version);
+      this.lib.name = item.name + ':' + item.version;
+    } else {
+      this.libSearch.setValue(item.name);
+      this.lib.name = item.name;
+    }
+    this.matAutoComplete.closePanel();
   }
 
   public removeSelectedLibrary(item): void {
     this.model.selectedLibs.splice(this.model.selectedLibs.indexOf(item), 1);
+    this.getMatchedLibs();
   }
 
   public open(notebook): void {
@@ -220,7 +247,7 @@
           this.resetDialog();
         }
       },
-      error => this.toastr.error(error.message || 'Library installation failed!', 'Oops!'),
+      error => this.toastr.error(error.message || 'Library installation error!', 'Oops!'),
       () => {
         this.getInstalledLibrariesList(true);
         this.changeDetector.detectChanges();
@@ -237,7 +264,7 @@
   public isInstallingInProgress(): void {
     this.installingInProgress = this.notebookLibs.some(lib => lib.filteredStatus.some(status => status.status === 'installing'));
       if (this.installingInProgress) {
-        clearTimeout(this.loadLibsTimer);
+        window.clearTimeout(this.loadLibsTimer);
         this.loadLibsTimer = window.setTimeout(() => this.getInstalledLibrariesList(), 10000);
       }
     }
@@ -254,6 +281,9 @@
 
   private getInstalledLibrariesList(init?: boolean) {
     this.model.getInstalledLibrariesList(this.notebook)
+      .pipe(
+        takeUntil(this.unsubscribe$)
+      )
       .subscribe((data: any) => {
         if ( !this.filtredNotebookLibs.length || data.length !== this.notebookLibs.length) {
           this.filtredNotebookLibs = [...data];
@@ -285,6 +315,9 @@
 
   private getInstalledLibsByResource() {
     this.librariesInstallationService.getInstalledLibsByResource(this.notebook.project, this.notebook.name, this.model.computational_name)
+      .pipe(
+        takeUntil(this.unsubscribe$)
+      )
       .subscribe((data: any) => this.destination.libs = data);
   }
 
@@ -302,45 +335,81 @@
 
   private getFilteredList(): void {
     this.validity_format = '';
-
-    if (this.group === 'java') {
-      this.model.getDependencies(this.query)
-        .subscribe(
-          lib => this.filteredList = [lib],
-          error => {
-            if (error.status === HTTP_STATUS_CODES.NOT_FOUND
-              || error.status === HTTP_STATUS_CODES.BAD_REQUEST
-              || error.status === HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) {
-              this.validity_format = error.message;
-              this.filteredList = null;
-            }
-          });
-    } else {
-      this.model.getLibrariesList(this.group, this.query)
-        .subscribe((libs: Library[]) => {
-          console.log('libs', libs);
-          console.log(this.query.slice(0, this.query.indexOf(':')));
-          this.isLibExist = libs.some(v => v.name === this.query.slice(0, this.query.indexOf(':')));
-          this.filteredList = libs;
-        });
+    if (this.lib.name.length > 1) {
+      if (this.group === 'java') {
+        this.model.getDependencies(this.lib.name)
+          .pipe(
+            takeUntil(this.unsubscribe$)
+          )
+          .subscribe(
+            libs => {
+              this.filteredList = [libs];
+              this.filteredList.forEach(lib => {
+                lib.isInSelectedList = this.model.selectedLibs.some(el => lib.name.toLowerCase() === el.name.substring(0, el.name.lastIndexOf(':')).toLowerCase());
+                lib.isInstalled = this.notebookLibs.some(libr => {
+                    return lib.name.toLowerCase() === libr.name.substring(0, libr.name.lastIndexOf(':')).toLowerCase() &&
+                      this.group === libr.group &&
+                      libr.status.some(res => res.resource === this.destination.name);
+                  }
+                );
+              });
+              this.isDuplicated(this.lib);
+            },
+            error => {
+              if (error.status === HTTP_STATUS_CODES.NOT_FOUND
+                || error.status === HTTP_STATUS_CODES.BAD_REQUEST
+                || error.status === HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) {
+                this.validity_format = error.message;
+                if (error.message.indexOf('query param artifact') !== -1) {
+                  this.validity_format = 'Wrong library name format. Should be <groupId>:<artifactId>:<versionId>.';
+                }
+                if (error.message.indexOf('not found') !== -1) {
+                  this.validity_format = 'No matches found.';
+                }
+                this.filteredList = null;
+              }
+            });
+      } else {
+        this.getMatchedLibs();
+      }
     }
   }
 
+  private getMatchedLibs() {
+    this.model.getLibrariesList(this.group, this.lib.name.toLowerCase())
+      .pipe(
+        takeUntil(this.unsubscribe$)
+      )
+      .subscribe((libs: Library[]) => {
+        this.isLibExist = libs.some(v => v.name.toLowerCase() === this.lib.name.toLowerCase());
+        this.filteredList = libs;
+        this.filteredList.forEach(lib => {
+          lib.isInSelectedList = this.model.selectedLibs.some(el => el.name.toLowerCase() === lib.name.toLowerCase());
+          lib.isInstalled = this.notebookLibs.some(libr => lib.name === libr.name &&
+            this.group === libr.group &&
+            libr.status.some(res => res.resource === this.destination.name));
+        });
+        this.isDuplicated(this.lib);
+      });
+
+  }
+
   private selectorsReset(): void {
     this.destination = this.getResourcesList()[0];
     this.uploadLibGroups();
     this.getInstalledLibsByResource();
+    this.libSearch.disable();
   }
 
   private resetDialog(): void {
     this.group = '';
-    this.query = '';
+    this.lib.name = '';
     this.libSearch.setValue('');
     this.isInstalled = false;
     this.isInSelectedList = false;
     this.uploading = false;
     this.model.selectedLibs = [];
-    this.filteredList = null;
+    this.filteredList = [];
     this.groupsList = [];
 
     clearTimeout(this.clear);
@@ -417,7 +486,7 @@
   template: `
   <div class="dialog-header">
     <h4 class="modal-title" *ngIf="data.type === 'added'">Installed dependency</h4>
-    <h4 class="modal-title" *ngIf="data.type === 'available'">Library installation error</h4>
+    <h4 class="modal-title" *ngIf="data.type === 'available'">Version is not available</h4>
     <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
   </div>
 <!--  <mat-list class="resources">-->
@@ -440,54 +509,16 @@
 <!--  </mat-list>-->
 
   <div class="lib-list" *ngIf="data.type === 'added'">
-    <span class="strong">Dependency: </span>{{data.lib.add_pkgs.join(', ')}}
+    <span class="strong dependency-title">Dependency: </span><span class="packeges" *ngFor="let pack of data.lib.add_pkgs; index as i">{{pack + (i !== data.lib.add_pkgs.length - 1 ? ', ' : '')}}</span>
   </div>
   <div class="lib-list" *ngIf="data.type === 'available'">
-    <p class="terminated">Version is not available</p>
     <span class="strong">Available versions: </span>{{data.lib.available_versions.join(', ')}}
   </div>
-<!--  <div class="text-center">-->
-<!--    <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">Close</button>-->
-<!--  </div>-->
   `,
   styles: [    `
     .lib-list { max-height: 200px; overflow-x: auto; word-break: break-all; padding: 20px 30px !important; margin: 20px 0; color: #577289;}
-    .terminated{padding-bottom: 15px;}
-
-    .mat-list-base {
-      padding: 40px 30px;
-    }
-
-    .object {
-      width: 70%;
-      display: flex;
-      align-items: center;
-      padding-right: 10px;
-    }
-
-    .size {
-      width: 30%;
-    }
-    .scrolling-content.delete-list {
-      max-height: 200px;
-      overflow-y: auto;
-      padding-top: 11px;
-    }
-
-    .empty-list {
-      display: flex;
-      width: 100%;
-      justify-content: center;
-      color: #35afd5;
-      padding: 15px;
-    }
-
-    .list-header {
-      border-top: 1px solid #edf1f5;
-      border-bottom: 1px solid #edf1f5;
-      color: #577289;
-      width: 100%;
-    }
+    .packeges { word-spacing: 5px; line-height: 23px;}
+    .dependency-title{ line-height: 23px; }
   `
   ]
 })
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts
index 65896d3..b201904 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts
@@ -60,7 +60,7 @@
       project_name: this.notebook.project,
       exploratory_name: this.notebook.name,
       group: group,
-      start_with: query.slice(0, query.indexOf(':'))
+      start_with: query
     };
     if (this.computational_name)
       lib_query.computational_name = this.computational_name;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html
index d45e10b..afa556c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html
@@ -19,7 +19,7 @@
 
 <section class="table-wrapper">
   <table mat-table [dataSource]="filteredEnvironments" multiTemplateDataRows
-    class="data-grid resources mat-elevation-z6">
+    class="data-grid resources mat-elevation-z6" [trackBy]="trackBy">
 
     <ng-container matColumnDef="project">
       <td mat-cell *matCellDef="let element" [attr.colspan]="8" class="project-name"> {{ element.project }} </td>
@@ -74,11 +74,16 @@
     <ng-container matColumnDef="tag">
       <th mat-header-cell *matHeaderCellDef class="tag-col label-header">
         <span class="label"> Tags </span>
+        <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+          <i class="material-icons">
+            <span>more_vert</span>
+          </i>
+        </button>
       </th>
     </ng-container>
     <ng-container matColumnDef="resources">
       <th mat-header-cell *matHeaderCellDef class="resources-col label-header">
-        <span class="label"> Computational resources </span>
+        <span class="label"> Compute </span>
         <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
           <i class="material-icons">
             <span *ngIf="filtering && filterForm.resources.length > 0 && !collapseFilterRow">filter_list</span>
@@ -90,10 +95,15 @@
     <ng-container matColumnDef="cost">
       <th mat-header-cell *matHeaderCellDef class="cost-col label-header">
         <span class="label"> Cost </span>
+        <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+          <i class="material-icons">
+            <span>more_vert</span>
+          </i>
+        </button>
       </th>
     </ng-container>
     <ng-container matColumnDef="actions" stickyEnd>
-      <th mat-header-cell *matHeaderCellDef class="actions-col label-header">
+      <th mat-header-cell *matHeaderCellDef class="settings label-header">
         <span class="label"> Actions </span>
       </th>
     </ng-container>
@@ -101,8 +111,8 @@
     <!-- ----------------------------------------------------- -->
 
     <ng-container matColumnDef="expandedDetail">
-      <td mat-cell *matCellDef="let element" class="exploratory" [attr.colspan]="8"
-        [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'" sticky>
+      <td mat-cell *matCellDef="let element" class="exploratory" [attr.colspan]="8" sticky>
+<!--        [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'" -->
 
         <tr *ngFor="let element of element.exploratory; let i = index" class="element-row mat-row">
           <td class="name-col highlight" (click)="printDetailEnvironmentModal(element)">
@@ -247,8 +257,10 @@
     <!-- FILTER START -->
     <ng-container matColumnDef="name-filter" sticky>
       <th mat-header-cell *matHeaderCellDef class="name-col filter-row-item">
-        <input placeholder="Filter by environment name" type="text" class="form-control filter-field"
-          [value]="filterForm.name" (input)="filterForm.name = $event.target['value']" />
+        <div class="input-wrapper">
+          <input placeholder="Filter by environment name" type="text" class="form-control filter-field"
+            [value]="filterForm.name" (input)="filterForm.name = $event.target['value']" />
+        </div>
       </th>
     </ng-container>
     <ng-container matColumnDef="status-filter">
@@ -312,9 +324,9 @@
     <tr [hidden]="!collapseFilterRow" mat-header-row *matHeaderRowDef="displayedFilterColumns; sticky: true"
       class="filter-row"></tr>
 
-    <tr mat-row *matRowDef="let element; columns: ['project']" class="element-row"
-      [class.expanded-row]="expandedElement === element"
-      (click)="expandedElement = expandedElement === element ? null : element">
+    <tr mat-row *matRowDef="let element; columns: ['project']" class="element-row">
+<!--      [class.expanded-row]="expandedElement === element"-->
+<!--      (click)="expandedElement = expandedElement === element ? null : element">-->
     </tr>
     <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row"></tr>
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss
index 9f8d9f9..fac9b18 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss
@@ -17,11 +17,13 @@
  * under the License.
  */
 
+@import "variables";
+
 .data-table {
   width: 100%;
 }
 
-table {
+table.resources {
   width: 100%;
 
   .header-row {
@@ -29,17 +31,26 @@
     background-clip:padding-box;
     th {
       padding: 5px;
+      padding-left: 20px;
+
+      .mat-icon-button{
+        line-height: 45px;
+      }
     }
 
     .label {
       display: inline-block;
-      padding-top: 10px;
+      padding-top: 14px;
       vertical-align: super !important;
-      padding-left: 5px;
-      font-size: 12px;
+      font-size: 13px;
     }
   }
 
+  .filter-field{
+    font-size: 13px;
+    padding-left: 10px;
+  }
+
   .exploratory {
     padding: 0;
 
@@ -50,13 +61,17 @@
 
       td {
         padding: 5px;
+        padding-left: 20px;
+        display: flex;
+        align-items: center;
 
         &.name-col {
           padding-right: 5px;
-          padding-left: 24px;
+          padding-left: 21px;
           cursor: pointer;
           overflow: hidden;
           text-overflow: ellipsis;
+          //min-width: 187px;
         }
 
         &.resources-col {
@@ -78,12 +93,13 @@
   }
 
   .filter-row {
-    height: 0 !important;
     background-clip:padding-box;
 
     th {
       padding: 5px;
       background-clip: padding-box;
+
+
       &:last-child {
         padding-right: 6px;
       }
@@ -91,39 +107,35 @@
   }
 
   .name-col {
-    width: 15%;
+    width: 17%;
     padding-right: 5px;
     padding-left: 24px;
     background-color: inherit;
-    &.notebook-name{
-
-    }
-    .label{
-      padding-top: 14px;
-    }
+    //min-width: 187px;
   }
 
   .project-name{
     font-weight: 600;
     color: #577289;
+    padding-left: 21px;
   }
 
+
   .status-col,
   .shape-col {
-    width: 12%;
-    .label{
-      padding-top: 14px;
-    }
+    width: 11%;
+    //min-width: 105px;
   }
   .shape-col{
     color: #577289;
     .label{
-      color: rgba(0,0,0,.54);
+      color: $table-header-color;
     }
   }
 
   .tag-col {
     width: 13%;
+    //min-width: 95px;
 
     mat-chip {
       min-height: 20px;
@@ -140,157 +152,201 @@
 
   .resources-col {
     width: 32%;
-    .label{
-      padding-top: 14px;
-    }
+    //min-width: 420px;
   }
 
   .cost-col {
     width: 10%;
-    text-align: center;
+    //min-width: 95px;
+    justify-content: space-between;
+  }
+
+  .label-header{
+    &.cost-col{
+      z-index: 6 !important;
+    }
+
+    &.status-col{
+      z-index: 10 !important;
+    }
+
+    &.resources-col {
+      z-index: 7 !important;
+    }
+
+    &.tag-col {
+      z-index: 8 !important;
+    }
+
+    &.shape-col {
+      z-index: 9 !important;
+    }
+
+    &.settings {
+      z-index: 5 !important;
+    }
   }
 
   .actions-col {
-    width: 10%;
+    //width: 10%;
     padding-right: 24px;
     text-align: right;
     background-color: inherit;
+    z-index: 5 !important;
     .label{
       padding-right: 5px;
     }
   }
-}
-
-tr.detail-row {
-  height: 0;
-}
+  tr.detail-row {
+    height: 0;
+  }
 
 
-.element-diagram {
-  min-width: 80px;
-  border: 2px solid black;
-  padding: 8px;
-  font-weight: lighter;
-  margin: 8px 0;
-  height: 104px;
-}
+  .element-diagram {
+    min-width: 80px;
+    border: 2px solid black;
+    padding: 8px;
+    font-weight: lighter;
+    margin: 8px 0;
+    height: 104px;
+  }
 
-.element-symbol {
-  font-weight: bold;
-  font-size: 40px;
-  line-height: normal;
-}
+  .element-symbol {
+    font-weight: bold;
+    font-size: 40px;
+    line-height: normal;
+  }
 
-.element-description {
-  padding: 16px;
-}
+  .element-description {
+    padding: 16px;
+  }
 
-.element-description-attribution {
-  opacity: 0.5;
-}
+  .element-description-attribution {
+    opacity: 0.5;
+  }
 
 
 
-.dashboard_table {
-  width: 100%;
-  table-layout: fixed;
-}
+  .dashboard_table {
+    width: 100%;
+    table-layout: fixed;
+  }
 
 
 
-.dashboard_table tr {
-  vertical-align: top;
-}
+  .dashboard_table tr {
+    vertical-align: top;
+  }
 
-.dashboard_table tr th span {
-  width: 50px;
-  text-align: center;
-  height: 100%;
-  line-height: 40px;
-}
+  .dashboard_table tr th span {
+    width: 50px;
+    text-align: center;
+    height: 100%;
+    line-height: 40px;
+  }
 
-.dashboard_table tr td {
-  font-size: 14px;
-  padding: 20px 15px 16px;
-}
+  .dashboard_table tr td {
+    font-size: 13px;
+    padding: 20px 15px 16px;
+  }
 
-.dashboard_table tr td,
-.dashboard_table tr th {
-  border: 1px solid #d5dfea;
-  text-align: left;
-}
+  .dashboard_table tr td,
+  .dashboard_table tr th {
+    border: 1px solid #d5dfea;
+    text-align: left;
+  }
 
-.dashboard_table tr td:last-child {
-  text-align: center;
-}
+  .dashboard_table tr td:last-child {
+    text-align: center;
+  }
 
-.dashboard_table_body td:first-child {
-  background: #f3fbfd;
-  color: #455c74;
-  font-weight: 600;
-  font-size: 16px;
-  cursor: pointer;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
+  .dashboard_table_body td:first-child {
+    background: #f3fbfd;
+    color: #455c74;
+    font-weight: 600;
+    font-size: 16px;
+    cursor: pointer;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
 
-.dashboard_table tr:nth-child(2n + 1) {
-  background: #f9fafb;
-}
+  .dashboard_table tr:nth-child(2n + 1) {
+    background: #f9fafb;
+  }
 
-.dashboard_table tr.filter-row td {
-  padding: 10px;
-}
+  .dashboard_table tr.filter-row td {
+    padding: 10px;
+  }
 
-.dashboard_table tr.filter-row td:first-child {
-  font-weight: 400;
-}
+  .dashboard_table tr.filter-row td:first-child {
+    font-weight: 400;
+  }
 
-.dashboard_table tr.filter-row td:last-child {
-  padding: 10px 0;
-}
+  .dashboard_table tr.filter-row td:last-child {
+    padding: 10px 0;
+  }
 
-.filter-row .actions {
-  text-align: right;
-  display: flex;
-  justify-content: flex-end;
-}
+  .dashboard_table tr:nth-child(2n + 1) td:first-child {
+    background: #edf6f9;
+  }
 
-.filter-row .actions button {
-  background: #fff;
-  border-color: #35afd5;
-  color: #35afd5;
-  outline: none;
-}
+  .dashboard_table th {
+    background: #a1b7d1;
+    color: #fff;
+    font-weight: 600;
+    line-height: 40px;
+    text-transform: uppercase;
+    padding-left: 12px;
+    font-size: 13px;
+  }
 
-.filter-row .actions .reset:hover {
-  border-color: #f1696e;
-  background: #f9fafb;
-  color: #f1696e;
-}
+  &.data-grid .status {
+    text-transform: capitalize;
+  }
 
-.filter-row .actions .apply:hover {
-  border-color: #49af38;
-  background: #f9fafb;
-  color: #49af38;
-}
+  .message_block td {
+    text-align: left !important;
+  }
 
-.dashboard_table tr:nth-child(2n + 1) td:first-child {
-  background: #edf6f9;
-}
+  &.data-grid .total_cost {
+    float: left;
+    display: inline-block;
+    color: #455c74;
+  }
 
-.dashboard_table th {
-  background: #a1b7d1;
-  color: #fff;
-  font-weight: 600;
-  line-height: 40px;
-  text-transform: uppercase;
-  padding-left: 12px;
-  font-size: 12px;
-}
+  .currency_details {
+    color: #35afd5;
+    cursor: pointer;
+    transition: all 0.45s ease-in-out;
+    padding-left: 10px;
+  }
 
-.data-grid .status {
-  text-transform: capitalize;
+  .currency_details:hover {
+    color: #3392b0;
+  }
+
+  .currency_details .material-icons {
+    font-size: 18px;
+  }
+
+  .mat-icon-button .mat-icon,
+  .mat-icon-button i {
+    line-height: 42px;
+    font-size: 18px;
+  }
+
+  .info {
+    padding: 40px;
+    text-align: center;
+  }
+
+  .content-row{
+    background-clip: padding-box;
+  }
+
+  .not-allow{
+    cursor: not-allowed !important;
+  }
 }
 
 .data-grid .list-menu {
@@ -299,7 +355,7 @@
   right: 15px;
   padding: 10px 15px;
   box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
-    0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
+  0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
   border: none;
   min-width: 190px;
 }
@@ -307,8 +363,9 @@
 .settings {
   position: relative;
   text-align: right;
-  min-width: 7%;
+  width: 6%;
   padding-right: 15px !important;
+  justify-content: flex-end;
 
   .actions {
     background-image: url(../../../assets/svg/settings_icon.svg);
@@ -328,7 +385,7 @@
 
 
 .data-grid .list-menu li {
-  font-size: 14px;
+  font-size: 13px;
   border-bottom: 1px solid #edf1f5;
   padding-bottom: 5px;
   cursor: pointer;
@@ -374,46 +431,13 @@
   background: #edf6f9;
 }
 
-.message_block td {
-  text-align: left !important;
+@media screen and (max-width: 1400px) {
+  table.resources {
+    .settings {
+      width: 7%;
+    }
+  }
 }
 
-.data-grid .total_cost {
-  display: inline-block;
-  width: 70%;
-  color: #455c74;
-}
 
-.currency_details {
-  float: right;
-  color: #35afd5;
-  cursor: pointer;
-  transition: all 0.45s ease-in-out;
-}
 
-.currency_details:hover {
-  color: #3392b0;
-}
-
-.currency_details .material-icons {
-  font-size: 18px;
-}
-
-.mat-icon-button .mat-icon,
-.mat-icon-button i {
-  line-height: 42px;
-  font-size: 18px;
-}
-
-.info {
-  padding: 40px;
-  text-align: center;
-}
-
-.content-row{
-  background-clip: padding-box;
-}
-
-.not-allow{
-  cursor: not-allowed !important;
-}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts
index 810304b..e4e5bf3 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts
@@ -18,7 +18,7 @@
  */
 
 import {Project} from '../../administration/project/project.component';
-import {Component, Input, OnInit} from '@angular/core';
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
 import { animate, state, style, transition, trigger } from '@angular/animations';
 import { ToastrService } from 'ngx-toastr';
 import { MatDialog } from '@angular/material/dialog';
@@ -91,6 +91,7 @@
   readonly DICTIONARY = DICTIONARY;
 
   @Input() projects: Array<any>;
+  @Output() getEnvironments: EventEmitter<any> = new EventEmitter();
 
   environments: Exploratory[];
 
@@ -119,8 +120,6 @@
   public bucketsList: BucketList;
   public activeProjectsList: any;
 
-
-
   constructor(
     public toastr: ToastrService,
     private userResourceService: UserResourceService,
@@ -146,12 +145,13 @@
     this.userResourceService.getUserProvisionedResources()
       .subscribe((result: any) => {
         this.environments = ExploratoryModel.loadEnvironments(result);
+        this.getEnvironments.emit(this.environments);
         this.getBuckets();
         this.getDefaultFilterConfiguration();
         (this.environments.length) ? this.getUserPreferences() : this.filteredEnvironments = [];
         this.healthStatus && !this.healthStatus.billingEnabled && this.modifyGrid();
         this.progressBarService.stopProgressBar();
-      }, () => this.progressBarService.stopProgressBar());
+        }, () => this.progressBarService.stopProgressBar());
   }
 
   public toggleFilterRow(): void {
@@ -225,7 +225,9 @@
 
     if (action === 'deploy') {
       this.dialog.open(ComputationalResourceCreateDialogComponent, { data: { notebook: resource, full_list: this.environments }, panelClass: 'modal-xxl' })
-        .afterClosed().subscribe(() => this.buildGrid());
+        .afterClosed().subscribe((res) => {
+        res && this.buildGrid();
+      });
     } else if (action === 'run') {
       this.userResourceService
         .runExploratoryEnvironment({ notebook_instance_name: data.name, project_name: data.project })
@@ -234,21 +236,22 @@
           error => this.toastr.error(error.message || 'Exploratory starting failed!', 'Oops!'));
     } else if (action === 'stop') {
       this.dialog.open(ConfirmationDialogComponent, { data: { notebook: data, type: ConfirmationDialogType.StopExploratory }, panelClass: 'modal-sm' })
-        .afterClosed().subscribe(() => this.buildGrid());
+        .afterClosed().subscribe((res) => {
+        res && this.buildGrid();
+      });
     } else if (action === 'terminate') {
       this.dialog.open(ConfirmationDialogComponent, { data:
           { notebook: data, type: ConfirmationDialogType.TerminateExploratory }, panelClass: 'modal-sm' })
-        .afterClosed().subscribe(() => this.buildGrid());
+        .afterClosed().subscribe((res) => res && this.buildGrid());
     } else if (action === 'install') {
       this.dialog.open(InstallLibrariesComponent, { data: data, panelClass: 'modal-fullscreen' })
-        .afterClosed().subscribe(() => this.buildGrid());
+        .afterClosed().subscribe((res) => res && this.buildGrid());
     } else if (action === 'schedule') {
       this.dialog.open(SchedulerComponent, { data: { notebook: data, type: 'EXPLORATORY' }, panelClass: 'modal-xl-s' })
-        .afterClosed().subscribe(() => this.buildGrid());
+        .afterClosed().subscribe((res) => res && this.buildGrid());
     } else if (action === 'ami') {
       this.dialog.open(AmiCreateDialogComponent, { data: data, panelClass: 'modal-sm' })
-
-        .afterClosed().subscribe(() => this.buildGrid());
+        .afterClosed().subscribe((res) => res && this.buildGrid());
     }
   }
 
@@ -260,11 +263,15 @@
           if (endpoint.status === 'ACTIVE') {
             const currEndpoint: SharedEndpoint = project.projectEndpoints[endpoint.name];
             const edgeItem: BucketList = {name: `${project.project} (${endpoint.name})`, children: [], cloud: endpoint.cloudProvider};
-            const projectBucket: string = currEndpoint.user_own_bicket_name
-              || currEndpoint.user_own_bucket_name
-              || currEndpoint.user_container_name ? currEndpoint.user_storage_account_name + '.' + currEndpoint.user_container_name : null;
-            const sharedBucket: string = currEndpoint.shared_bucket_name ||
-            currEndpoint.shared_container_name ? currEndpoint.shared_storage_account_name + '.' + currEndpoint.shared_container_name : null;
+            let projectBucket: string = currEndpoint.user_own_bicket_name
+              || currEndpoint.user_own_bucket_name;
+            if (currEndpoint.user_container_name) {
+              projectBucket = currEndpoint.user_storage_account_name + '.' + currEndpoint.user_container_name;
+            }
+            let sharedBucket: string = currEndpoint.shared_bucket_name;
+            if (currEndpoint.shared_container_name) {
+              sharedBucket = currEndpoint.shared_storage_account_name + '.' + currEndpoint.shared_container_name;
+            }
             if (projectBucket && currEndpoint.status !== 'terminated'
               && currEndpoint.status !== 'terminating' && currEndpoint.status !== 'failed') {
               edgeItem.children.push({name: projectBucket, endpoint: endpoint.name});
@@ -426,4 +433,8 @@
     }).subscribe();
   }
 
+  public trackBy(index, item) {
+    return null;
+  }
+
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html
index d47559f..ad6fc53 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html
@@ -18,7 +18,7 @@
   -->
 
 <div class="base-retreat">
-  <div class="sub-nav">
+  <div class="sub-nav resource-btns">
     <div class="selection">
       <span
         matTooltip="{{!healthStatus?.projectAssigned ? 'You are not assigned to any project' : 'You have not any active project'}}"
@@ -26,22 +26,21 @@
         [matTooltipClass]="'bucket-item-tooltip'"
         [matTooltipDisabled]="healthStatus?.projectAssigned && resourcesGrid.activeProjectsList?.length !== 0"
       >
-        <span>{{resourcesGrid.activeProject}}</span>
       <button mat-raised-button class="butt butt-create" (click)="createEnvironment()"
         [disabled]="!healthStatus?.projectAssigned || !resourcesGrid.activeProjectsList?.length">
         <i class="material-icons">add</i>Create new
       </button>
       </span>
       <div class="mat-reset">
-        <div class="control selector-wrapper" *ngIf="projects.length">
+        <div class="control selector-wrapper" *ngIf="projects?.length">
           <mat-form-field>
-            <mat-label>Select active project</mat-label>
+            <mat-label>Select project</mat-label>
             <mat-select [(value)]="resourcesGrid.activeProject">
-              <mat-option *ngIf="projects.length > 1" (click)="setActiveProject()">Show all</mat-option>
-              <mat-option *ngFor="let project of projects" [value]="project.name"
-                (click)="setActiveProject(project.name)">
-                {{ project.name }}</mat-option>
-              <mat-option *ngIf="!projects.length" class="multiple-select ml-10" disabled>Projects list is empty
+              <mat-option *ngIf="projects?.length > 1" (click)="setActiveProject('')">Show all</mat-option>
+              <mat-option *ngFor="let project of projects" [value]="project"
+                (click)="setActiveProject(project)">
+                {{ project }}</mat-option>
+              <mat-option *ngIf="!projects?.length" class="multiple-select ml-10" disabled>Projects list is empty
               </mat-option>
             </mat-select>
             <button class="caret">
@@ -60,25 +59,31 @@
       >
         <button mat-raised-button class="butt butt-tool" (click)="bucketBrowser(this.bucketStatus?.view)"
                 [disabled]="!this.bucketStatus?.view || resourcesGrid.bucketsList?.length === 0">
-        <i class="material-icons"></i>Bucket browser
-      </button>
+          <i class="material-icons"></i>Bucket browser
+        </button>
       </span>
-      <button mat-raised-button class="butt butt-tool" (click)="manageUngit()">
-        <i class="material-icons"></i>Git credentials
-      </button>
-      <button mat-raised-button class="butt butt-tool" (click)="toggleFiltering()">
-        <span *ngIf="!resourcesGrid.activeFiltering">
-          <i class="material-icons">visibility_off</i> Show active
-        </span>
-        <span *ngIf="resourcesGrid.activeFiltering">
-          <i class="material-icons">visibility</i> Show all
-        </span>
-      </button>
-      <button mat-raised-button class="butt" (click)="refreshGrid()">
-        <i class="material-icons">autorenew</i>Refresh
-      </button>
+      <span>
+        <button mat-raised-button class="butt butt-tool" (click)="manageUngit()">
+          <i class="material-icons"></i>Git credentials
+        </button>
+      </span>
+      <span>
+        <button mat-raised-button class="butt butt-tool show-all-btn" (click)="toggleFiltering()">
+          <span *ngIf="!resourcesGrid.activeFiltering">
+            <i class="material-icons">visibility_off</i> Show active
+          </span>
+          <span *ngIf="resourcesGrid.activeFiltering">
+            <i class="material-icons">visibility</i> Show all
+          </span>
+        </button>
+      </span>
+      <span>
+        <button mat-raised-button class="butt" (click)="refreshGrid()">
+          <i class="material-icons">autorenew</i>Refresh
+        </button>
+      </span>
     </div>
   </div>
   <mat-divider></mat-divider>
-  <resources-grid></resources-grid>
+  <resources-grid (getEnvironments)="getEnvironments($event)" ></resources-grid>
 </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts
index 301509d..3dadd70 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { Component, OnInit, ViewChild } from '@angular/core';
+import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
 import { ToastrService } from 'ngx-toastr';
 import { MatDialog } from '@angular/material/dialog';
 
@@ -35,10 +35,10 @@
   styleUrls: ['./resources.component.scss']
 })
 
-export class ResourcesComponent implements OnInit {
+export class ResourcesComponent implements OnInit, AfterViewInit {
   public exploratoryEnvironments: Exploratory[] = [];
   public healthStatus: any;
-  projects: Project[] = [];
+  projects = [];
 
   @ViewChild(ResourcesGridComponent, { static: true }) resourcesGrid: ResourcesGridComponent;
 
@@ -52,7 +52,11 @@
 
   ngOnInit() {
     this.getEnvironmentHealthStatus();
-    this.exploratoryEnvironments = this.resourcesGrid.environments;
+    this.projects = this.resourcesGrid.activeProjectsList;
+  }
+
+  ngAfterViewInit() {
+
   }
 
   public createEnvironment(): void {
@@ -82,6 +86,7 @@
   }
 
   public bucketBrowser(permition): void {
+    console.log(this.exploratoryEnvironments);
     const defaultBucket = this.resourcesGrid.bucketsList[0].children[0];
       permition && this.dialog.open(BucketBrowserComponent, { data:
         {
@@ -112,6 +117,12 @@
   }
 
 
+  public getEnvironments(environment) {
+    this.exploratoryEnvironments = environment;
+    this.projects = environment.map(env => env.project);
+  }
+
+
   private getEnvironmentHealthStatus() {
     this.healthStatusService.getEnvironmentHealthStatus().subscribe(
       (result: any) => {
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss
index a177f5c..ad90694 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss
@@ -28,8 +28,9 @@
   min-width: 100%;
   background: #fff;
   padding-left: 15px;
-  font-size: 14px;
-  // height: 34px;
+  font-size: 13px;
+  padding-top: 1px;
+  height: 34px;
   text-align: left;
   white-space: nowrap;
   cursor: pointer;
@@ -68,7 +69,7 @@
     span {
       color: #999;
       font-weight: 300;
-      display: inline-block;
+      //display: inline-block;
       max-width: 80%;
     }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
index a066dd5..038b54c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
@@ -29,8 +29,8 @@
   width: 100%;
   background: #fff;
   padding-left: 15px;
-  font-size: 14px;
-  // height: 34px;
+  font-size: 13px;
+  height: 34px;
   text-align: left;
   white-space: nowrap;
   cursor: pointer;
@@ -76,6 +76,7 @@
     .selected-items {
       color: #4a5c89;
       max-width: 477px;
+      padding-top: 5px;
     }
   }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts
index b8a2cff..5d39c68 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts
@@ -60,12 +60,12 @@
   }
 
   ngOnInit() {
-    if(this.data.type !== 5){
+    if (this.data.type !== 5) {
       this.confirmationType = this.data.type;
       this.notebook = this.data.notebook;
       this.model = new ConfirmationDialogModel(this.confirmationType, this.notebook,
         response => {
-          if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close();
+          if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close(true);
         },
         error => this.toastr.error(error.message || 'Action failed!', 'Oops'),
         this.data.manageAction,
@@ -75,7 +75,9 @@
 
       if (!this.confirmationType) this.filterResourcesByType(this.notebook.resources);
       this.isAliveResources = this.model.isAliveResources(this.notebook.resources);
-      this.onlyKilled = this.notebook.resources ? !this.notebook.resources.some(el => el.status !== 'terminated' && el.status !== 'failed') : false;
+      this.onlyKilled = this.notebook.resources ?
+        !this.notebook.resources.some(el => el.status !== 'terminated' && el.status !== 'failed')
+        : false;
     }
   }
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
index e185675..551e3e2 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
@@ -56,7 +56,9 @@
                   </div>
                   <span class="strong blue">by a schedule in less than 15 minutes.</span>
               </div>
-              <div *ngIf="data.type === 'message'"><span [innerHTML]="data.template"></span></div>
+              <div class="alert" *ngIf="data.type === 'message'">
+                <span  [innerHTML]="data.template"></span>
+              </div>
               <div *ngIf="data.type === 'confirmation'" class="confirm-dialog">
                   <p *ngIf="data.template; else label">
                       <span [innerHTML]="data.template"></span>
@@ -169,6 +171,7 @@
     label{cursor: pointer}
     .bottom-message{padding-top: 15px;}
     .table-header{padding-bottom: 10px;}
+    .alert{text-align: left; line-height: 22px; padding-bottom: 25px;padding-top: 15px;}
 
 
   `]
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
index e30f8db..7046696 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
@@ -38,9 +38,14 @@
   animateChild,
   state
 } from '@angular/animations';
-import {skip} from 'rxjs/operators';
+import {skip, take} from 'rxjs/operators';
 import {ProgressBarService} from '../../core/services/progress-bar.service';
 
+
+interface Quota {
+  projectQuotas: {};
+  totalQuotaUsed: number;
+}
 @Component({
   selector: 'dlab-navbar',
   templateUrl: 'navbar.component.html',
@@ -110,7 +115,7 @@
       if (this.isLoggedIn) {
         this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
           this.healthStatus = result;
-          result.status && this.checkQuoteUsed(this.healthStatus);
+          result.status && this.checkQuoteUsed();
           result.status && !result.projectAssigned && !result.admin && this.checkAssignment(this.healthStatus);
         }));
         this.subscriptions.add(timer(0, this.CHECK_ACTIVE_SCHEDULE_TIMEOUT).subscribe(() => this.refreshSchedulerData()));
@@ -148,9 +153,9 @@
     this.isExpanded = !this.isExpanded;
   }
 
-  public emitQuotes(alert, user_quota?, total_quota?): void {
+  public emitQuotes(alert, total_quota?, exideedProjects?, informProjects?): void {
     const dialogRef: MatDialogRef<NotificationDialogComponent> = this.dialog.open(NotificationDialogComponent, {
-      data: { template: this.selectAlert(alert, user_quota, total_quota), type: 'message' },
+      data: { template: this.selectAlert(alert, total_quota, exideedProjects, informProjects), type: 'message' },
       width: '550px'
     });
     dialogRef.afterClosed().subscribe(() => {
@@ -158,17 +163,38 @@
     });
   }
 
-  private checkQuoteUsed(params): void {
-    if (!this.storage.getBillingQuoteUsed() && params) {
-      let checkQuotaAlert = '';
+  private checkQuoteUsed(): void {
+    if (!this.storage.getBillingQuoteUsed( )) {
+      this.healthStatusService.getQuotaStatus().pipe(take(1)).subscribe((params: Quota) => {
+        let checkQuotaAlert = '';
+        const exceedProjects = [], informProjects = [];
+        Object.keys(params.projectQuotas).forEach(key => {
+          if (params.projectQuotas[key] > this.quotesLimit && params.projectQuotas[key] < 100) {
+            informProjects.push(key);
+          } else if (params.projectQuotas[key] >= 100) {
+            exceedProjects.push(key);
+          }
+        });
 
-      if (params.billingUserQuoteUsed >= this.quotesLimit && params.billingUserQuoteUsed < 100) checkQuotaAlert = 'user_quota';
-      if (params.billingQuoteUsed >= this.quotesLimit && params.billingQuoteUsed < 100) checkQuotaAlert = 'total_quota';
-      if (Number(params.billingUserQuoteUsed) >= 100) checkQuotaAlert = 'user_exceed';
-      if (Number(params.billingQuoteUsed) >= 100) checkQuotaAlert = 'total_exceed';
+        if (informProjects.length > 0 && exceedProjects.length === 0) checkQuotaAlert = 'project_quota';
+        if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100) checkQuotaAlert = 'total_quota';
+        if (exceedProjects.length > 0 && informProjects.length === 0) checkQuotaAlert = 'project_exceed';
+        if (informProjects.length > 0 && exceedProjects.length > 0) checkQuotaAlert = 'project_inform_and_exceed';
+        if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100 && exceedProjects.length > 0) checkQuotaAlert = 'total_quota_and_project_exceed';
+        if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100 && informProjects.length > 0 && exceedProjects.length > 0) checkQuotaAlert = 'total_quota_and_project_inform_and_exceed';
 
-      if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
-      checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.billingUserQuoteUsed, params.billingQuoteUsed);
+
+        if (Number(params.totalQuotaUsed) >= 100) checkQuotaAlert = 'total_exceed';
+
+        if (checkQuotaAlert === '') {
+          this.storage.setBillingQuoteUsed('informed');
+        } else {
+          this.storage.setBillingQuoteUsed('');
+        }
+
+        if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
+        checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.totalQuotaUsed, exceedProjects, informProjects);
+      });
     }
   }
 
@@ -206,25 +232,46 @@
       });
   }
 
-  private selectAlert(type: string, user_quota?: number, total_quota?: number): string {
+  private selectAlert(type: string, total_quota?: number, exideedProjects?: string[], informProjects?: string[]): string {
     const alerts = {
-      user_exceed: `Dear <b>${this.currentUserName}</b>,<br />
-          DLab cloud infrastructure usage quota associated with your user has been exceeded.
-          All your analytical environment will be stopped. To proceed working with environment,
-          request increase of user quota from DLab administrator.`,
-      total_exceed: `Dear <b>${this.currentUserName}</b>,<br />
+      total_quota_and_project_inform_and_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+          DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+          Once quota is depleted all your analytical environment will be stopped.<br /><br />
+          Quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+          Quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+          If quota is depleted all your analytical environment will be stopped.<br /><br />
+          To proceed working with environment you'll have to request increase of quota from DLab administrator. `,
+
+      total_quota_and_project_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+          DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+          Once quota is depleted all your analytical environment will be stopped.<br /><br />
+          Quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+          To proceed working with environment you'll have to request increase of quota from DLab administrator. `,
+
+      project_inform_and_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+          DLab cloud infrastructure usage quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+          Quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+          If quota is depleted all your analytical environment will be stopped.<br /><br />
+          To proceed working with environment, request increase of project quota from DLab administrator.`,
+      project_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+          DLab cloud infrastructure usage quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded.
+          All your analytical environment will be stopped.<br /><br />
+          To proceed working with environment,
+          request increase of project(s) quota from DLab administrator.`,
+      total_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
           DLab cloud infrastructure usage quota has been exceeded.
-          All your analytical environment will be stopped. To proceed working with environment,
+          All your analytical environment will be stopped.<br /><br />
+          To proceed working with environment,
           request increase application quota from DLab administrator.`,
-      user_quota: `Dear <b>${this.currentUserName}</b>,<br />
-          Cloud infrastructure usage quota associated with your user has been used for <b>${user_quota}%</b>.
-          Once quota is depleted all your analytical environment will be stopped.
-          To proceed working with environment you'll have to request increase of user quota from DLab administrator.`,
-      total_quota: `Dear <b>${this.currentUserName}</b>,<br />
-          DLab cloud infrastructure usage quota has been used for <b>${total_quota}%</b>.
-          Once quota is depleted all your analytical environment will be stopped.
-          To proceed working with environment you'll have to request increase of user quota from DLab administrator. `,
-      permissions: `Dear <b>${this.currentUserName}</b>,<br />
+      project_quota: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+          Cloud infrastructure usage quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+          Once quota is depleted all your analytical environment will be stopped.<br /><br />
+          To proceed working with environment you'll have to request increase of project(s) quota from DLab administrator.`,
+      total_quota: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+          DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+          Once quota is depleted all your analytical environment will be stopped.<br /><br />
+          To proceed working with environment you'll have to request increase of total quota from DLab administrator. `,
+      permissions: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
           Currently, you are not assigned to any project. To start working with the environment
           request permission from DLab administrator.`
     };
diff --git a/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html b/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html
index 4aedd1c..6fe2d98 100644
--- a/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html
@@ -15,6 +15,6 @@
   ~ KIND, either express or implied.  See the License for the
   ~ specific language governing permissions and limitations
   ~ under the License.
--->
+  -->
 
 <div #terminal id="display" class="guac-display guac-loading"></div>
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
index c00dd14..e4d0418 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
@@ -52,7 +52,8 @@
 }
 
 .modal-fullscreen {
-  width: 100vw;
+  width: 90vw;
+  max-width: 90vw !important;
   min-height: 80vh;
 }
 
@@ -374,6 +375,11 @@
   height: 30px;
 }
 
+.mat-list-item{
+  font-family: "Open Sans", sans-serif;
+  font-weight: 400;
+}
+
 .d-none{
   display: none !important;
 }
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
index 121fe6e..50aeed8 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
@@ -30,11 +30,14 @@
 }
 
 .alignleft, .al {float: left}
-.alignright, .ar {float: right}
+.alignright, .ar {float: right; left: 26px; z-index: 1010}
 .aligncenter, .ac {margin-left: auto;margin-right: auto}
 
 .mt-5 {margin-top: 5px}
 
+
+.pr-3{padding-right: 3pxr7}
+
 .pb-50 {padding-bottom: 50px;}
 
 .txt-r {text-align: right }
@@ -174,3 +177,7 @@
 input[type=file]::-webkit-file-upload-button {
     cursor: pointer;
 }
+
+.refresh-icon{
+  color: #35afd5;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
index 2500caf..ee719c5 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
@@ -28,6 +28,9 @@
     font-size: 15px;
     font-family: 'Open Sans', sans-serif;
     color: #577289;
+    &[disabled]{
+      box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
+    }
 
     i {
       margin: 0 5px 0 0;
@@ -49,6 +52,14 @@
 
     &.action {
       width: 140px;
+
+      &.install-btn{
+        margin-left: 0;
+      }
+
+      &.close-btn{
+        margin-right: 25px;
+      }
     }
 
     &.butt-success {
@@ -466,7 +477,7 @@
   position: relative;
   cursor: pointer;
   &.header-checkbox{
-    margin-top: 13px;
+    margin-top: 7px;
     float: left;
   }
   &.checked {
@@ -734,17 +745,32 @@
   }
 }
 
-.mat-table {
-  .header-row {
-    th.mat-header-cell {
+table.mat-table {
+  font-family: "Open Sans", sans-serif;
+  font-weight: 400;
+
+  .mat-cell{
+    font-size: 13px;
+  }
+  .header-row,
+  .mat-header-row{
+    .mat-header-cell {
       font-family: 'Open Sans', sans-serif;
       font-weight: 600;
+      font-size: 13px;
+      .label{
+        font-family: 'Open Sans', sans-serif;
+        font-weight: 600;
+        font-size: 13px;
+      }
     }
 
     .mat-cell {
       word-break: break-all;
       vertical-align: top;
       padding: 15px 5px 10px 5px;
+      font-size: 13px;
+      font-family: "Open Sans", sans-serif;
 
       td {
         vertical-align: baseline;
@@ -787,5 +813,175 @@
 .filter-row-item, .label-header{
   box-shadow: inset 0 -1px 0 lightgrey;
   border-bottom: none !important;
+  multi-select-dropdown, .input-wrapper{
+    position: absolute;
+    top: 10px;
+    left: 5px;
+    right: 5px;
+  }
+
+  .input-wrapper{
+    left: 10px;
+    right: 4px;
+  }
 }
 
+/* daterangepicker themes */
+#range-picker {
+  display: flex;
+  justify-content: center;
+}
+
+#range-picker path#Shape {
+  fill: #36afd5;
+}
+
+#range-picker .ng-daterangepicker,
+ {
+  border: none;
+  border-radius: 0;
+  box-shadow: none;
+}
+
+#range-picker .ng-daterangepicker .calendar {
+  z-index: 102;
+  border: 1px solid rgba(234, 234, 234, 0.64);
+  border-radius: 0;
+  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
+  0 2px 2px 0 rgba(0, 0, 0, 0.14),
+  0 1px 5px 0 rgba(0, 0, 0, 0.12);
+
+  &.is-to:after {
+    left: 250px;
+  }
+}
+
+#range-picker .ng-daterangepicker .calendar::after {
+  border-top: 1px solid rgba(234, 234, 234, 0.64);
+  border-left: 1px solid rgba(234, 234, 234, 0.64);
+}
+
+#range-picker .ng-daterangepicker .calendar .side-container .side-button {
+  background: #fff;
+  color: #718ba6;
+  border: none;
+  border-radius: 0px;
+}
+
+#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active,
+#range-picker .ng-daterangepicker .input-section .label-txt {
+  color: #35afd5;
+  display: unset;
+  font-size: 13px;
+}
+
+#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active {
+  color: #fff;
+  background: #35afd5;
+  border-radius: 10px;
+}
+
+#range-picker .ng-daterangepicker .calendar .calendar-container .day-num.is-active,
+#range-picker .ng-daterangepicker .calendar .calendar-container .days .day-num:hover {
+  background: #35afd5;
+  background-clip: padding-box;
+
+}
+
+#range-picker .ng-daterangepicker .calendar .calendar-container .day-names,
+#range-picker .ng-daterangepicker .calendar .calendar-container .days {
+  width: 310px;
+}
+
+#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-first-weekday,
+#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-last-weekday {
+  background-clip: padding-box;
+}
+
+#range-picker .ng-daterangepicker .calendar .calendar-container .day.is-within-range {
+  background: #e9f8fc
+}
+
+#range-picker .ng-daterangepicker .input-section .cal-icon svg path {
+  fill: #35afd5;
+}
+
+#range-picker .ng-daterangepicker .input-section .value-txt {
+  color: #718ba6;
+  display: unset;
+  padding-left: 5px;
+}
+
+#range-picker .ng-daterangepicker .input-section .value-txt.untouched,
+#range-picker .ng-daterangepicker .input-section .label-txt.untouched {
+  color: #fff;
+}
+
+//#range-picker .ng-daterangepicker .input-section .value-txt.untouched::after {
+//  content: 'date';
+//  position: absolute;
+//  top: 9px;
+//  left: 61px;
+//  color: #718ba6;
+//}
+
+.filter-row .actions {
+  text-align: right;
+  display: flex;
+  justify-content: flex-end;
+}
+
+.filter-row .actions button {
+  background: #fff;
+  border-color: #35afd5;
+  color: #35afd5;
+  outline: none;
+}
+
+.filter-row .actions .reset:hover {
+  border-color: #f1696e;
+  background: #f9fafb;
+  color: #f1696e;
+}
+
+.filter-row .actions .apply:hover {
+  border-color: #49af38;
+  background: #f9fafb;
+  color: #49af38;
+}
+
+#range-picker .ng-daterangepicker {
+  height: 37px;
+  width: 360px;
+  display: flex;
+  justify-content: space-between;
+
+
+  .d-none{
+    display: none;
+  }
+
+  .input-section {
+    height: 37px;
+    padding-right: 30px;
+    width: 175px;
+    box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
+  }
+}
+
+.show-all-btn.mat-raised-button .mat-button-wrapper > *{
+  vertical-align: baseline;
+}
+
+.resource-btns {
+  .mat-raised-button{
+    line-height: 38px;
+  }
+
+  .mat-select-value{
+    margin-top: 1px;
+  }
+}
+
+
+
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss
index ed038e7..e0d909d 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss
@@ -20,6 +20,8 @@
 $modal-text-color: #718aa5;
 $modal-header-color: #f6fafe;
 
+$table-header-color: rgba(0,0,0,.54);
+
 $brand-color: #4ab8dc;
 $blue-grey-color: #718ba6;
 $dark-grey-color: #455c74;
diff --git a/services/self-service/src/main/resources/webapp/src/styles.scss b/services/self-service/src/main/resources/webapp/src/styles.scss
index cc18983..a31908e 100644
--- a/services/self-service/src/main/resources/webapp/src/styles.scss
+++ b/services/self-service/src/main/resources/webapp/src/styles.scss
@@ -140,7 +140,9 @@
 .terminating,
 .failed,
 .deleting,
-.deleted {
+.deleted,
+.invalid_version,
+.installation_error{
   color: #f1696e;
 }
 
@@ -174,6 +176,10 @@
   font-size: 15px;
   font-weight: 300;
   color: #35afd5;
+  position: relative;
+  .buttons{
+    position: absolute;
+  }
 }
 
 .base-retreat {
@@ -371,6 +377,9 @@
     text-align: center;
   }
 }
+#scrolling{
+  scrollbar-width: thin;
+}
 
 #scrolling::-webkit-scrollbar,
 .list-selected mat-chip-list .mat-chip-list-wrapper::-webkit-scrollbar {
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java
index 37c4c5a..31ea3a3 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources;
 
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
@@ -16,8 +35,12 @@
 import javax.ws.rs.core.Response;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 public class KeycloakResourceTest extends TestBase {
     private SecurityService securityService = mock(SecurityService.class);
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
index e0c7ed4..f1b9810 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
@@ -441,8 +441,7 @@
 		assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
 		assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
 
-		assertEquals("{\"errors\":[\"query param artifact Wrong library name format. Should be " +
-						"<groupId>:<artifactId>:<versionId>. E.g. io.dropwizard:dropwizard-core:1.3.5\"]}",
+		assertEquals("{\"errors\":[\"query param artifact Wrong library name format. Should be <groupId>:<artifactId>:<versionId>\"]}",
 				response.readEntity(String.class));
 
 		verifyZeroInteractions(externalLibraryService);
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java
index 7c78fed..1ea8115 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.resources;
 
 import com.epam.dlab.auth.UserInfo;
@@ -31,81 +50,81 @@
 
 
 public class ProjectResourceTest extends TestBase {
-    private ProjectService projectService = mock(ProjectService.class);
-    private AccessKeyService keyService = mock(AccessKeyService.class);
+	private ProjectService projectService = mock(ProjectService.class);
+	private AccessKeyService keyService = mock(AccessKeyService.class);
 
-    @Rule
-    public final ResourceTestRule resources = getResourceTestRuleInstance(
-            new ProjectResource(projectService, keyService));
+	@Rule
+	public final ResourceTestRule resources = getResourceTestRuleInstance(
+			new ProjectResource(projectService, keyService));
 
-    @Before
-    public void setup() throws AuthenticationException {
-        authSetup();
-    }
+	@Before
+	public void setup() throws AuthenticationException {
+		authSetup();
+	}
 
-    @Test
-    public void stopProject() {
-        final Response response = resources.getJerseyTest()
-                .target("project/stop")
-                .request()
-                .header("Authorization", "Bearer " + TOKEN)
-                .post(Entity.json(getProjectActionDTO()));
+	@Test
+	public void stopProject() {
+		final Response response = resources.getJerseyTest()
+				.target("project/stop")
+				.request()
+				.header("Authorization", "Bearer " + TOKEN)
+				.post(Entity.json(getProjectActionDTO()));
 
-        assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
-        verify(projectService).stopWithResources(any(UserInfo.class), anyList(), anyString());
-        verifyNoMoreInteractions(projectService);
-    }
+		assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
+		verify(projectService).stopWithResources(any(UserInfo.class), anyList(), anyString());
+		verifyNoMoreInteractions(projectService);
+	}
 
-    @Test
-    public void startProject() {
-        final Response response = resources.getJerseyTest()
-                .target("project/start")
-                .request()
-                .header("Authorization", "Bearer " + TOKEN)
-                .post(Entity.json(getProjectActionDTO()));
+	@Test
+	public void startProject() {
+		final Response response = resources.getJerseyTest()
+				.target("project/start")
+				.request()
+				.header("Authorization", "Bearer " + TOKEN)
+				.post(Entity.json(getProjectActionDTO()));
 
-        assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
-        verify(projectService).start(any(UserInfo.class), anyList(), anyString());
-        verifyNoMoreInteractions(projectService);
-    }
+		assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
+		verify(projectService).start(any(UserInfo.class), anyList(), anyString());
+		verifyNoMoreInteractions(projectService);
+	}
 
-    @Test
-    public void generate() {
-        when(keyService.generateKeys(any(UserInfo.class))).thenReturn(new KeysDTO("somePublicKey", "somePrivateKey",
-                "user"));
+	@Test
+	public void generate() {
+		when(keyService.generateKeys(any(UserInfo.class))).thenReturn(new KeysDTO("somePublicKey", "somePrivateKey",
+				"user"));
 
-        final Response response = resources.getJerseyTest()
-                .target("/project/keys")
-                .request()
-                .header("Authorization", "Bearer " + TOKEN)
-                .post(Entity.json(""));
+		final Response response = resources.getJerseyTest()
+				.target("/project/keys")
+				.request()
+				.header("Authorization", "Bearer " + TOKEN)
+				.post(Entity.json(""));
 
-        assertEquals(HttpStatus.SC_OK, response.getStatus());
-        assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+		assertEquals(HttpStatus.SC_OK, response.getStatus());
+		assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
 
-        verify(keyService).generateKeys(getUserInfo());
-        verifyNoMoreInteractions(keyService);
-    }
+		verify(keyService).generateKeys(getUserInfo());
+		verifyNoMoreInteractions(keyService);
+	}
 
-    @Test
-    public void generateKeysWithException() {
-        doThrow(new DlabException("Can not generate private/public key pair due to"))
-                .when(keyService).generateKeys(any(UserInfo.class));
+	@Test
+	public void generateKeysWithException() {
+		doThrow(new DlabException("Can not generate private/public key pair due to"))
+				.when(keyService).generateKeys(any(UserInfo.class));
 
-        final Response response = resources.getJerseyTest()
-                .target("/project/keys")
-                .request()
-                .header("Authorization", "Bearer " + TOKEN)
-                .post(Entity.json(""));
+		final Response response = resources.getJerseyTest()
+				.target("/project/keys")
+				.request()
+				.header("Authorization", "Bearer " + TOKEN)
+				.post(Entity.json(""));
 
-        assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus());
-        assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+		assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus());
+		assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
 
-        verify(keyService).generateKeys(getUserInfo());
-        verifyNoMoreInteractions(keyService);
-    }
+		verify(keyService).generateKeys(getUserInfo());
+		verifyNoMoreInteractions(keyService);
+	}
 
-    private ProjectActionFormDTO getProjectActionDTO() {
-        return new ProjectActionFormDTO("DLAB", Collections.singletonList("https://localhost:8083/"));
-    }
+	private ProjectActionFormDTO getProjectActionDTO() {
+		return new ProjectActionFormDTO("DLAB", Collections.singletonList("https://localhost:8083/"));
+	}
 }
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java
index ea6b9cc..37395a5 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java
@@ -20,8 +20,14 @@
 package com.epam.dlab.backendapi.resources;
 
 import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.backendapi.domain.EndpointDTO;
+import com.epam.dlab.cloud.CloudProvider;
 import com.epam.dlab.rest.mappers.ResourceNotFoundExceptionMapper;
-import io.dropwizard.auth.*;
+import io.dropwizard.auth.AuthDynamicFeature;
+import io.dropwizard.auth.AuthValueFactoryProvider;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.Authorizer;
 import io.dropwizard.auth.oauth.OAuthCredentialAuthFilter;
 import io.dropwizard.testing.junit.ResourceTestRule;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
@@ -38,6 +44,11 @@
 
 	protected final String TOKEN = "TOKEN";
 	protected final String USER = "testUser";
+	protected final String ENDPOINT_NAME = "local";
+	protected final String ENDPOINT_URL = "http://localhost:8443/";
+	protected final String ENDPOINT_ACCOUNT = "account";
+	protected final String ENDPOINT_TAG = "tag";
+
 	@SuppressWarnings("unchecked")
 	private static Authenticator<String, UserInfo> authenticator = mock(Authenticator.class);
 	@SuppressWarnings("unchecked")
@@ -74,4 +85,8 @@
 	protected UserInfo getUserInfo() {
 		return new UserInfo(USER, TOKEN);
 	}
+
+	protected EndpointDTO getEndpointDTO() {
+		return new EndpointDTO(ENDPOINT_NAME, ENDPOINT_URL, ENDPOINT_ACCOUNT, ENDPOINT_TAG, EndpointDTO.EndpointStatus.ACTIVE, CloudProvider.AWS);
+	}
 }
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java
index 3c64dc6..d57efa2 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package com.epam.dlab.backendapi.service;
 
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
@@ -17,69 +36,73 @@
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class KeycloakServiceImplTest {
-    private static final String ACCESS_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJNUC15QVpENFdJRzloa" +
-            "np3R0RqQjdCeW9aNGpaV05QTjJ3X25uS1BkTnQ4In0.eyJqdGkiOiJlYTgzZTQ2OS0xNjFhLTQ1ZDUtYWI4YS1mZDUxYThmMzMwMzYiL" +
-            "CJleHAiOjE1NzA0NDQ1NTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL" +
-            "3JlYWxtcy9ETEFCX2JobGl2YSIsImF1ZCI6WyJwcm92aXNpb25pbmciLCJhY2NvdW50Il0sInN1YiI6ImRjNzczMThkLWYzN2UtNGNmO" +
-            "S1iMDgwLTU2ZTRjMWUwNDVhNSIsInR5cCI6IkJlYXJlciIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MTU3MDQ0MzMyOSwic2Vzc2lvb" +
-            "l9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZ" +
-            "XMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InNzcyI6eyJyb2xlcyI6W" +
-            "yJ0ZXN0Il19LCJwcm92aXNpb25pbmciOnsicm9sZXMiOlsidGVzdCJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3Vud" +
-            "CIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtY" +
-            "WlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.jXjqFP1xmG32NahYnw1spO7fhEyGiqeu0QdBYuo9" +
-            "y6TI8xlAy5EFQ_5SrW6UuzpZUhgCjStH3Qkk_xgLlbZ9IqnxwOmx1i8arlurKf1mY_rm2_C5JBxHdHio8in8yEMls8t-wQOT46kMJNC7" +
-            "4GUzuWWQxS1h6F1V6238rnT8_W27oFcG449ShOGOQ5Du4F9B4ur3Ns6j5oSduwUFlbY_rNpGurUmtFWXBaXM61CiezJPxXu5pHzWK6Xq" +
-            "Z1IkuEUaDDJdBf1OGi13toq88V7C-Pr7YlnyWlbZ7bw2VXAs3NAgtn_30KlgYwR9YUJ_AB5TP3u8kK0jY0vLPosuBZgKeA";
-    private static final String REFRESH_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImUyZjk0YjFmLTBhMjMtNGJi" +
-            "OS05NDUwLTdjNDQ4MTdjY2RkMCJ9.eyJqdGkiOiI0NmNiMzczMy1mM2IzLTRiYjItYmQyZC02N2FjNzg5N2VmNTUiLCJleHAiOjE1NzA" +
-            "0NDMzNTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL3JlYWxtcy9ETEF" +
-            "CX2JobGl2YSIsImF1ZCI6Imh0dHA6Ly81Mi4xMS40NS4xMTo4MDgwL2F1dGgvcmVhbG1zL0RMQUJfYmhsaXZhIiwic3ViIjoiZGM3NzM" +
-            "xOGQtZjM3ZS00Y2Y5LWIwODAtNTZlNGMxZTA0NWE1IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MCwic2V" +
-            "zc2lvbl9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ" +
-            "vZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsic3NzIjp7InJvbGVzIjpbInRlc3Q" +
-            "iXX0sInByb3Zpc2lvbmluZyI6eyJyb2xlcyI6WyJ0ZXN0Il19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWF" +
-            "uYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIn0.rzkrAprIt0-" +
-            "jD0h9ex3krzfu8UDcgnrRdocNFJmYa30";
-    @Mock
-    private Client httpClient;
-    @Mock
-    private SecurityDAO securityDAO;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private SelfServiceApplicationConfiguration conf;
+	private static final String ACCESS_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJNUC15QVpENFdJRzloa" +
+			"np3R0RqQjdCeW9aNGpaV05QTjJ3X25uS1BkTnQ4In0.eyJqdGkiOiJlYTgzZTQ2OS0xNjFhLTQ1ZDUtYWI4YS1mZDUxYThmMzMwMzYiL" +
+			"CJleHAiOjE1NzA0NDQ1NTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL" +
+			"3JlYWxtcy9ETEFCX2JobGl2YSIsImF1ZCI6WyJwcm92aXNpb25pbmciLCJhY2NvdW50Il0sInN1YiI6ImRjNzczMThkLWYzN2UtNGNmO" +
+			"S1iMDgwLTU2ZTRjMWUwNDVhNSIsInR5cCI6IkJlYXJlciIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MTU3MDQ0MzMyOSwic2Vzc2lvb" +
+			"l9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZ" +
+			"XMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InNzcyI6eyJyb2xlcyI6W" +
+			"yJ0ZXN0Il19LCJwcm92aXNpb25pbmciOnsicm9sZXMiOlsidGVzdCJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3Vud" +
+			"CIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtY" +
+			"WlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.jXjqFP1xmG32NahYnw1spO7fhEyGiqeu0QdBYuo9" +
+			"y6TI8xlAy5EFQ_5SrW6UuzpZUhgCjStH3Qkk_xgLlbZ9IqnxwOmx1i8arlurKf1mY_rm2_C5JBxHdHio8in8yEMls8t-wQOT46kMJNC7" +
+			"4GUzuWWQxS1h6F1V6238rnT8_W27oFcG449ShOGOQ5Du4F9B4ur3Ns6j5oSduwUFlbY_rNpGurUmtFWXBaXM61CiezJPxXu5pHzWK6Xq" +
+			"Z1IkuEUaDDJdBf1OGi13toq88V7C-Pr7YlnyWlbZ7bw2VXAs3NAgtn_30KlgYwR9YUJ_AB5TP3u8kK0jY0vLPosuBZgKeA";
+	private static final String REFRESH_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImUyZjk0YjFmLTBhMjMtNGJi" +
+			"OS05NDUwLTdjNDQ4MTdjY2RkMCJ9.eyJqdGkiOiI0NmNiMzczMy1mM2IzLTRiYjItYmQyZC02N2FjNzg5N2VmNTUiLCJleHAiOjE1NzA" +
+			"0NDMzNTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL3JlYWxtcy9ETEF" +
+			"CX2JobGl2YSIsImF1ZCI6Imh0dHA6Ly81Mi4xMS40NS4xMTo4MDgwL2F1dGgvcmVhbG1zL0RMQUJfYmhsaXZhIiwic3ViIjoiZGM3NzM" +
+			"xOGQtZjM3ZS00Y2Y5LWIwODAtNTZlNGMxZTA0NWE1IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MCwic2V" +
+			"zc2lvbl9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ" +
+			"vZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsic3NzIjp7InJvbGVzIjpbInRlc3Q" +
+			"iXX0sInByb3Zpc2lvbmluZyI6eyJyb2xlcyI6WyJ0ZXN0Il19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWF" +
+			"uYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIn0.rzkrAprIt0-" +
+			"jD0h9ex3krzfu8UDcgnrRdocNFJmYa30";
+	@Mock
+	private Client httpClient;
+	@Mock
+	private SecurityDAO securityDAO;
+	@Mock(answer = Answers.RETURNS_DEEP_STUBS)
+	private SelfServiceApplicationConfiguration conf;
 
-    private KeycloakServiceImpl keycloakService;
+	private KeycloakServiceImpl keycloakService;
 
-    @Before
-    public void setUp() {
-        keycloakService = new KeycloakServiceImpl(httpClient, conf, securityDAO);
-    }
+	@Before
+	public void setUp() {
+		keycloakService = new KeycloakServiceImpl(httpClient, conf, securityDAO);
+	}
 
-    @Test
-    public void generateAccessToken() {
-        WebTarget webTarget = mock(WebTarget.class);
-        Invocation.Builder builder = mock(Invocation.Builder.class);
-        Response response = mock(Response.class);
-        Response.StatusType statusType = mock(Response.StatusType.class);
-        AccessTokenResponse tokenResponse = mock(AccessTokenResponse.class);
+	@Test
+	public void generateAccessToken() {
+		WebTarget webTarget = mock(WebTarget.class);
+		Invocation.Builder builder = mock(Invocation.Builder.class);
+		Response response = mock(Response.class);
+		Response.StatusType statusType = mock(Response.StatusType.class);
+		AccessTokenResponse tokenResponse = mock(AccessTokenResponse.class);
 
-        when(httpClient.target(anyString())).thenReturn(webTarget);
-        when(webTarget.request()).thenReturn(builder);
-        when(builder.header(any(), anyString())).thenReturn(builder);
-        when(builder.post(any())).thenReturn(response);
-        when(response.getStatusInfo()).thenReturn(statusType);
-        when(response.readEntity(AccessTokenResponse.class)).thenReturn(tokenResponse);
-        when(statusType.getFamily()).thenReturn(Response.Status.Family.SUCCESSFUL);
-        when(tokenResponse.getToken()).thenReturn(ACCESS_TOKEN);
-        doNothing().when(securityDAO).updateUser(anyString(), any(AccessTokenResponse.class));
+		when(httpClient.target(anyString())).thenReturn(webTarget);
+		when(webTarget.request()).thenReturn(builder);
+		when(builder.header(any(), anyString())).thenReturn(builder);
+		when(builder.post(any())).thenReturn(response);
+		when(response.getStatusInfo()).thenReturn(statusType);
+		when(response.readEntity(AccessTokenResponse.class)).thenReturn(tokenResponse);
+		when(statusType.getFamily()).thenReturn(Response.Status.Family.SUCCESSFUL);
+		when(tokenResponse.getToken()).thenReturn(ACCESS_TOKEN);
+		doNothing().when(securityDAO).updateUser(anyString(), any(AccessTokenResponse.class));
 
-        keycloakService.generateAccessToken(REFRESH_TOKEN);
+		keycloakService.generateAccessToken(REFRESH_TOKEN);
 
-        verify(httpClient).target(anyString());
-        verify(securityDAO).updateUser("test", tokenResponse);
-        verifyNoMoreInteractions(securityDAO, httpClient);
-    }
+		verify(httpClient).target(anyString());
+		verify(securityDAO).updateUser("test", tokenResponse);
+		verifyNoMoreInteractions(securityDAO, httpClient);
+	}
 }
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/ProjectServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/ProjectServiceImplTest.java
new file mode 100644
index 0000000..a5c9ebf
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/ProjectServiceImplTest.java
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.dao.ExploratoryDAO;
+import com.epam.dlab.backendapi.dao.ProjectDAO;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.domain.EndpointDTO;
+import com.epam.dlab.backendapi.domain.ProjectDTO;
+import com.epam.dlab.backendapi.domain.ProjectEndpointDTO;
+import com.epam.dlab.backendapi.domain.RequestId;
+import com.epam.dlab.backendapi.domain.UpdateProjectBudgetDTO;
+import com.epam.dlab.backendapi.resources.TestBase;
+import com.epam.dlab.backendapi.service.impl.ProjectServiceImpl;
+import com.epam.dlab.backendapi.util.RequestBuilder;
+import com.epam.dlab.dto.UserInstanceStatus;
+import com.epam.dlab.dto.project.ProjectActionDTO;
+import com.epam.dlab.dto.project.ProjectCreateDTO;
+import com.epam.dlab.exceptions.DlabException;
+import com.epam.dlab.exceptions.ResourceConflictException;
+import com.epam.dlab.exceptions.ResourceNotFoundException;
+import com.epam.dlab.rest.client.RESTService;
+import com.google.common.collect.Sets;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anySet;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProjectServiceImplTest extends TestBase {
+	private static final String CREATE_PRJ_API = "infrastructure/project/create";
+	private static final String TERMINATE_PRJ_API = "infrastructure/project/terminate";
+	private static final String START_PRJ_API = "infrastructure/project/start";
+	private static final String STOP_PRJ_API = "infrastructure/project/stop";
+
+	private static final String NAME1 = "name1";
+	private static final String NAME2 = "name2";
+	private static final String GROUP1 = "group1";
+	private static final String GROUP2 = "group2";
+	private static final String UUID = "uuid";
+
+	private static final List<UserInstanceStatus> notebookStatuses = Arrays.asList(
+			UserInstanceStatus.CREATING, UserInstanceStatus.STARTING, UserInstanceStatus.CREATING_IMAGE,
+			UserInstanceStatus.CONFIGURING, UserInstanceStatus.RECONFIGURING, UserInstanceStatus.STOPPING,
+			UserInstanceStatus.TERMINATING);
+	private static final UserInstanceStatus[] computeStatuses = {UserInstanceStatus.CREATING, UserInstanceStatus.CONFIGURING, UserInstanceStatus.STARTING,
+			UserInstanceStatus.RECONFIGURING, UserInstanceStatus.CREATING_IMAGE, UserInstanceStatus.STOPPING,
+			UserInstanceStatus.TERMINATING};
+
+	@Mock
+	private ProjectDAO projectDAO;
+	@Mock
+	private EndpointService endpointService;
+	@Mock
+	private RESTService provisioningService;
+	@Mock
+	private RequestBuilder requestBuilder;
+	@Mock
+	private RequestId requestId;
+	@Mock
+	private ExploratoryService exploratoryService;
+	@Mock
+	private ExploratoryDAO exploratoryDAO;
+	@Mock
+	private UserGroupDAO userGroupDao;
+	@Mock
+	private SelfServiceApplicationConfiguration configuration;
+	@InjectMocks
+	private ProjectServiceImpl projectService;
+
+	@Test
+	public void getProjects() {
+		List<ProjectDTO> projectsMock = getProjectDTOs();
+		when(projectDAO.getProjects()).thenReturn(projectsMock);
+
+		List<ProjectDTO> projects = projectService.getProjects();
+
+		assertEquals(projects, projectsMock);
+		verify(projectDAO).getProjects();
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void testGetProjects() {
+		List<ProjectDTO> projectsMock = getProjectDTOs();
+		when(projectDAO.getProjects()).thenReturn(projectsMock);
+
+		projectService.getProjects(getUserInfo());
+
+		verify(projectDAO).getProjects();
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void getUserProjects() {
+		List<ProjectDTO> projectsMock = Collections.singletonList(getProjectCreatingDTO());
+		when(projectDAO.getUserProjects(any(UserInfo.class), anyBoolean())).thenReturn(projectsMock);
+
+		List<ProjectDTO> projects = projectService.getUserProjects(getUserInfo(), Boolean.TRUE);
+
+		assertEquals(projectsMock, projects);
+		verify(projectDAO).getUserProjects(getUserInfo(), Boolean.TRUE);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void getProjectsByEndpoint() {
+		List<ProjectDTO> projectsMock = Collections.singletonList(getProjectCreatingDTO());
+		when(projectDAO.getProjectsByEndpoint(anyString())).thenReturn(projectsMock);
+
+		List<ProjectDTO> projects = projectService.getProjectsByEndpoint(ENDPOINT_NAME);
+
+		assertEquals(projectsMock, projects);
+		verify(projectDAO).getProjectsByEndpoint(ENDPOINT_NAME);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void create() {
+		when(projectDAO.get(anyString())).thenReturn(Optional.empty());
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectCreate(any(UserInfo.class), any(ProjectDTO.class), any(EndpointDTO.class))).thenReturn(newProjectCreate());
+
+		ProjectDTO projectDTO = getProjectCreatingDTO();
+		projectService.create(getUserInfo(), projectDTO, projectDTO.getName());
+
+		verify(projectDAO).get(NAME1);
+		verify(projectDAO).create(projectDTO);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(requestBuilder).newProjectCreate(getUserInfo(), projectDTO, getEndpointDTO());
+		verify(provisioningService).post(ENDPOINT_URL + CREATE_PRJ_API, TOKEN, newProjectCreate(), String.class);
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder);
+	}
+
+	@Test(expected = ResourceConflictException.class)
+	public void createWithException() {
+		when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectCreatingDTO()));
+
+		ProjectDTO projectDTO = getProjectCreatingDTO();
+		projectService.create(getUserInfo(), projectDTO, projectDTO.getName());
+
+		verify(projectDAO).get(NAME1);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void get() {
+		ProjectDTO projectMock = getProjectCreatingDTO();
+		when(projectDAO.get(anyString())).thenReturn(Optional.of(projectMock));
+
+		ProjectDTO project = projectService.get(NAME1);
+
+		assertEquals(projectMock, project);
+		verify(projectDAO).get(NAME1);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test(expected = ResourceNotFoundException.class)
+	public void getWithException() {
+		when(projectDAO.get(anyString())).thenReturn(Optional.empty());
+
+		projectService.get(NAME1);
+
+		verify(projectDAO).get(NAME1);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void terminateEndpoint() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+		projectService.terminateEndpoint(getUserInfo(), ENDPOINT_NAME, NAME1);
+
+		verify(exploratoryService).updateProjectExploratoryStatuses(getUserInfo(), NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + TERMINATE_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, exploratoryService);
+	}
+
+	@Test
+	public void terminateEndpointWithException() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenThrow(new DlabException("Exception message"));
+
+		projectService.terminateEndpoint(getUserInfo(), ENDPOINT_NAME, NAME1);
+
+		verify(exploratoryService).updateProjectExploratoryStatuses(getUserInfo(), NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+		verify(projectDAO).updateStatus(NAME1, ProjectDTO.Status.FAILED);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + TERMINATE_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, exploratoryService);
+	}
+
+	@Test
+	public void testTerminateEndpoint() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+		when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectRunningDTO()));
+		when(exploratoryDAO.fetchProjectEndpointExploratoriesWhereStatusIn(anyString(), anyListOf(String.class), anyListOf(UserInstanceStatus.class)))
+				.thenReturn(Collections.emptyList());
+
+		projectService.terminateEndpoint(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+		verify(projectDAO).get(NAME1);
+		verify(exploratoryDAO).fetchProjectEndpointExploratoriesWhereStatusIn(NAME1, Collections.singletonList(ENDPOINT_NAME), notebookStatuses, computeStatuses);
+		verify(exploratoryService).updateProjectExploratoryStatuses(getUserInfo(), NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + TERMINATE_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, exploratoryDAO);
+	}
+
+	@Test(expected = ResourceConflictException.class)
+	public void testTerminateEndpointWithException1() {
+		when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectCreatingDTO()));
+
+		projectService.terminateEndpoint(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+		verify(projectDAO).get(NAME1);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void start() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+		projectService.start(getUserInfo(), ENDPOINT_NAME, NAME1);
+
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STARTING);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + START_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+	}
+
+	@Test
+	public void testStart() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+		projectService.start(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STARTING);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + START_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+	}
+
+	@Test
+	public void stop() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+		projectService.stop(getUserInfo(), ENDPOINT_NAME, NAME1, null);
+
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STOPPING);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + STOP_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+	}
+
+	@Test
+	public void stopWithResources() {
+		when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+		when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+		when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+		when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectRunningDTO()));
+		when(exploratoryDAO.fetchProjectEndpointExploratoriesWhereStatusIn(anyString(), anyListOf(String.class), anyListOf(UserInstanceStatus.class)))
+				.thenReturn(Collections.emptyList());
+
+		projectService.stopWithResources(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+		verify(projectDAO).get(NAME1);
+		verify(exploratoryDAO).fetchProjectEndpointExploratoriesWhereStatusIn(NAME1, Collections.singletonList(ENDPOINT_NAME), notebookStatuses, computeStatuses);
+		verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STOPPING);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(ENDPOINT_URL + STOP_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+		verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+		verify(requestId).put(USER.toLowerCase(), UUID);
+		verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+	}
+
+	@Test
+	public void update() {
+	}
+
+	@Test
+	public void updateBudget() {
+		projectService.updateBudget(getUserInfo(), Collections.singletonList(getUpdateProjectBudgetDTO()));
+
+		verify(projectDAO).updateBudget(NAME1, 10, true);
+		verifyNoMoreInteractions(projectDAO);
+	}
+
+	@Test
+	public void isAnyProjectAssigned() {
+		when(userGroupDao.getUserGroups(anyString())).thenReturn(Sets.newHashSet(GROUP1));
+		when(projectDAO.isAnyProjectAssigned(anySet())).thenReturn(Boolean.TRUE);
+
+		final boolean anyProjectAssigned = projectService.isAnyProjectAssigned(getUserInfo());
+
+		assertEquals(anyProjectAssigned, Boolean.TRUE);
+		verify(userGroupDao).getUserGroups(USER.toLowerCase());
+		verify(projectDAO).isAnyProjectAssigned(Sets.newHashSet(GROUP1));
+		verifyNoMoreInteractions(userGroupDao, projectDAO);
+	}
+
+	@Test
+	public void checkExploratoriesAndComputationalProgress() {
+		when(exploratoryDAO.fetchProjectEndpointExploratoriesWhereStatusIn(anyString(), anyListOf(String.class), anyListOf(UserInstanceStatus.class)))
+				.thenReturn(Collections.emptyList());
+
+		final boolean b = projectService.checkExploratoriesAndComputationalProgress(NAME1, Collections.singletonList(ENDPOINT_NAME));
+
+		assertEquals(b, Boolean.TRUE);
+		verify(exploratoryDAO).fetchProjectEndpointExploratoriesWhereStatusIn(NAME1, Collections.singletonList(ENDPOINT_NAME), notebookStatuses, computeStatuses);
+		verifyNoMoreInteractions(exploratoryDAO);
+	}
+
+	private List<ProjectDTO> getProjectDTOs() {
+		ProjectDTO project1 = ProjectDTO.builder()
+				.name(NAME1)
+				.groups(getGroup(GROUP1))
+				.build();
+		ProjectDTO project2 = ProjectDTO.builder()
+				.name(NAME2)
+				.groups(getGroup(GROUP2))
+				.build();
+		return Arrays.asList(project1, project2);
+	}
+
+	private ProjectDTO getProjectCreatingDTO() {
+		ProjectEndpointDTO projectEndpointDTO = new ProjectEndpointDTO(ENDPOINT_NAME, UserInstanceStatus.CREATING, null);
+		return ProjectDTO.builder()
+				.name(NAME1)
+				.groups(getGroup(GROUP1))
+				.endpoints(Collections.singletonList(projectEndpointDTO))
+				.build();
+	}
+
+	private ProjectDTO getProjectRunningDTO() {
+		ProjectEndpointDTO projectEndpointDTO = new ProjectEndpointDTO(ENDPOINT_NAME, UserInstanceStatus.RUNNING, null);
+		return ProjectDTO.builder()
+				.name(NAME1)
+				.groups(getGroup(GROUP1))
+				.endpoints(Collections.singletonList(projectEndpointDTO))
+				.build();
+	}
+
+	private Set<String> getGroup(String group) {
+		return Collections.singleton(group);
+	}
+
+	private ProjectCreateDTO newProjectCreate() {
+		return ProjectCreateDTO.builder()
+				.name(NAME1)
+				.endpoint(ENDPOINT_NAME)
+				.build();
+	}
+
+	private ProjectActionDTO getProjectActionDTO() {
+		return new ProjectActionDTO(NAME1, ENDPOINT_NAME);
+	}
+
+	private UpdateProjectBudgetDTO getUpdateProjectBudgetDTO() {
+		return new UpdateProjectBudgetDTO(NAME1, 10, true);
+	}
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java
index 883630c..ef7ac34 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java
@@ -18,7 +18,7 @@
  */
 package com.epam.dlab.backendapi.service;
 
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
 import com.epam.dlab.backendapi.resources.TestBase;
 import com.epam.dlab.backendapi.resources.dto.UserRoleDto;
 import com.epam.dlab.exceptions.ResourceNotFoundException;
@@ -39,15 +39,15 @@
 @RunWith(MockitoJUnitRunner.class)
 public class UserRoleServiceImplTest extends TestBase {
 
-    private static final String ROLE_ID = "roleId";
-    @Mock
-    private UserRoleDao dao;
-    @InjectMocks
-    private UserRoleServiceImpl userRoleService;
-    @Rule
-    public ExpectedException expectedException = ExpectedException.none();
+	private static final String ROLE_ID = "roleId";
+	@Mock
+	private UserRoleDAO dao;
+	@InjectMocks
+	private UserRoleServiceImpl userRoleService;
+	@Rule
+	public ExpectedException expectedException = ExpectedException.none();
 
-    @Test
+	@Test
 	public void createRole() {
 
 		userRoleService.createRole(getUserRole());
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AccessKeyServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AccessKeyServiceImplTest.java
new file mode 100644
index 0000000..f064c42
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AccessKeyServiceImplTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service.impl;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.resources.TestBase;
+import com.epam.dlab.backendapi.resources.dto.KeysDTO;
+import com.epam.dlab.exceptions.DlabException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AccessKeyServiceImplTest extends TestBase {
+
+	@Mock
+	private SelfServiceApplicationConfiguration conf;
+
+	@InjectMocks
+	private AccessKeyServiceImpl accessKeyService;
+
+
+	@Test
+	public void generateKeys() {
+		UserInfo userInfo = getUserInfo();
+		when(conf.getPrivateKeySize()).thenReturn(2048);
+
+		KeysDTO keysDTO = accessKeyService.generateKeys(userInfo);
+
+		assertEquals("Usernames are not equal", USER.toLowerCase(), keysDTO.getUsername());
+		assertNotNull("Public key is null", keysDTO.getPublicKey());
+		assertNotNull("Private key is null", keysDTO.getPrivateKey());
+	}
+
+	@Test(expected = DlabException.class)
+	public void generateKeysWithException() {
+		UserInfo userInfo = getUserInfo();
+		when(conf.getPrivateKeySize()).thenReturn(0);
+
+		accessKeyService.generateKeys(userInfo);
+	}
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AuditServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AuditServiceImplTest.java
new file mode 100644
index 0000000..da0c002
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AuditServiceImplTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service.impl;
+
+import com.epam.dlab.backendapi.dao.AuditDAO;
+import com.epam.dlab.backendapi.domain.AuditActionEnum;
+import com.epam.dlab.backendapi.domain.AuditCreateDTO;
+import com.epam.dlab.backendapi.domain.AuditDTO;
+import com.epam.dlab.backendapi.domain.AuditResourceTypeEnum;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.refEq;
+import static org.mockito.Mockito.verify;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuditServiceImplTest {
+	private static final String USER = "user";
+	private static final String PROJECT = "project";
+	private static final String RESOURCE_NAME = "resourceName";
+	private static final String INFO = "info";
+
+	@Mock
+	private AuditDAO auditDAO;
+	@InjectMocks
+	private AuditServiceImpl auditService;
+
+	@Test
+	public void save() {
+		AuditDTO auditDTO = getAuditDTO();
+
+		auditService.save(auditDTO);
+
+		verify(auditDAO).save(refEq(auditDTO));
+	}
+
+	@Test
+	public void testSave() {
+		AuditCreateDTO auditCreateDTO = getAuditCreateDTO();
+
+		auditService.save(USER, auditCreateDTO);
+
+		verify(auditDAO).save(eq(getAuditDTO(USER, auditCreateDTO)));
+	}
+
+	@Test
+	public void getAudit() {
+		List<String> users = new ArrayList<>();
+		List<String> projects = new ArrayList<>();
+		List<String> resourceNames = new ArrayList<>();
+		List<String> resourceTypes = new ArrayList<>();
+		String dateStart = "";
+		String dateEnd = "";
+		int pageNumber = 1;
+		int pageSize = 10;
+
+		auditService.getAudit(users, projects, resourceNames, resourceTypes, dateStart, dateEnd, pageNumber, pageSize);
+
+		verify(auditDAO).getAudit(refEq(users), refEq(projects), refEq(resourceNames), refEq(resourceTypes), eq(dateStart), eq(dateEnd), eq(pageNumber), eq(pageSize));
+	}
+
+	private AuditDTO getAuditDTO() {
+		return AuditDTO.builder()
+				.user(USER)
+				.project(PROJECT)
+				.build();
+	}
+
+	private AuditDTO getAuditDTO(String user, AuditCreateDTO auditCreateDTO) {
+		return AuditDTO.builder()
+				.user(user)
+				.resourceName(auditCreateDTO.getResourceName())
+				.info(auditCreateDTO.getInfo())
+				.type(auditCreateDTO.getType())
+				.action(AuditActionEnum.FOLLOW_LINK)
+				.build();
+	}
+
+	private AuditCreateDTO getAuditCreateDTO() {
+		return new AuditCreateDTO(RESOURCE_NAME, INFO, AuditResourceTypeEnum.COMPUTE);
+	}
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java
index 4a27bb5..e8916e8 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java
@@ -20,7 +20,7 @@
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.backendapi.dao.BackupDao;
+import com.epam.dlab.backendapi.dao.BackupDAO;
 import com.epam.dlab.backendapi.resources.dto.BackupInfoRecord;
 import com.epam.dlab.dto.backup.EnvBackupDTO;
 import com.epam.dlab.dto.backup.EnvBackupStatus;
@@ -41,7 +41,16 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.refEq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class BackupServiceImplTest {
@@ -51,7 +60,7 @@
 	@Mock
 	private RESTService provisioningService;
 	@Mock
-	private BackupDao backupDao;
+	private BackupDAO backupDao;
 
 	@InjectMocks
 	private BackupServiceImpl backupService;
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BucketServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BucketServiceImplTest.java
new file mode 100644
index 0000000..641100d
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BucketServiceImplTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service.impl;
+
+import com.epam.dlab.backendapi.domain.EndpointDTO;
+import com.epam.dlab.backendapi.resources.TestBase;
+import com.epam.dlab.backendapi.service.EndpointService;
+import com.epam.dlab.dto.bucket.BucketDTO;
+import com.epam.dlab.dto.bucket.BucketDeleteDTO;
+import com.epam.dlab.dto.bucket.FolderUploadDTO;
+import com.epam.dlab.exceptions.DlabException;
+import com.epam.dlab.rest.client.RESTService;
+import org.apache.http.HttpStatus;
+import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class BucketServiceImplTest extends TestBase {
+	private static final String BUCKET_GET_OBJECTS = "%sbucket/%s";
+	private static final String BUCKET_UPLOAD_OBJECT = "%sbucket/upload";
+	private static final String BUCKET_UPLOAD_FOLDER = "%sbucket/folder/upload";
+	private static final String BUCKET_DOWNLOAD_OBJECT = "%sbucket/%s/object/%s/download";
+	private static final String BUCKET_DELETE_OBJECT = "%sbucket/objects/delete";
+	private static final String BUCKET = "bucket";
+	private static final String OBJECT = "object";
+	private static final String SIZE = "size";
+	private static final String DATE = "date";
+	private static final String FOLDER = "folder/";
+
+	@Mock
+	private EndpointService endpointService;
+	@Mock
+	private RESTService provisioningService;
+	@InjectMocks
+	private BucketServiceImpl bucketService;
+
+	@Test
+	public void getObjects() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		List<BucketDTO> objects = getBucketList();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.get(anyString(), anyString(), any(GenericType.class))).thenReturn(objects);
+
+		List<BucketDTO> actualObjects = bucketService.getObjects(getUserInfo(), BUCKET, ENDPOINT_NAME);
+
+		assertEquals("lists should be equal", objects, actualObjects);
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).get(String.format(BUCKET_GET_OBJECTS, ENDPOINT_URL, BUCKET), TOKEN, new GenericType<List<BucketDTO>>() {
+		});
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void getObjectsWithException() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.get(anyString(), anyString(), any(GenericType.class))).thenThrow(new DlabException("Exception message"));
+
+		bucketService.getObjects(getUserInfo(), BUCKET, ENDPOINT_NAME);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).get(String.format(BUCKET_GET_OBJECTS, ENDPOINT_URL, BUCKET), TOKEN, new GenericType<List<BucketDTO>>() {
+		});
+
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test
+	public void uploadObject() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		Response response = Response.ok().build();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.postForm(anyString(), anyString(), any(FormDataMultiPart.class), any())).thenReturn(response);
+
+		bucketService.uploadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, getInputStream(), APPLICATION_JSON, 0, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).postForm(eq(String.format(BUCKET_UPLOAD_OBJECT, ENDPOINT_URL)), eq(TOKEN), any(FormDataMultiPart.class), eq(Response.class));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void uploadObjectWithException1() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		Response response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.postForm(anyString(), anyString(), any(FormDataMultiPart.class), any())).thenReturn(response);
+
+		bucketService.uploadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, getInputStream(), APPLICATION_JSON, 0, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).postForm(eq(String.format(BUCKET_UPLOAD_OBJECT, ENDPOINT_URL)), eq(TOKEN), any(FormDataMultiPart.class), eq(Response.class));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void uploadObjectWithException2() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+
+		bucketService.uploadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, null, APPLICATION_JSON, 0, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test
+	public void uploadFolder() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		Response response = Response.ok().build();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.post(anyString(), anyString(), any(FolderUploadDTO.class), any())).thenReturn(response);
+
+		bucketService.uploadFolder(getUserInfo(), BUCKET, FOLDER, ENDPOINT_NAME, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(eq(String.format(BUCKET_UPLOAD_FOLDER, ENDPOINT_URL)), eq(TOKEN), eq(getFolderUploadDTO()), eq(Response.class));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void uploadFolderWithException1() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		Response response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.post(anyString(), anyString(), any(FolderUploadDTO.class), any())).thenReturn(response);
+
+		bucketService.uploadFolder(getUserInfo(), BUCKET, FOLDER, ENDPOINT_NAME, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(eq(String.format(BUCKET_UPLOAD_FOLDER, ENDPOINT_URL)), eq(TOKEN), eq(getFolderUploadDTO()), eq(Response.class));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void uploadFolderWithException2() {
+		bucketService.uploadFolder(getUserInfo(), BUCKET, "folder_name_without_slash", ENDPOINT_NAME, null);
+	}
+
+	@Test
+	public void downloadObject() throws IOException {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		HttpServletResponse response = mock(HttpServletResponse.class);
+		ServletOutputStream outputStream = mock(ServletOutputStream.class);
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.getWithMediaTypes(anyString(), anyString(), any(), anyString(), anyString())).thenReturn(getInputStream());
+		when(response.getOutputStream()).thenReturn(outputStream);
+
+		bucketService.downloadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, response, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).getWithMediaTypes(eq(String.format(BUCKET_DOWNLOAD_OBJECT, ENDPOINT_URL, BUCKET, OBJECT)), eq(TOKEN), eq(InputStream.class),
+				eq(APPLICATION_JSON), eq(APPLICATION_OCTET_STREAM));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void downloadObjectWithException() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		HttpServletResponse response = mock(HttpServletResponse.class);
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.getWithMediaTypes(anyString(), anyString(), any(), anyString(), anyString())).thenThrow(new DlabException("Exception message"));
+
+		bucketService.downloadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, response, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).getWithMediaTypes(eq(String.format(BUCKET_DOWNLOAD_OBJECT, ENDPOINT_URL, BUCKET, OBJECT)), eq(TOKEN), eq(InputStream.class),
+				eq(APPLICATION_JSON), eq(APPLICATION_OCTET_STREAM));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test
+	public void deleteObjects() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		Response response = Response.ok().build();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.post(anyString(), anyString(), any(BucketDeleteDTO.class), any())).thenReturn(response);
+
+		bucketService.deleteObjects(getUserInfo(), BUCKET, Collections.singletonList(OBJECT), ENDPOINT_NAME, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(eq(String.format(BUCKET_DELETE_OBJECT, ENDPOINT_URL)), eq(TOKEN), eq(getBucketDeleteDTO()), eq(Response.class));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	@Test(expected = DlabException.class)
+	public void deleteObjectsWithException() {
+		EndpointDTO endpointDTO = getEndpointDTO();
+		Response response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
+		when(endpointService.get(anyString())).thenReturn(endpointDTO);
+		when(provisioningService.post(anyString(), anyString(), any(BucketDeleteDTO.class), any())).thenReturn(response);
+
+		bucketService.deleteObjects(getUserInfo(), BUCKET, Collections.singletonList(OBJECT), ENDPOINT_NAME, null);
+
+		verify(endpointService).get(ENDPOINT_NAME);
+		verify(provisioningService).post(eq(String.format(BUCKET_DELETE_OBJECT, ENDPOINT_URL)), eq(TOKEN), eq(getBucketDeleteDTO()), eq(Response.class));
+		verifyNoMoreInteractions(endpointService, provisioningService);
+	}
+
+	private List<BucketDTO> getBucketList() {
+		return Collections.singletonList(BucketDTO.builder()
+				.bucket(BUCKET)
+				.object(OBJECT)
+				.size(SIZE)
+				.lastModifiedDate(DATE)
+				.build());
+	}
+
+	private FolderUploadDTO getFolderUploadDTO() {
+		return new FolderUploadDTO(BUCKET, FOLDER);
+	}
+
+	private BucketDeleteDTO getBucketDeleteDTO() {
+		return new BucketDeleteDTO(BUCKET, Collections.singletonList(OBJECT));
+	}
+
+	private ByteArrayInputStream getInputStream() {
+		return new ByteArrayInputStream("input stream".getBytes());
+	}
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java
index 85d6015..ded7347 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java
@@ -22,7 +22,7 @@
 import com.epam.dlab.auth.UserInfo;
 import com.epam.dlab.backendapi.dao.ExploratoryDAO;
 import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.resources.dto.ImageInfoRecord;
@@ -84,7 +84,7 @@
 	@Mock
 	private ExploratoryDAO exploratoryDAO;
 	@Mock
-	private ImageExploratoryDao imageExploratoryDao;
+	private ImageExploratoryDAO imageExploratoryDao;
 	@Mock
 	private ExploratoryLibDAO libDAO;
 	@Mock
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java
index 97079e3..769b0de 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java
@@ -23,7 +23,7 @@
 import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
 import com.epam.dlab.backendapi.dao.ProjectDAO;
 import com.epam.dlab.backendapi.dao.SettingsDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
 import com.epam.dlab.backendapi.domain.EndpointDTO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.service.EndpointService;
@@ -71,7 +71,7 @@
 	@Mock
 	private EndpointService endpointService;
 	@Mock
-	private UserGroupDao userGroupDao;
+	private UserGroupDAO userGroupDao;
 	@Mock
 	private SelfServiceApplicationConfiguration configuration;
 
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java
index 0e4b3d2..3b3e901 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java
@@ -20,8 +20,8 @@
 package com.epam.dlab.backendapi.service.impl;
 
 import com.epam.dlab.backendapi.dao.ProjectDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
 import com.epam.dlab.backendapi.domain.ProjectDTO;
 import com.epam.dlab.backendapi.resources.TestBase;
 import com.epam.dlab.backendapi.resources.dto.UserGroupDto;
@@ -54,25 +54,25 @@
 @RunWith(MockitoJUnitRunner.class)
 public class UserGroupServiceImplTest extends TestBase {
 
-    private static final String ROLE_ID = "Role id";
-    private static final String USER = "test";
-    private static final String GROUP = "admin";
-    @Mock
-    private UserRoleDao userRoleDao;
-    @Mock
-    private UserGroupDao userGroupDao;
-    @Mock
-    private ProjectDAO projectDAO;
-    @InjectMocks
-    private UserGroupServiceImpl userGroupService;
+	private static final String ROLE_ID = "Role id";
+	private static final String USER = "test";
+	private static final String GROUP = "admin";
+	@Mock
+	private UserRoleDAO userRoleDao;
+	@Mock
+	private UserGroupDAO userGroupDao;
+	@Mock
+	private ProjectDAO projectDAO;
+	@InjectMocks
+	private UserGroupServiceImpl userGroupService;
 
-    @Rule
-    public ExpectedException expectedException = ExpectedException.none();
+	@Rule
+	public ExpectedException expectedException = ExpectedException.none();
 
-    @Before
-    public void setup() throws AuthenticationException {
-        authSetup();
-    }
+	@Before
+	public void setup() throws AuthenticationException {
+		authSetup();
+	}
 
     @Test
     public void createGroup() {