diff --git a/.gitignore b/.gitignore
index 1336c5cc2d0089ba4c0700b1bd960c570c9b405b..d544f3c1010615ef43fdef96465eeafdf53081e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ kubernetes/test-postgres-deployment.yaml
 kubernetes/secrets*
 clarin-dev_eurac_edu.key
 clarin_eurac_edu.key
+**/.release
+backup/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 263ee74e5e30685ea9aab01abfc9f1a4b6969844..46da80f7cd6c581f17f8397eda813f4fb51dc509 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,15 +12,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 
 
-## [1.4.0] - 2020-12-22
+## [1.4.0] - 2021-01
 
 ### Added
-- Use explicit tag for dspace checkout
+- Use dspace-app image from gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/dspace-app/
+- Test set-up for #59
+- Debug output for cron-hack in `entrypoint.sh`
+- CephFS backend for clarin-dspace:{dspace,tomcat,shibboleth}:log
 
 ### Changed
 - DEPLOYMENT.md
 - set `lr.reserve.pid.on.start = true` to show users the handle of the finished submission
-- Use clarin-dsapce@commul-2020.02.1
+- Use dsapce-app image 2020.02.1:1.1
+- Rm apt cache after apt-get update+install
+- Rebuild Postgres image with latest 9.6
+- Avoid tomcat start/kill/restart-cycle at startup
+
+### Removed
+- Use of https://github.com/ufal/lindat-aai-discovery
+
+### Fixed
+- #60
+- Changed branch names during git clone/checkout
+- [Open redirect vulnerability](https://wiki.shibboleth.net/confluence/display/SP3/Sessions)
 
 
 ## [1.3.5] - 2020-01-22
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
index 77bdf3f0a4341ac1b6f9e22276b09c3801dce61f..75930926fb429ceda1cb295098b3d40b459b5594 100644
--- a/DEPLOYMENT.md
+++ b/DEPLOYMENT.md
@@ -5,6 +5,10 @@
   - [ ] Reintroduce [Unreleased]
   - [ ] Fix [Unreleased] and add [$VERSION] named link at the end of CHANGELOG.md
 
+- [ ] Bump versions of
+      - clarin-dspace-app: `DSPACE_APP_VERSION` in docker/clarin-dspace/dockerfiles/Earthfile
+      - lindat-common: settings in docker/clarin-dspace/dockerfiles/commul-customization/variable.makefile
+
 - [ ] Commit to master to make sure that the master branch is clean and all
       commits are pushed to origin
       ```
diff --git a/clarin-dev2clarin.sh b/clarin-dev2clarin.sh
index 3005c28a2028f701eb31228376c9fa6f21f9111a..7483780baa5ae25e4047100ffa23573d5f3b23d3 100755
--- a/clarin-dev2clarin.sh
+++ b/clarin-dev2clarin.sh
@@ -5,8 +5,6 @@ perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/shibboleth2
 perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/local.properties
 perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/nginx.default.conf
 
-perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/aai.js
-perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/aai_config.js
 perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/aa-statistics.php
 perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/clarin.eurac.edu.template.metadata.xml
 perl -pi -e 's/clarin-dev/clarin/g' dockerfiles/commul-customization/webpage/index.html
@@ -26,3 +24,6 @@ echo "Modified all files to point to clarin.eurac.edu instead of clarin-dev.eura
 # adapt namespace in kubernetes yaml files
 sed -i 's/dspace-dev/dspace/' kubernetes/*.yaml
 perl -pi -e 's/clarin-dev/clarin/g' kubernetes/{dspace-ingress,dspace-deployment,nginx-deployment}.yaml
+
+# adapt branches for cloned repositories
+sed -i 's/ercc-master/ercc-production/' dockerfiles/adapt_utilities_sql.sh
diff --git a/dockerfiles/Dockerfile.dspace b/dockerfiles/Dockerfile
similarity index 73%
rename from dockerfiles/Dockerfile.dspace
rename to dockerfiles/Dockerfile
index 94db5148507638cae27ad442588ecce66a750d9a..cf37a84a431c8680b4d823357d092266385f201b 100644
--- a/dockerfiles/Dockerfile.dspace
+++ b/dockerfiles/Dockerfile
@@ -2,31 +2,30 @@
 # Dockerfile to build LINDAT Dspace container images
 # Based on Ubuntu
 ##############################################################################
-
+ARG DSPACE_APP_VERSION
 ARG UBUNTU_VERSION=16.04
+
+FROM gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/dspace-app/2020.02.1:$DSPACE_APP_VERSION as dspace-app
+
 FROM ubuntu:$UBUNTU_VERSION
 ARG UBUNTU_VERSION
 
-ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
-LABEL maintainer="Alexander König <Alexander.Koenig@eurac.edu>" \
-      maintainer="Egon W. Stemle <egon.stemle@eurac.edu>"
+LABEL author="Alexander König <Alexander.Koenig@eurac.edu>, \
+Egon W. Stemle <egon.stemle@eurac.edu>"
+LABEL maintainer="Egon W. Stemle <egon.stemle@eurac.edu>"
 
 ENV TOMCAT_VERSION="8.0.53"
 ENV TOMCAT_SHA512="cd8a4e48a629a2f2bb4ce6b101ebcce41da52b506064396ec1b2915c0b0d8d82123091242f2929a649bcd8b65ecf6cd1ab9c7d90ac0e261821097ab6fbe22df9 *apache-tomcat-8.0.53.tar.gz"
 # https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.53/bin/apache-tomcat-8.0.53.tar.gz.sha512
 
-# Our clarin-dspace tag to checkout
-ENV DSPACE_TAG="commul-2020.02.1"
-
 ENV TERM linux
 # APT(-GET) tweaks
 # Set some sane defaults for apt inside docker
 ENV DEBIAN_FRONTEND=noninteractive
 COPY apt.local.conf /etc/apt/apt.conf.d/99local.conf
-# use fast(er) local mirrors
-COPY ubuntu-$UBUNTU_VERSION.sources.list /etc/apt/sources.list
 RUN apt-get update && \
-    apt-get upgrade
+    apt-get upgrade && \
+    rm -rf /var/lib/apt/lists/*
 
 # install cpanm and dependencies
 # install jdk, ant, psql, mvn, make, libxml, xsltproc, zip, wget
@@ -35,20 +34,16 @@ RUN apt-get update && apt-get install \
     make gcc \
     cpanminus \
     openjdk-8-jdk ant maven libxml2-utils xsltproc \
-    libapr1-dev
+    libapr1-dev && \
+    rm -rf /var/lib/apt/lists/*
 
 RUN cpanm -n File::Spec::Functions && \
     cpanm Term::ReadLine
 
-# install convenience apps for debug purposes (vim and jsbeautifier)
-RUN apt-get update && apt-get install vim less python-pip
-RUN pip install jsbeautifier
-COPY commul-customization/__init__.py /usr/local/lib/python2.7/dist-packages/jsbeautifier/
-
 # set up a proper locale
-RUN apt-get update && apt-get install locales
+RUN apt-get update && apt-get install locales && rm -rf /var/lib/apt/lists/*
 RUN locale-gen en_US.UTF-8
-COPY commul-customization/default_locale /etc/default/locale
+COPY default_locale /etc/default/locale
 RUN chmod 0755 /etc/default/locale
 
 ENV LC_ALL=en_US.UTF-8
@@ -92,27 +87,16 @@ COPY commul-customization/tomcat-server.xml /opt/tomcat8/conf/server.xml
 
 
 ### Install Dspace
-#
-# pre-fetch maven dependencies
-RUN git clone --depth 1 --branch "$DSPACE_TAG" --recursive https://github.com/commul/clarin-dspace.git /opt/repository/sources/dspace
-WORKDIR /opt/repository/sources/dspace
-RUN mvn -B -T 1C \
-    --quiet \
-    --fail-never \
-    dependency:copy-dependencies dependency:resolve-plugins dependency:go-offline
-#
-# this checks if there was a new commit since the last build
-ADD https://api.github.com/repos/commul/clarin-dspace/git/refs/heads/commul-custom /tmp/version.json
-RUN git pull
-RUN mvn -B -T 1C clean compile
+COPY --from=dspace-app /app /opt/repository/sources/dspace
 
 WORKDIR /opt/repository/sources/dspace/utilities/project_helpers
 RUN ./setup.sh /opt/repository/workspace
 COPY commul-customization/variable.makefile /opt/repository/workspace/config/variable.makefile
-# COPY commul-customization/dspace.cfg /opt/repository/sources/dspace/dspace/config/dspace.cfg
 
 # install python modules: magic dateutil, lxml
-RUN apt-get update && apt-get install python-magic python-dateutil python-lxml
+RUN apt-get update && apt-get install \
+    python-magic python-dateutil python-lxml && \
+    rm -rf /var/lib/apt/lists/*
 
 # copy over configs and startup scripts
 COPY commul-customization/start_stack.sh /opt/repository/workspace/scripts/
@@ -142,11 +126,11 @@ RUN cp /opt/repository/workspace/config/etc/init.d/handle-server /etc/init.d/
 RUN chmod +x /etc/init.d/handle-server
 RUN perl -pi -e 's#DSPACE_INSTALLATION_DIRECTORY=#DSPACE_INSTALLATION_DIRECTORY=/opt/lindat-dspace/installation#' /etc/default/handle-server
 
-ARG LABEL_VERSION
-ARG LABEL_BUILD_DATE
-LABEL org.label-schema.version=$LABEL_VERSION \
-      org.label-schema.build-date=$LABEL_BUILD_DATE \
-      org.label-schema.vcs-url=$LABEL_VCS_URL
+# Install ping for livenessProbe
+RUN apt-get update && apt-get install iputils-ping && rm -rf /var/lib/apt/lists/*
+
+# Make directory to share shibboleth log files for analytics
+RUN mkdir -p /opt/shibboleth-sp-fastcgi/var/log/shibboleth
 
 # copy entrypoint script and start
 COPY commul-customization/entrypoint.sh /usr/bin/entrypoint.sh
diff --git a/dockerfiles/Dockerfile.handle b/dockerfiles/Dockerfile.handle
deleted file mode 100644
index f56410a18ce34a6f69af11b5c0196b35bbd592b5..0000000000000000000000000000000000000000
--- a/dockerfiles/Dockerfile.handle
+++ /dev/null
@@ -1,52 +0,0 @@
-############################################################
-# Dockerfile to build a handle server
-# Based on Ubuntu
-############################################################
-
-ARG UBUNTU_VERSION=16.04
-FROM ubuntu:$UBUNTU_VERSION
-ARG UBUNTU_VERSION
-
-ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
-LABEL maintainer="Alexander König <Alexander.Koenig@eurac.edu>" \
-      maintainer="Egon W. Stemle <egon.stemle@eurac.edu>"
-
-ENV TERM linux
-# APT(-GET) tweaks
-# Set some sane defaults for apt inside docker
-ENV DEBIAN_FRONTEND=noninteractive
-COPY apt.local.conf /etc/apt/apt.conf.d/99local.conf
-# use fast(er) local mirrors
-COPY ubuntu-$UBUNTU_VERSION.sources.list /etc/apt/sources.list
-RUN apt-get update && \
-    apt-get upgrade
-
-RUN apt-get update &&\
-	apt-get install openjdk-8-jdk unzip wget make cpanminus gcc
-
-# convenience packages
-RUN apt-get update && apt-get install less vim
-
-RUN cpanm Term::ReadLine
-RUN cpanm File::Spec::Functions
-
-RUN mkdir -p /hs/svr_1
-WORKDIR /hs
-RUN wget http://www.handle.net/hnr-source/hsj-8.1.1.tar.gz
-RUN tar -xzf /hs/hsj-8.1.1.tar.gz
-RUN mv hsj-8.1.1 hsj-8
-COPY commul-customization/hdl-setup.tmp /tmp/
-WORKDIR /hs/hsj-8
-RUN cat /tmp/hdl-setup.tmp | bin/hdl-setup-server /hs/svr_1/
-RUN perl -pi -e 's/YOUR_PREFIX/20.500.12084/' /hs/svr_1/config.dct
-RUN perl -pi -e 's/case_sensitive" = "no/case_sensitive" = "yes/' /hs/svr_1/config.dct
-RUN perl -i -plne 'print "    \"storage_type\" = \"CUSTOM\"\n\    \"storage_class\" = \"org.dspace.handle.HandlePlugin\"" if(/max_session/);' /hs/svr_1/config.dct
-
-ARG LABEL_VERSION
-ARG LABEL_BUILD_DATE
-LABEL org.label-schema.version=$LABEL_VERSION \
-      org.label-schema.build-date=$LABEL_BUILD_DATE \
-      org.label-schema.vcs-url=$LABEL_VCS_URL
-
-# ENTRYPOINT ["/bin/bash"]
-CMD tail -f /hs/svr_1/config.dct
diff --git a/dockerfiles/Dockerfile.nginx b/dockerfiles/Dockerfile.nginx
deleted file mode 100644
index e9fba1b601fde3eba49100d46aa91ee6f3fa6fd0..0000000000000000000000000000000000000000
--- a/dockerfiles/Dockerfile.nginx
+++ /dev/null
@@ -1,150 +0,0 @@
-##############################################################################
-# Dockerfile to build nginx and shibboleth for LINDAT Dspace container
-# Based on Ubuntu
-##############################################################################
-
-ARG UBUNTU_VERSION=16.04
-FROM ubuntu:$UBUNTU_VERSION
-ARG UBUNTU_VERSION
-
-ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
-LABEL maintainer="Alexander König <Alexander.Koenig@eurac.edu>" \
-      maintainer="Egon W. Stemle <egon.stemle@eurac.edu>"
-
-ENV TERM linux
-# APT(-GET) tweaks
-# Set some sane defaults for apt inside docker
-ENV DEBIAN_FRONTEND=noninteractive
-COPY apt.local.conf /etc/apt/apt.conf.d/99local.conf
-# use fast(er) local mirrors
-COPY ubuntu-$UBUNTU_VERSION.sources.list /etc/apt/sources.list
-RUN apt-get update && \
-    apt-get upgrade
-
-# install cpanm and dependencies
-RUN apt-get update \
-&&  apt-get install make gcc wget cpanminus
-
-RUN cpanm -n File::Spec::Functions
-RUN cpanm Term::ReadLine
-
-# install jdk, ant, psql, mvn, make, libxml, xsltproc, zip, wget
-RUN apt-get update \
-&& apt-get install ant curl libxml2-utils maven openjdk-8-jdk unzip xsltproc yui-compressor
-
-# install convenience apps for debug purposes (vim and jsbeautifier)
-RUN apt-get update && apt-get install vim less python-pip
-RUN pip install --upgrade pip
-RUN pip install jsbeautifier
-COPY commul-customization/__init__.py /usr/local/lib/python2.7/dist-packages/jsbeautifier/
-
-# set up a proper locale
-RUN apt-get update && apt-get install locales
-RUN locale-gen en_US.UTF-8
-COPY commul-customization/default_locale /etc/default/locale
-RUN chmod 0755 /etc/default/locale
-
-ENV LC_ALL=en_US.UTF-8
-ENV LANG=en_US.UTF-8
-ENV LANGUAGE=en_US.UTF-8
-
-# build nginx
-RUN apt-get update && apt-get install zlib1g zlib1g-dev libpcre3 libpcre3-dev curl
-RUN cpanm File::Spec::Functions
-RUN cpanm Term::ReadLine
-COPY commul-customization/nginx_build.sh /tmp/nginx_build.sh
-RUN chmod a+x /tmp/nginx_build.sh
-WORKDIR /tmp/
-RUN ./nginx_build.sh
-# copy the init script
-COPY commul-customization/nginx /etc/init.d/
-RUN chmod a+x /etc/init.d/nginx
-# add a symlink
-RUN ln -s /opt/nginx/sbin/nginx /usr/sbin/nginx
-# copy over static html
-COPY commul-customization/webpage/ /opt/nginx/html/
-# copy over robots.txt
-COPY commul-customization/robots-clarin-dev.txt /opt/nginx/html/robots.txt
-COPY commul-customization/google4a439c0ac1ac30d0.html /opt/nginx/html/
-RUN chown -R www-data:www-data /opt/nginx/html/
-
-#RUN mkdir /opt/nginx/html/img
-#COPY commul-customization/index.html /opt/nginx/html/
-#COPY commul-customization/eurac.png /opt/nginx/html/img/
-
-# install php
-RUN apt-get update && apt-get install php-fpm php-xml
-# copy over aa-statistics script
-RUN mkdir /opt/nginx/html/php
-COPY commul-customization/aa-statistics.php /opt/nginx/html/php/
-
-# get aai project
-RUN apt-get update && apt-get install git
-RUN git clone https://github.com/ufal/lindat-aai-discovery.git /opt/repository/sources/lindat-aai-discovery
-
-# install shibboleth
-COPY commul-customization/shibboleth_sp_with_fastcgi.sh /tmp/
-WORKDIR /tmp
-RUN chmod u+x /tmp/shibboleth_sp_with_fastcgi.sh
-RUN /tmp/shibboleth_sp_with_fastcgi.sh
-# copy the init script
-RUN cp /opt/shibboleth-sp-fastcgi/etc/shibboleth/shibd-debian /etc/init.d/shibd
-RUN chmod a+x /etc/init.d/shibd
-
-# create the test secure folder and set up perl fastcgi
-RUN mkdir /opt/nginx/html/secure
-RUN apt-get update && apt-get install fcgiwrap
-RUN cpanm CGI URI XML::Twig LWP::Protocol::https
-COPY commul-customization/shib_test.pl /opt/nginx/html/secure/
-COPY commul-customization/shib_fastcgi_params /opt/nginx/conf/
-COPY commul-customization/attribute-map.xml /opt/shibboleth-sp-fastcgi/etc/shibboleth/
-RUN chown -R www-data:www-data /opt/nginx/html/secure
-RUN chmod a+x /opt/nginx/html/secure/shib_test.pl
-
-# install supervisor
-RUN apt-get update && apt-get install python-setuptools
-RUN easy_install supervisor
-COPY commul-customization/supervisord.conf /etc/
-RUN mkdir -p /var/log/supervisor
-# create dirs for php-fpm socket/pid and log files
-RUN mkdir -p /run/php
-RUN mkdir -p /var/log/php-fpm/
-COPY commul-customization/php-fpm.conf /etc/php/7.0/fpm/
-COPY commul-customization/php.ini /etc/php/7.0/fpm/
-
-# copy over config files
-COPY commul-customization/nginx.default.conf /opt/nginx/conf/
-COPY commul-customization/nginx.conf /opt/nginx/conf/
-COPY commul-customization/repository_auth /opt/nginx/conf/
-COPY commul-customization/shibboleth2.xml /opt/shibboleth-sp-fastcgi/etc/shibboleth/
-COPY commul-customization/clarin.eurac.edu.template.metadata.xml /opt/shibboleth-sp-fastcgi/etc/shibboleth/
-COPY commul-customization/shib_clear_headers /opt/nginx/conf/
-
-# copy over config files
-COPY commul-customization/aai.js /opt/repository/sources/lindat-aai-discovery/
-WORKDIR /opt/repository/sources/lindat-aai-discovery/
-# this does not always work, because the website is often down or the certificate has run out
-# RUN touch /opt/repository/sources/lindat-aai-discovery/aai.js
-# RUN make aai.min.js
-RUN yui-compressor -o aai.min.js aai.js
-
-# copy certificate for clarin-dev
-# COPY commul-customization/certs/clarin-dev.key /etc/ssl/private/
-# COPY commul-customization/certs/clarin-dev_eurac_edu.crt /etc/ssl/certs/
-
-# if deployed on clarin instead of clarin-dev comment the two lines above and uncomment the following lines
-
-## copy certificate for clarin
-# COPY commul-customization/certs/clarin.key /etc/ssl/private/
-# COPY commul-customization/certs/clarin_eurac_edu.crt /etc/ssl/certs/
-
-# add IdP metadata from CLARIN server
-ADD https://infra.clarin.eu/aai/prod_md_about_spf_idps.xml /opt/shibboleth-sp-fastcgi/var/cache/shibboleth/
-
-ARG LABEL_VERSION
-ARG LABEL_BUILD_DATE
-LABEL org.label-schema.version=$LABEL_VERSION \
-      org.label-schema.build-date=$LABEL_BUILD_DATE \
-      org.label-schema.vcs-url=$LABEL_VCS_URL
-
-ENTRYPOINT ["/usr/local/bin/supervisord", "-c", "/etc/supervisord.conf"]
diff --git a/dockerfiles/Earthfile b/dockerfiles/Earthfile
new file mode 100644
index 0000000000000000000000000000000000000000..f2b76f9a9d63ea93b0446eff34b9839abf8666a3
--- /dev/null
+++ b/dockerfiles/Earthfile
@@ -0,0 +1,45 @@
+# Usage: earthly --push [--no-cache] +docker
+ARG DSPACE_APP_VERSION=1.1
+
+docker-from-docker:
+    FROM DOCKERFILE --build-arg DSPACE_APP_VERSION=$DSPACE_APP_VERSION .
+
+    ARG DOCKER_BASE_URL="gitlab.inf.unibz.it:4567"
+    ARG EARTHLY_GIT_PROJECT_NAME  # https://docs.earthly.dev/earthfile/builtin-args
+    ARG GIT_PROJECT_NAME="commul/docker/clarin-dspace"
+    ARG COMMUL_REGISTRY_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace/container_registry/"
+    ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
+
+    ARG AUTHOR="Egon W. Stemle <egon.stemle@eurac.edu>"
+    ARG MAINTAINER="Egon W. Stemle <egon.stemle@eurac.edu>"
+    LABEL author="$AUTHOR"
+    LABEL maintainer="$MAINTAINER"
+
+    # An updated VERSION ARG triggers an update of the texlive installation
+    ARG EARTHLY_TARGET_TAG
+    ARG VERSION=$EARTHLY_TARGET_TAG
+
+    ARG EARTHLY_GIT_HASH
+    ARG GIT_HASH=$EARTHLY_GIT_HASH
+    ARG EARTHLY_TARGET_TAG_DOCKER
+    ARG TARGET_TAG_DOCKER=$EARTHLY_TARGET_TAG_DOCKER
+    ARG DOCKER_URL="$DOCKER_BASE_URL/$GIT_PROJECT_NAME/dspace-bundle/dspace"
+
+    LABEL org.label-schema.schema-version="1.0" \  # http://label-schema.org/rc1/
+          org.label-schema.version="$VERSION" \
+          org.label-schema.vcs-url="$LABEL_VCS_URL" \
+          org.commul.git-hash="$GIT_HASH" \
+          org.commul.registry-url="$COMMUL_REGISTRY_URL" \
+          org.commul.docker-url="$DOCKER_URL"
+
+    RUN echo $VERSION > /tmp/release
+    SAVE ARTIFACT --keep-ts /tmp/release AS LOCAL ./.release
+
+    SAVE IMAGE dspace:latest
+    SAVE IMAGE --push "$DOCKER_URL:latest"
+    SAVE IMAGE --push "$DOCKER_URL:$VERSION"
+
+docker:
+    BUILD ./nginx/+docker
+    BUILD --build-arg DSPACE_APP_VERSION=$DSPACE_APP_VERSION ./postgres/+docker
+    BUILD --build-arg DSPACE_APP_VERSION=$DSPACE_APP_VERSION +docker-from-docker
diff --git a/dockerfiles/adapt_utilities_sql.sh b/dockerfiles/adapt_utilities_sql.sh
deleted file mode 100755
index 5661053be3a14e51215921e25ab032d1efd71e82..0000000000000000000000000000000000000000
--- a/dockerfiles/adapt_utilities_sql.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-git clone --depth 1 --branch commul-custom https://github.com/commul/clarin-dspace.git /tmp/dspace
-cp /tmp/dspace/utilities/utilities.sql /tmp/sql/
-cp /tmp/dspace/utilities/license_definition.txt /tmp/sql/
-chmod -R a+w /tmp/sql/
-perl -pi -e "s#afile :utildir '/license_definition.txt'#afile '/tmp/sql/license_definition.txt'#;" /tmp/sql/utilities.sql
-#perl -pi -e 's/\$DSPACE_USER/$ENV{DSPACE_USER}/g;' /tmp/sql/utilities.sql
-rm -rf /tmp/dspace
diff --git a/dockerfiles/commul-customization/__init__.py b/dockerfiles/commul-customization/__init__.py
deleted file mode 100644
index 1555a9c7790e61f1cbe489c1e10c12abde56ba3f..0000000000000000000000000000000000000000
--- a/dockerfiles/commul-customization/__init__.py
+++ /dev/null
@@ -1,2353 +0,0 @@
-from __future__ import print_function
-import sys
-import os
-import io
-import getopt
-import re
-import string
-import errno
-import copy
-import locale
-from jsbeautifier.__version__ import __version__
-
-#
-# The MIT License (MIT)
-
-# Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
-
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Originally written by Einar Lielmanis et al.,
-# Conversion to python by Einar Lielmanis, einar@jsbeautifier.org,
-# Parsing improvement for brace-less and semicolon-less statements
-#    by Liam Newman <bitwiseman@gmail.com>
-# Python is not my native language, feel free to push things around.
-#
-# Use either from command line (script displays its usage when run
-# without any parameters),
-#
-#
-# or, alternatively, use it as a module:
-#
-#   import jsbeautifier
-#   res = jsbeautifier.beautify('your javascript string')
-#   res = jsbeautifier.beautify_file('some_file.js')
-#
-#  you may specify some options:
-#
-#   opts = jsbeautifier.default_options()
-#   opts.indent_size = 2
-#   res = jsbeautifier.beautify('some javascript', opts)
-#
-#
-# Here are the available options: (read source)
-
-
-class BeautifierOptions:
-    def __init__(self):
-        self.indent_size = 4
-        self.indent_char = ' '
-        self.indent_with_tabs = False
-        self.eol = 'auto'
-        self.preserve_newlines = True
-        self.max_preserve_newlines = 10
-        self.space_in_paren = False
-        self.space_in_empty_paren = False
-        self.e4x = False
-        self.jslint_happy = False
-        self.space_after_anon_function = False
-        self.brace_style = 'collapse'
-        self.keep_array_indentation = False
-        self.keep_function_indentation = False
-        self.eval_code = False
-        self.unescape_strings = False
-        self.wrap_line_length = 0
-        self.break_chained_methods = False
-        self.end_with_newline = False
-        self.comma_first = False
-        self.operator_position = 'before-newline'
-
-        self.css = None
-        self.js = None
-        self.html = None
-
-        # For testing of beautify ignore:start directive
-        self.test_output_raw = False
-        self.editorconfig = False
-
-
-
-    def mergeOpts(self, targetType):
-        finalOpts = copy.copy(self)
-
-        local = getattr(finalOpts, targetType)
-        if (local):
-            delattr(finalOpts, targetType)
-            for key in local:
-                setattr(finalOpts, key, local[key])
-
-        return finalOpts
-
-    def __repr__(self):
-        return \
-"""indent_size = %d
-indent_char = [%s]
-preserve_newlines = %s
-max_preserve_newlines = %d
-space_in_paren = %s
-jslint_happy = %s
-space_after_anon_function = %s
-indent_with_tabs = %s
-brace_style = %s
-keep_array_indentation = %s
-eval_code = %s
-wrap_line_length = %s
-unescape_strings = %s
-""" % ( self.indent_size,
-        self.indent_char,
-        self.preserve_newlines,
-        self.max_preserve_newlines,
-        self.space_in_paren,
-        self.jslint_happy,
-        self.space_after_anon_function,
-        self.indent_with_tabs,
-        self.brace_style,
-        self.keep_array_indentation,
-        self.eval_code,
-        self.wrap_line_length,
-        self.unescape_strings,
-        )
-
-
-class BeautifierFlags:
-    def __init__(self, mode):
-        self.mode = mode
-        self.parent = None
-        self.last_text = ''
-        self.last_word = ''
-        self.declaration_statement = False
-        self.declaration_assignment = False
-        self.multiline_frame = False
-        self.inline_frame = False
-        self.if_block = False
-        self.else_block = False
-        self.do_block = False
-        self.do_while = False
-        self.import_block = False
-        self.in_case = False
-        self.in_case_statement = False
-        self.case_body = False
-        self.indentation_level = 0
-        self.line_indent_level = 0
-        self.start_line_index = 0
-        self.ternary_depth = 0
-
-    def apply_base(self, flags_base, added_newline):
-        next_indent_level = flags_base.indentation_level
-        if not added_newline and \
-            flags_base.line_indent_level > next_indent_level:
-            next_indent_level = flags_base.line_indent_level
-
-        self.parent = flags_base
-        self.last_text = flags_base.last_text
-        self.last_word = flags_base.last_word
-        self.indentation_level = next_indent_level
-
-class Acorn:
-    def __init__(self):
-        # This is not pretty, but given how we did the version import
-        # it is the only way to do this without having setup.py fail on a missing six dependency.
-        self.six = __import__("six")
-        # This section of code was translated to python from acorn (javascript).
-        #
-        # Acorn was written by Marijn Haverbeke and released under an MIT
-        # license. The Unicode regexps (for identifiers and whitespace) were
-        # taken from [Esprima](http://esprima.org) by Ariya Hidayat.
-        #
-        # Git repositories for Acorn are available at
-        #
-        #     http://marijnhaverbeke.nl/git/acorn
-        #     https://github.com/marijnh/acorn.git
-
-        # ## Character categories
-
-        # Big ugly regular expressions that match characters in the
-        # whitespace, identifier, and identifier-start categories. These
-        # are only applied when a character is found to actually have a
-        # code point above 128.
-
-        self.nonASCIIwhitespace = re.compile(self.six.u("[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]"))
-        self.nonASCIIidentifierStartChars = self.six.u("\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc")
-        self.nonASCIIidentifierChars = self.six.u("\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f")
-        self.nonASCIIidentifierStart = re.compile("[" + self.nonASCIIidentifierStartChars + "]")
-        self.nonASCIIidentifier = re.compile("[" + self.nonASCIIidentifierStartChars + self.nonASCIIidentifierChars + "]")
-
-        # Whether a single character denotes a newline.
-
-        self.newline = re.compile(self.six.u("[\n\r\u2028\u2029]"))
-
-        # Matches a whole line break (where CRLF is considered a single
-        # line break). Used to count lines.
-
-        # in javascript, these two differ
-        # in python they are the same, different methods are called on them
-        self.lineBreak = re.compile(self.six.u("\r\n|[\n\r\u2028\u2029]"))
-        self.allLineBreaks = self.lineBreak
-
-
-    # Test whether a given character code starts an identifier.
-    def isIdentifierStart(self, code):
-        if code < 65:
-            return code in [36, 64] # permit $ (36) and @ (64). @ is used in ES7 decorators.
-        if code < 91:
-            return True # 65 through 91 are uppercase letters
-        if code < 97:
-            return code == 95 # permit _ (95)
-        if code < 123:
-            return True # 97 through 123 are lowercase letters
-        return code >= 0xaa and self.nonASCIIidentifierStart.match(self.six.unichr(code)) != None
-
-    # Test whether a given character is part of an identifier.
-    def isIdentifierChar(self, code):
-        if code < 48:
-            return code == 36
-        if code < 58:
-            return True
-        if code < 65:
-            return False
-        if code < 91:
-            return True
-        if code < 97:
-            return code == 95
-        if code < 123:
-            return True
-        return code >= 0xaa and self.nonASCIIidentifier.match(self.six.unichr(code)) != None
-
-class Token:
-    def __init__(self, type, text, newlines = 0, whitespace_before = '', mode = None, parent = None):
-        self.type = type
-        self.text = text
-        self.comments_before = []
-        self.newlines = newlines
-        self.wanted_newline = newlines > 0
-        self.whitespace_before = whitespace_before
-        self.parent = None
-        self.opened = None
-        self.directives = None
-
-
-def default_options():
-    return BeautifierOptions()
-
-
-def beautify(string, opts = default_options() ):
-    b = Beautifier()
-    return b.beautify(string, opts)
-
-def set_file_editorconfig_opts(filename, js_options):
-    from editorconfig import get_properties, EditorConfigError
-    try:
-        _ecoptions = get_properties(os.path.abspath(filename))
-
-        if _ecoptions.get("indent_style") == "tab":
-            js_options.indent_with_tabs = True
-        elif _ecoptions.get("indent_style") == "space":
-            js_options.indent_with_tabs = False
-
-        if _ecoptions.get("indent_size"):
-            js_options.indent_size = int(_ecoptions["indent_size"])
-
-        if _ecoptions.get("max_line_length"):
-            if _ecoptions.get("max_line_length") == "off":
-                js_options.wrap_line_length = 0
-            else:
-                js_options.wrap_line_length = int(_ecoptions["max_line_length"])
-
-        if _ecoptions.get("insert_final_newline") == 'true':
-            js_options.end_with_newline = True
-        elif _ecoptions.get("insert_final_newline") == 'false':
-            js_options.end_with_newline = False
-
-        if _ecoptions.get("end_of_line"):
-            if _ecoptions["end_of_line"] == "cr":
-                js_options.eol = '\r'
-            elif _ecoptions["end_of_line"] == "lf":
-                js_options.eol = '\n'
-            elif _ecoptions["end_of_line"] == "crlf":
-                js_options.eol = '\r\n'
-
-    except EditorConfigError as ex:
-        # do not error on bad editor config
-        print("Error loading EditorConfig.  Ignoring.", file=sys.stderr)
-
-
-def beautify_file(file_name, opts = default_options() ):
-    input_string = ''
-    if file_name == '-': # stdin
-        try:
-            if sys.stdin.isatty():
-                raise Exception()
-
-            stream = sys.stdin
-            input_string = ''.join(stream.readlines())
-        except Exception as ex:
-            print("Must pipe input or define at least one file.", file=sys.stderr)
-            usage(sys.stderr)
-            raise Exception()
-    else:
-        stream = io.open(file_name, 'rt', newline='')
-        input_string = ''.join(stream.readlines())
-
-    return beautify(input_string, opts)
-
-
-def usage(stream=sys.stdout):
-
-    print("jsbeautifier.py@" + __version__ + """
-
-Javascript beautifier (http://jsbeautifier.org/)
-
-Usage: jsbeautifier.py [options] <infile>
-
-    <infile> can be "-", which means stdin.
-    <outfile> defaults to stdout
-
-Input options:
-
- -i,  --stdin                      Read input from stdin
-
-Output options:
-
- -s,  --indent-size=NUMBER         Indentation size. (default 4).
- -c,  --indent-char=CHAR           Character to indent with. (default space).
- -e,  --eol=STRING                 Character(s) to use as line terminators.
-                                   (default first newline in file, otherwise "\\n")
- -t,  --indent-with-tabs           Indent with tabs, overrides -s and -c
- -d,  --disable-preserve-newlines  Do not preserve existing line breaks.
- -P,  --space-in-paren             Add padding spaces within paren, ie. f( a, b )
- -E,  --space-in-empty-paren       Add a single space inside empty paren, ie. f( )
- -j,  --jslint-happy               More jslint-compatible output
- -a,  --space_after_anon_function  Add a space before an anonymous function's parens, ie. function ()
- -b,  --brace-style=collapse       Brace style (collapse, expand, end-expand, none)(,preserve-inline)
- -k,  --keep-array-indentation     Keep array indentation.
- -r,  --replace                    Write output in-place, replacing input
- -o,  --outfile=FILE               Specify a file to output to (default stdout)
- -f,  --keep-function-indentation  Do not re-indent function bodies defined in var lines.
- -x,  --unescape-strings           Decode printable chars encoded in \\xNN notation.
- -X,  --e4x                        Pass E4X xml literals through untouched
- -w,  --wrap-line-length                   Attempt to wrap line when it exceeds this length.
-                                   NOTE: Line continues until next wrap point is found.
- -n, --end_with_newline            End output with newline
- --editorconfig                    Enable setting configuration from EditorConfig
-
-Rarely needed options:
-
- --eval-code                       evaluate code if a JS interpreter is
-                                   installed. May be useful with some obfuscated
-                                   script but poses a potential security issue.
-
- -l,  --indent-level=NUMBER        Initial indentation level. (default 0).
-
- -h,  --help, --usage              Prints this help statement.
- -v, --version                     Show the version
-
-""", file=stream)
-    if stream == sys.stderr:
-        return 1
-    else:
-        return 0
-
-OPERATOR_POSITION = {
-    'before_newline': 'before-newline',
-    'after_newline': 'after-newline',
-    'preserve_newline': 'preserve-newline'
-}
-OPERATOR_POSITION_BEFORE_OR_PRESERVE = [OPERATOR_POSITION['before_newline'], OPERATOR_POSITION['preserve_newline']];
-
-def sanitizeOperatorPosition(opPosition):
-    if not opPosition:
-        return OPERATOR_POSITION['before_newline']
-    elif opPosition not in OPERATOR_POSITION.values():
-        raise ValueError("Invalid Option Value: The option 'operator_position' must be one of the following values\n" +
-            str(OPERATOR_POSITION.values()) +
-            "\nYou passed in: '" + opPosition + "'")
-
-    return opPosition
-
-class MODE:
-      BlockStatement, Statement, ObjectLiteral, ArrayLiteral, \
-      ForInitializer, Conditional, Expression = range(7)
-
-class Beautifier:
-
-    def __init__(self, opts = default_options() ):
-
-        self.opts = copy.copy(opts)
-        self.acorn = Acorn()
-        self.blank_state()
-
-    def blank_state(self, js_source_text = None):
-
-        # internal flags
-        self.flags = None
-        self.previous_flags = None
-        self.flag_store = []
-        self.tokens = []
-        self.token_pos = 0
-
-
-        # force opts.space_after_anon_function to true if opts.jslint_happy
-        if self.opts.jslint_happy:
-            self.opts.space_after_anon_function = True
-
-        if self.opts.indent_with_tabs:
-            self.opts.indent_char = "\t"
-            self.opts.indent_size = 1
-
-        if self.opts.eol == 'auto':
-            self.opts.eol = '\n'
-            if self.acorn.lineBreak.search(js_source_text or ''):
-                self.opts.eol = self.acorn.lineBreak.search(js_source_text).group()
-
-        self.opts.eol = self.opts.eol.replace('\\r', '\r').replace('\\n', '\n')
-
-        self.indent_string = self.opts.indent_char * self.opts.indent_size
-
-        self.baseIndentString = ''
-        self.last_type = 'TK_START_BLOCK' # last token type
-        self.last_last_text = ''         # pre-last token text
-
-        preindent_index = 0;
-        if not js_source_text == None and len(js_source_text) > 0:
-            while preindent_index < len(js_source_text) and \
-                    js_source_text[preindent_index] in [' ', '\t'] :
-                self.baseIndentString += js_source_text[preindent_index]
-                preindent_index += 1
-            js_source_text = js_source_text[preindent_index:]
-
-        self.output = Output(self.indent_string, self.baseIndentString)
-        # If testing the ignore directive, start with output disable set to true
-        self.output.raw = self.opts.test_output_raw;
-
-        self.set_mode(MODE.BlockStatement)
-        return js_source_text
-
-    def beautify(self, s, opts = None ):
-
-        if opts != None:
-            opts = opts.mergeOpts('js')
-            self.opts = copy.copy(opts)
-
-
-        #Compat with old form
-        if self.opts.brace_style == 'collapse-preserve-inline':
-            self.opts.brace_style = 'collapse,preserve-inline'
-
-        split = re.compile("[^a-zA-Z0-9_\-]+").split(self.opts.brace_style)
-        self.opts.brace_style = split[0]
-        self.opts.brace_preserve_inline = (True if bool(split[1] == 'preserve-inline') else None) if len(split) > 1 else False
-
-        if self.opts.brace_style not in ['expand', 'collapse', 'end-expand', 'none']:
-            raise(Exception('opts.brace_style must be "expand", "collapse", "end-expand", or "none".'))
-
-        if self.opts.brace_preserve_inline == None:
-            raise(Exception('opts.brace_style second item must be "preserve-inline"'))
-
-        s = self.blank_state(s)
-
-        input = self.unpack(s, self.opts.eval_code)
-
-        self.handlers = {
-            'TK_START_EXPR': self.handle_start_expr,
-            'TK_END_EXPR': self.handle_end_expr,
-            'TK_START_BLOCK': self.handle_start_block,
-            'TK_END_BLOCK': self.handle_end_block,
-            'TK_WORD': self.handle_word,
-            'TK_RESERVED': self.handle_word,
-            'TK_SEMICOLON': self.handle_semicolon,
-            'TK_STRING': self.handle_string,
-            'TK_EQUALS': self.handle_equals,
-            'TK_OPERATOR': self.handle_operator,
-            'TK_COMMA': self.handle_comma,
-            'TK_BLOCK_COMMENT': self.handle_block_comment,
-            'TK_COMMENT': self.handle_comment,
-            'TK_DOT': self.handle_dot,
-            'TK_UNKNOWN': self.handle_unknown,
-            'TK_EOF': self.handle_eof
-        }
-
-        self.tokens = Tokenizer(input, self.opts, self.indent_string).tokenize()
-        self.token_pos = 0
-
-        current_token = self.get_token()
-        while current_token != None:
-            self.handlers[current_token.type](current_token)
-
-            self.last_last_text = self.flags.last_text
-            self.last_type = current_token.type
-            self.flags.last_text = current_token.text
-            self.token_pos += 1
-            current_token = self.get_token()
-
-
-        sweet_code = self.output.get_code()
-        if self.opts.end_with_newline:
-            sweet_code += '\n'
-
-        if not self.opts.eol == '\n':
-            sweet_code = sweet_code.replace('\n', self.opts.eol)
-
-        return sweet_code
-
-
-    def handle_whitespace_and_comments(self, local_token, preserve_statement_flags = False):
-        newlines = local_token.newlines
-        keep_whitespace = self.opts.keep_array_indentation and self.is_array(self.flags.mode)
-
-        for comment_token in local_token.comments_before:
-            # The cleanest handling of inline comments is to treat them as though they aren't there.
-            # Just continue formatting and the behavior should be logical.
-            # Also ignore unknown tokens.  Again, this should result in better behavior.
-            self.handle_whitespace_and_comments(comment_token, preserve_statement_flags)
-            self.handlers[comment_token.type](comment_token, preserve_statement_flags)
-
-
-        if keep_whitespace:
-             for i in range(newlines):
-                    self.print_newline(i > 0, preserve_statement_flags)
-        else: # not keep_whitespace
-            if self.opts.max_preserve_newlines != 0 and newlines > self.opts.max_preserve_newlines:
-                newlines = self.opts.max_preserve_newlines
-
-            if self.opts.preserve_newlines and newlines > 1:
-                self.print_newline(False, preserve_statement_flags)
-                for i in range(1, newlines):
-                    self.print_newline(True, preserve_statement_flags)
-
-
-    def unpack(self, source, evalcode=False):
-        import jsbeautifier.unpackers as unpackers
-        try:
-            return unpackers.run(source, evalcode)
-        except unpackers.UnpackingError as error:
-            return source
-
-    def is_special_word(self, s):
-        return s in ['case', 'return', 'do', 'if', 'throw', 'else']
-
-    def is_array(self, mode):
-        return mode == MODE.ArrayLiteral
-
-
-    def is_expression(self, mode):
-        return mode in [MODE.Expression, MODE.ForInitializer, MODE.Conditional]
-
-
-    _newline_restricted_tokens = ['break','continue','return', 'throw']
-    def allow_wrap_or_preserved_newline(self, current_token, force_linewrap = False):
-        # never wrap the first token of a line.
-        if self.output.just_added_newline():
-            return
-
-        shouldPreserveOrForce = (self.opts.preserve_newlines and current_token.wanted_newline) or force_linewrap
-        operatorLogicApplies = self.flags.last_text in Tokenizer.positionable_operators or current_token.text in Tokenizer.positionable_operators
-
-        if operatorLogicApplies:
-            shouldPrintOperatorNewline = (self.flags.last_text in Tokenizer.positionable_operators and self.opts.operator_position in OPERATOR_POSITION_BEFORE_OR_PRESERVE) \
-                or current_token.text in Tokenizer.positionable_operators
-            shouldPreserveOrForce = shouldPreserveOrForce and shouldPrintOperatorNewline
-
-        if shouldPreserveOrForce:
-            self.print_newline(preserve_statement_flags = True)
-        elif self.opts.wrap_line_length > 0:
-            if self.last_type == 'TK_RESERVED' and self.flags.last_text in self._newline_restricted_tokens:
-                # These tokens should never have a newline inserted between
-                # them and the following expression.
-                return
-            proposed_line_length = self.output.current_line.get_character_count() + len(current_token.text)
-            if self.output.space_before_token:
-                proposed_line_length += 1
-
-            if proposed_line_length >= self.opts.wrap_line_length:
-                self.print_newline(preserve_statement_flags = True)
-
-
-    def print_newline(self, force_newline = False, preserve_statement_flags = False):
-        if not preserve_statement_flags:
-            if self.flags.last_text != ';' and self.flags.last_text != ',' and self.flags.last_text != '=' and self.last_type != 'TK_OPERATOR':
-                next_token = self.get_token(1)
-                while (self.flags.mode == MODE.Statement and
-                        not (self.flags.if_block and next_token and next_token.type == 'TK_RESERVED' and next_token.text == 'else') and
-                        not self.flags.do_block):
-                    self.restore_mode()
-
-        if self.output.add_new_line(force_newline):
-            self.flags.multiline_frame = True
-
-    def print_token_line_indentation(self, current_token):
-        if self.output.just_added_newline():
-            line = self.output.current_line
-            if self.opts.keep_array_indentation and self.is_array(self.flags.mode) and current_token.wanted_newline:
-                line.push(current_token.whitespace_before)
-                self.output.space_before_token = False
-            elif self.output.set_indent(self.flags.indentation_level):
-                self.flags.line_indent_level = self.flags.indentation_level
-
-
-    def print_token(self, current_token, s=None):
-        if self.output.raw:
-            self.output.add_raw_token(current_token)
-            return
-
-        if self.opts.comma_first and self.last_type == 'TK_COMMA' and self.output.just_added_newline():
-            if self.output.previous_line.last() == ',':
-                # if the comma was already at the start of the line,
-                # pull back onto that line and reprint the indentation
-                popped = self.output.previous_line.pop()
-                if  self.output.previous_line.is_empty():
-                     self.output.previous_line.push(popped)
-                     self.output.trim(True)
-                     self.output.current_line.pop()
-                     self.output.trim()
-
-                # add the comma in front of the next token
-                self.print_token_line_indentation(current_token)
-                self.output.add_token(',')
-                self.output.space_before_token = True
-
-        if s == None:
-            s = current_token.text
-
-        self.print_token_line_indentation(current_token)
-        self.output.add_token(s);
-
-
-    def indent(self):
-        self.flags.indentation_level += 1
-
-    def deindent(self):
-        allow_deindent = self.flags.indentation_level > 0 and ((self.flags.parent == None) or self.flags.indentation_level > self.flags.parent.indentation_level)
-
-        if allow_deindent:
-            self.flags.indentation_level -= 1
-
-    def set_mode(self, mode):
-        if self.flags:
-            self.flag_store.append(self.flags)
-            self.previous_flags = self.flags
-        else:
-            self.previous_flags = BeautifierFlags(mode)
-
-        self.flags = BeautifierFlags(mode)
-        self.flags.apply_base(self.previous_flags, self.output.just_added_newline())
-        self.flags.start_line_index = self.output.get_line_number();
-
-    def restore_mode(self):
-        if len(self.flag_store) > 0:
-            self.previous_flags = self.flags
-            self.flags = self.flag_store.pop()
-            if self.previous_flags.mode == MODE.Statement:
-                self.output.remove_redundant_indentation(self.previous_flags)
-
-
-    def start_of_object_property(self):
-        return self.flags.parent.mode == MODE.ObjectLiteral and self.flags.mode == MODE.Statement and \
-                ((self.flags.last_text == ':' and self.flags.ternary_depth == 0) or (self.last_type == 'TK_RESERVED' and self.flags.last_text in ['get', 'set']))
-
-    def start_of_statement(self, current_token):
-        if (
-            (self.last_type == 'TK_RESERVED' and self.flags.last_text in ['var', 'let', 'const'] and current_token.type == 'TK_WORD') \
-                or (self.last_type == 'TK_RESERVED' and self.flags.last_text== 'do') \
-                or (self.last_type == 'TK_RESERVED' and self.flags.last_text in ['return', 'throw'] and not current_token.wanted_newline) \
-                or (self.last_type == 'TK_RESERVED' and self.flags.last_text == 'else' \
-                    and not (current_token.type == 'TK_RESERVED' and current_token.text == 'if' and not len(current_token.comments_before))) \
-                or (self.last_type == 'TK_END_EXPR' and (self.previous_flags.mode == MODE.ForInitializer or self.previous_flags.mode == MODE.Conditional)) \
-                or (self.last_type == 'TK_WORD' and self.flags.mode == MODE.BlockStatement \
-                    and not self.flags.in_case
-                    and not (current_token.text == '--' or current_token.text == '++')
-                    and self.last_last_text != 'function'
-                    and current_token.type != 'TK_WORD' and current_token.type != 'TK_RESERVED') \
-                or (self.flags.mode == MODE.ObjectLiteral and \
-                    ((self.flags.last_text == ':' and self.flags.ternary_depth == 0) or (self.last_type == 'TK_RESERVED' and self.flags.last_text in ['get', 'set'])))
-                ):
-
-            self.set_mode(MODE.Statement)
-            self.indent()
-
-            self.handle_whitespace_and_comments(current_token, True);
-
-            # Issue #276:
-            # If starting a new statement with [if, for, while, do], push to a new line.
-            # if (a) if (b) if(c) d(); else e(); else f();
-            if not self.start_of_object_property():
-                self.allow_wrap_or_preserved_newline(current_token, current_token.type == 'TK_RESERVED' and current_token.text in ['do', 'for', 'if', 'while'])
-
-            return True
-        else:
-            return False
-
-    def get_token(self, offset = 0):
-        index = self.token_pos + offset
-        if index < 0 or index >= len(self.tokens):
-            return None
-        else:
-            return self.tokens[index]
-
-
-    def handle_start_expr(self, current_token):
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            pass
-        else:
-            self.handle_whitespace_and_comments(current_token)
-
-        next_mode = MODE.Expression
-
-        if current_token.text == '[':
-            if self.last_type == 'TK_WORD' or self.flags.last_text == ')':
-                if self.last_type == 'TK_RESERVED' and self.flags.last_text in Tokenizer.line_starters:
-                    self.output.space_before_token = True
-                self.set_mode(next_mode)
-                self.print_token(current_token)
-                self.indent()
-                if self.opts.space_in_paren:
-                    self.output.space_before_token = True
-                return
-
-            next_mode = MODE.ArrayLiteral
-
-            if self.is_array(self.flags.mode):
-                if self.flags.last_text == '[' or (
-                    self.flags.last_text == ',' and (self.last_last_text == ']' or self.last_last_text == '}')):
-                    # ], [ goes to a new line
-                    # }, [ goes to a new line
-                    if not self.opts.keep_array_indentation:
-                        self.print_newline()
-
-        else:
-            if self.last_type == 'TK_RESERVED' and self.flags.last_text == 'for':
-                next_mode = MODE.ForInitializer
-            elif self.last_type == 'TK_RESERVED' and self.flags.last_text in ['if', 'while']:
-                next_mode = MODE.Conditional
-            else:
-                next_mode = MODE.Expression
-
-
-        if self.flags.last_text == ';' or self.last_type == 'TK_START_BLOCK':
-            self.print_newline()
-        elif self.last_type in ['TK_END_EXPR', 'TK_START_EXPR', 'TK_END_BLOCK'] or self.flags.last_text == '.':
-            # do nothing on (( and )( and ][ and ]( and .(
-            # TODO: Consider whether forcing this is required.  Review failing tests when removed.
-            self.allow_wrap_or_preserved_newline(current_token, current_token.wanted_newline)
-
-        elif not (self.last_type == 'TK_RESERVED' and current_token.text == '(') and self.last_type not in ['TK_WORD', 'TK_OPERATOR']:
-            self.output.space_before_token = True
-        elif (self.last_type == 'TK_RESERVED' and (self.flags.last_word == 'function' or self.flags.last_word == 'typeof')) or \
-            (self.flags.last_text == '*' and (
-                self.last_last_text in ['function', 'yield'] or
-                (self.flags.mode == MODE.ObjectLiteral and self.last_last_text in ['{', ',']))):
-            # function() vs function (), typeof() vs typeof ()
-            # function*() vs function* (), yield*() vs yield* ()
-            if self.opts.space_after_anon_function:
-                self.output.space_before_token = True
-        elif self.last_type == 'TK_RESERVED' and (self.flags.last_text in Tokenizer.line_starters or self.flags.last_text == 'catch'):
-            # TODO: option space_before_conditional
-            self.output.space_before_token = True
-
-        elif current_token.text == '(' and self.last_type == 'TK_RESERVED' and self.flags.last_word == 'await':
-            self.output.space_before_token = True
-
-
-        # Support of this kind of newline preservation:
-        # a = (b &&
-        #     (c || d));
-        if self.last_type in ['TK_EQUALS', 'TK_OPERATOR']:
-            if not self.start_of_object_property():
-                self.allow_wrap_or_preserved_newline(current_token)
-
-
-        # Support preserving wrapped arrow function expressions
-        # a.b('c',
-        #     () => d.e
-        # )
-        if current_token.text == '(' and self.last_type not in ['TK_WORD', 'TK_RESERVED']:
-            self.allow_wrap_or_preserved_newline(current_token)
-
-
-        self.set_mode(next_mode)
-        self.print_token(current_token)
-
-        if self.opts.space_in_paren:
-            self.output.space_before_token = True
-
-        # In all cases, if we newline while inside an expression it should be indented.
-        self.indent()
-
-
-
-    def handle_end_expr(self, current_token):
-        # statements inside expressions are not valid syntax, but...
-        # statements must all be closed when their container closes
-        while self.flags.mode == MODE.Statement:
-            self.restore_mode()
-
-        self.handle_whitespace_and_comments(current_token)
-
-        if self.flags.multiline_frame:
-            self.allow_wrap_or_preserved_newline(current_token, current_token.text == ']' and self.is_array(self.flags.mode) and not self.opts.keep_array_indentation)
-
-        if self.opts.space_in_paren:
-            if self.last_type == 'TK_START_EXPR' and not self.opts.space_in_empty_paren:
-                # empty parens are always "()" and "[]", not "( )" or "[ ]"
-                self.output.space_before_token = False
-                self.output.trim()
-            else:
-                self.output.space_before_token = True
-
-        if current_token.text == ']' and self.opts.keep_array_indentation:
-            self.print_token(current_token)
-            self.restore_mode()
-        else:
-            self.restore_mode()
-            self.print_token(current_token)
-
-        self.output.remove_redundant_indentation(self.previous_flags)
-
-        # do {} while () // no statement required after
-        if self.flags.do_while and self.previous_flags.mode == MODE.Conditional:
-            self.previous_flags.mode = MODE.Expression
-            self.flags.do_block = False
-            self.flags.do_while = False
-
-    def handle_start_block(self, current_token):
-        self.handle_whitespace_and_comments(current_token)
-
-        # Check if this is a BlockStatement that should be treated as a ObjectLiteral
-        next_token = self.get_token(1)
-        second_token = self.get_token(2)
-        if second_token != None and \
-            ((second_token.text in [':', ','] and next_token.type in ['TK_STRING', 'TK_WORD', 'TK_RESERVED']) \
-                or (next_token.text in ['get', 'set', '...'] and second_token.type in ['TK_WORD', 'TK_RESERVED'])):
-            # We don't support TypeScript,but we didn't break it for a very long time.
-            # We'll try to keep not breaking it.
-            if not self.last_last_text in ['class','interface']:
-                self.set_mode(MODE.ObjectLiteral)
-            else:
-                self.set_mode(MODE.BlockStatement)
-        elif self.last_type == 'TK_OPERATOR' and self.flags.last_text == '=>':
-            # arrow function: (param1, paramN) => { statements }
-            self.set_mode(MODE.BlockStatement)
-        elif self.last_type in ['TK_EQUALS', 'TK_START_EXPR', 'TK_COMMA', 'TK_OPERATOR'] or \
-            (self.last_type == 'TK_RESERVED' and self.flags.last_text in ['return', 'throw', 'import', 'default']):
-            # Detecting shorthand function syntax is difficult by scanning forward,
-            #     so check the surrounding context.
-            # If the block is being returned, imported, export default, passed as arg,
-            #     assigned with = or assigned in a nested object, treat as an ObjectLiteral.
-            self.set_mode(MODE.ObjectLiteral)
-        else:
-            self.set_mode(MODE.BlockStatement)
-
-        empty_braces = (not next_token == None) and len(next_token.comments_before) == 0 and next_token.text == '}'
-        empty_anonymous_function = empty_braces and self.flags.last_word == 'function' and \
-            self.last_type == 'TK_END_EXPR'
-
-        if self.opts.brace_preserve_inline: # check for inline, set inline_frame if so
-            # search forward for newline wanted inside this block
-            index = 0
-            check_token = None
-            self.flags.inline_frame = True
-            do_loop = True
-            while (do_loop):
-                index += 1
-                check_token = self.get_token(index)
-                if check_token.wanted_newline:
-                    self.flags.inline_frame = False
-
-                do_loop = (check_token.type != 'TK_EOF' and
-                      not (check_token.type == 'TK_END_BLOCK' and check_token.opened == current_token))
-
-        if (self.opts.brace_style == 'expand' or \
-            (self.opts.brace_style == 'none' and current_token.wanted_newline)) and \
-            not self.flags.inline_frame:
-            if self.last_type != 'TK_OPERATOR' and \
-                (empty_anonymous_function or
-                    self.last_type == 'TK_EQUALS' or
-                    (self.last_type == 'TK_RESERVED' and self.is_special_word(self.flags.last_text) and self.flags.last_text != 'else')):
-                self.output.space_before_token = True
-            else:
-                self.print_newline(preserve_statement_flags = True)
-        else: # collapse || inline_frame
-            if self.is_array(self.previous_flags.mode) and (self.last_type == 'TK_START_EXPR' or self.last_type == 'TK_COMMA'):
-                # if we're preserving inline,
-                # allow newline between comma and next brace.
-                if self.flags.inline_frame:
-                    self.allow_wrap_or_preserved_newline(current_token)
-                    self.flags.inline_frame = True
-                    self.previous_flags.multiline_frame = self.previous_flags.multiline_frame or self.flags.multiline_frame
-                    self.flags.multiline_frame = False
-                elif self.last_type == 'TK_COMMA':
-                    self.output.space_before_token = True
-
-            elif self.last_type not in ['TK_OPERATOR', 'TK_START_EXPR']:
-                if self.last_type == 'TK_START_BLOCK' and not self.flags.inline_frame:
-                    self.print_newline()
-                else:
-                    self.output.space_before_token = True
-
-        self.print_token(current_token)
-        self.indent()
-
-
-    def handle_end_block(self, current_token):
-        # statements must all be closed when their container closes
-        self.handle_whitespace_and_comments(current_token)
-
-        while self.flags.mode == MODE.Statement:
-            self.restore_mode()
-
-        empty_braces = self.last_type == 'TK_START_BLOCK'
-
-        if self.flags.inline_frame and not empty_braces: # try inline_frame (only set if opt.braces-preserve-inline) first
-            self.output.space_before_token = True;
-        elif self.opts.brace_style == 'expand':
-            if not empty_braces:
-                self.print_newline()
-        else:
-            # skip {}
-            if not empty_braces:
-                if self.is_array(self.flags.mode) and self.opts.keep_array_indentation:
-                    self.opts.keep_array_indentation = False
-                    self.print_newline()
-                    self.opts.keep_array_indentation = True
-                else:
-                    self.print_newline()
-
-        self.restore_mode()
-        self.print_token(current_token)
-
-
-    def handle_word(self, current_token):
-        if current_token.type == 'TK_RESERVED':
-            if current_token.text in ['set', 'get'] and self.flags.mode != MODE.ObjectLiteral:
-                current_token.type = 'TK_WORD'
-            elif current_token.text in ['as', 'from'] and not self.flags.import_block:
-                current_token.type = 'TK_WORD'
-            elif self.flags.mode == MODE.ObjectLiteral:
-                next_token = self.get_token(1)
-                if next_token.text == ':':
-                    current_token.type = 'TK_WORD'
-
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            if self.last_type == 'TK_RESERVED' and self.flags.last_text in ['var', 'let', 'const'] and current_token.type == 'TK_WORD':
-                self.flags.declaration_statement = True
-
-        elif current_token.wanted_newline and \
-                not self.is_expression(self.flags.mode) and \
-                (self.last_type != 'TK_OPERATOR' or (self.flags.last_text == '--' or self.flags.last_text == '++')) and \
-                self.last_type != 'TK_EQUALS' and \
-                (self.opts.preserve_newlines or not (self.last_type == 'TK_RESERVED' and self.flags.last_text in ['var', 'let', 'const', 'set', 'get'])):
-            self.handle_whitespace_and_comments(current_token)
-            self.print_newline()
-        else:
-            self.handle_whitespace_and_comments(current_token)
-
-
-        if self.flags.do_block and not self.flags.do_while:
-            if current_token.type == 'TK_RESERVED' and current_token.text == 'while':
-                # do {} ## while ()
-                self.output.space_before_token = True
-                self.print_token(current_token)
-                self.output.space_before_token = True
-                self.flags.do_while = True
-                return
-            else:
-                # do {} should always have while as the next word.
-                # if we don't see the expected while, recover
-                self.print_newline()
-                self.flags.do_block = False
-
-        # if may be followed by else, or not
-        # Bare/inline ifs are tricky
-        # Need to unwind the modes correctly: if (a) if (b) c(); else d(); else e();
-        if self.flags.if_block:
-            if (not self.flags.else_block) and (current_token.type == 'TK_RESERVED' and current_token.text == 'else'):
-                self.flags.else_block = True
-            else:
-                while self.flags.mode == MODE.Statement:
-                    self.restore_mode()
-
-                self.flags.if_block = False
-
-        if current_token.type == 'TK_RESERVED' and (current_token.text == 'case' or (current_token.text == 'default' and self.flags.in_case_statement)):
-            self.print_newline()
-            if self.flags.case_body or self.opts.jslint_happy:
-                self.flags.case_body = False
-                self.deindent()
-            self.print_token(current_token)
-            self.flags.in_case = True
-            self.flags.in_case_statement = True
-            return
-
-        if self.last_type in ['TK_COMMA', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']:
-            if not self.start_of_object_property():
-                self.allow_wrap_or_preserved_newline(current_token)
-
-        if current_token.type == 'TK_RESERVED' and current_token.text == 'function':
-            if (self.flags.last_text in ['}', ';'] or
-                (self.output.just_added_newline() and not (self.flags.last_text in ['(', '[', '{', ':', '=', ','] or self.last_type == 'TK_OPERATOR'))):
-                # make sure there is a nice clean space of at least one blank line
-                # before a new function definition, except in arrays
-                if not self.output.just_added_blankline() and len(current_token.comments_before) == 0:
-                    self.print_newline()
-                    self.print_newline(True)
-
-            if self.last_type == 'TK_RESERVED' or self.last_type == 'TK_WORD':
-                if self.last_type == 'TK_RESERVED' and self.flags.last_text in ['get', 'set', 'new', 'return', 'export', 'async']:
-                    self.output.space_before_token = True
-                elif self.last_type == 'TK_RESERVED' and self.flags.last_text == 'default' and self.last_last_text == 'export':
-                    self.output.space_before_token = True
-                else:
-                    self.print_newline()
-            elif self.last_type == 'TK_OPERATOR' or self.flags.last_text == '=':
-                # foo = function
-                self.output.space_before_token = True
-            elif not self.flags.multiline_frame and (self.is_expression(self.flags.mode) or self.is_array(self.flags.mode)):
-                # (function
-                pass
-            else:
-                self.print_newline()
-
-            self.print_token(current_token)
-            self.flags.last_word = current_token.text
-            return
-
-        prefix = 'NONE'
-
-        if self.last_type == 'TK_END_BLOCK':
-            if self.previous_flags.inline_frame:
-                prefix = 'SPACE'
-            elif not (current_token.type == 'TK_RESERVED' and current_token.text in ['else', 'catch', 'finally', 'from']):
-                prefix = 'NEWLINE'
-            else:
-                if self.opts.brace_style in ['expand', 'end-expand'] or \
-                    (self.opts.brace_style == 'none' and current_token.wanted_newline):
-                    prefix = 'NEWLINE'
-                else:
-                    prefix = 'SPACE'
-                    self.output.space_before_token = True
-        elif self.last_type == 'TK_SEMICOLON' and self.flags.mode == MODE.BlockStatement:
-            # TODO: Should this be for STATEMENT as well?
-            prefix = 'NEWLINE'
-        elif self.last_type == 'TK_SEMICOLON' and self.is_expression(self.flags.mode):
-            prefix = 'SPACE'
-        elif self.last_type == 'TK_STRING':
-            prefix = 'NEWLINE'
-        elif self.last_type == 'TK_RESERVED' or self.last_type == 'TK_WORD' or \
-            (self.flags.last_text == '*' and (
-                self.last_last_text in ['function', 'yield'] or
-                (self.flags.mode == MODE.ObjectLiteral and self.last_last_text in ['{', ',']))):
-            prefix = 'SPACE'
-        elif self.last_type == 'TK_START_BLOCK':
-            if self.flags.inline_frame:
-                prefix = 'SPACE'
-            else:
-                prefix = 'NEWLINE'
-        elif self.last_type == 'TK_END_EXPR':
-            self.output.space_before_token = True
-            prefix = 'NEWLINE'
-
-        if current_token.type == 'TK_RESERVED' and current_token.text in Tokenizer.line_starters and self.flags.last_text != ')':
-            if self.flags.inline_frame or self.flags.last_text == 'else ' or self.flags.last_text == 'export':
-                prefix = 'SPACE'
-            else:
-                prefix = 'NEWLINE'
-
-        if current_token.type == 'TK_RESERVED' and current_token.text in ['else', 'catch', 'finally']:
-            if ((not (self.last_type == 'TK_END_BLOCK' and self.previous_flags.mode == MODE.BlockStatement)) \
-               or self.opts.brace_style == 'expand' \
-               or self.opts.brace_style == 'end-expand' \
-               or (self.opts.brace_style == 'none' and current_token.wanted_newline)) \
-               and not self.flags.inline_frame:
-                self.print_newline()
-            else:
-                self.output.trim(True)
-                # If we trimmed and there's something other than a close block before us
-                # put a newline back in.  Handles '} // comment' scenario.
-                if self.output.current_line.last() != '}':
-                    self.print_newline()
-
-                self.output.space_before_token = True
-
-        elif prefix == 'NEWLINE':
-            if self.last_type == 'TK_RESERVED' and self.is_special_word(self.flags.last_text):
-                # no newline between return nnn
-                self.output.space_before_token = True
-            elif self.last_type != 'TK_END_EXPR':
-                if (self.last_type != 'TK_START_EXPR' or not (current_token.type == 'TK_RESERVED' and current_token.text in ['var', 'let', 'const'])) and self.flags.last_text != ':':
-                    # no need to force newline on VAR -
-                    # for (var x = 0...
-                    if current_token.type == 'TK_RESERVED' and current_token.text == 'if' and self.flags.last_text == 'else':
-                        self.output.space_before_token = True
-                    else:
-                        self.print_newline()
-            elif current_token.type == 'TK_RESERVED' and current_token.text in Tokenizer.line_starters and self.flags.last_text != ')':
-                self.print_newline()
-        elif self.flags.multiline_frame and self.is_array(self.flags.mode) and self.flags.last_text == ',' and self.last_last_text == '}':
-            self.print_newline() # }, in lists get a newline
-        elif prefix == 'SPACE':
-            self.output.space_before_token = True
-
-
-        self.print_token(current_token)
-        self.flags.last_word = current_token.text
-
-        if current_token.type == 'TK_RESERVED':
-            if current_token.text == 'do':
-                self.flags.do_block = True
-            elif current_token.text == 'if':
-                self.flags.if_block = True
-            elif current_token.text == 'import':
-                self.flags.import_block = True
-            elif current_token.text == 'from' and self.flags.import_block:
-                self.flags.import_block = False
-
-
-    def handle_semicolon(self, current_token):
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            # Semicolon can be the start (and end) of a statement
-            self.output.space_before_token = False
-        else:
-            self.handle_whitespace_and_comments(current_token)
-
-        next_token = self.get_token(1)
-        while (self.flags.mode == MODE.Statement and
-                not (self.flags.if_block and next_token and next_token.type == 'TK_RESERVED' and next_token.text == 'else') and
-                not self.flags.do_block):
-            self.restore_mode()
-
-        if self.flags.import_block:
-            self.flags.import_block = False
-
-        self.print_token(current_token)
-
-
-    def handle_string(self, current_token):
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            # One difference - strings want at least a space before
-            self.output.space_before_token = True
-        else:
-            self.handle_whitespace_and_comments(current_token)
-
-            if self.last_type == 'TK_RESERVED' or self.last_type == 'TK_WORD' or self.flags.inline_frame:
-                self.output.space_before_token = True
-            elif self.last_type in ['TK_COMMA', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']:
-                if not self.start_of_object_property():
-                    self.allow_wrap_or_preserved_newline(current_token)
-            else:
-                self.print_newline()
-
-        self.print_token(current_token)
-
-
-    def handle_equals(self, current_token):
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            pass
-        else:
-            self.handle_whitespace_and_comments(current_token)
-
-
-        if self.flags.declaration_statement:
-            # just got an '=' in a var-line, different line breaking rules will apply
-            self.flags.declaration_assignment = True
-
-        self.output.space_before_token = True
-        self.print_token(current_token)
-        self.output.space_before_token = True
-
-
-    def handle_comma(self, current_token):
-        self.handle_whitespace_and_comments(current_token, True)
-
-        self.print_token(current_token)
-        self.output.space_before_token = True
-
-        if self.flags.declaration_statement:
-            if self.is_expression(self.flags.parent.mode):
-                # do not break on comma, for ( var a = 1, b = 2
-                self.flags.declaration_assignment = False
-
-            if self.flags.declaration_assignment:
-                self.flags.declaration_assignment = False
-                self.print_newline(preserve_statement_flags = True)
-            elif self.opts.comma_first:
-                # for comma-first, we want to allow a newline before the comma
-                # to turn into a newline after the comma, which we will fixup later
-                self.allow_wrap_or_preserved_newline(current_token)
-
-        elif self.flags.mode == MODE.ObjectLiteral \
-            or (self.flags.mode == MODE.Statement and self.flags.parent.mode ==  MODE.ObjectLiteral):
-            if self.flags.mode == MODE.Statement:
-                self.restore_mode()
-
-            if not self.flags.inline_frame:
-                self.print_newline()
-        elif self.opts.comma_first:
-            # EXPR or DO_BLOCK
-            # for comma-first, we want to allow a newline before the comma
-            # to turn into a newline after the comma, which we will fixup later
-            self.allow_wrap_or_preserved_newline(current_token)
-
-
-    def handle_operator(self, current_token):
-        isGeneratorAsterisk = current_token.text == '*' and \
-            ((self.last_type == 'TK_RESERVED' and self.flags.last_text in ['function', 'yield']) or
-                (self.last_type in ['TK_START_BLOCK', 'TK_COMMA', 'TK_END_BLOCK', 'TK_SEMICOLON']))
-        isUnary = current_token.text in ['+', '-'] \
-            and (self.last_type in ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR'] \
-            or self.flags.last_text in Tokenizer.line_starters or self.flags.last_text == ',')
-
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            pass
-        else:
-            preserve_statement_flags = not isGeneratorAsterisk
-            self.handle_whitespace_and_comments(current_token, preserve_statement_flags)
-
-        if self.last_type == 'TK_RESERVED' and self.is_special_word(self.flags.last_text):
-            # return had a special handling in TK_WORD
-            self.output.space_before_token = True
-            self.print_token(current_token)
-            return
-
-        # hack for actionscript's import .*;
-        if current_token.text == '*' and self.last_type == 'TK_DOT':
-            self.print_token(current_token)
-            return
-
-        if current_token.text == '::':
-            # no spaces around the exotic namespacing syntax operator
-            self.print_token(current_token)
-            return
-
-        # Allow line wrapping between operators when operator_position is
-        #   set to before or preserve
-        if self.last_type == 'TK_OPERATOR' and self.opts.operator_position in OPERATOR_POSITION_BEFORE_OR_PRESERVE:
-            self.allow_wrap_or_preserved_newline(current_token)
-
-        if current_token.text == ':' and self.flags.in_case:
-            self.flags.case_body = True
-            self.indent()
-            self.print_token(current_token)
-            self.print_newline()
-            self.flags.in_case = False
-            return
-
-        space_before = True
-        space_after = True
-        in_ternary = False
-
-        if current_token.text == ':':
-            if self.flags.ternary_depth == 0:
-                # Colon is invalid javascript outside of ternary and object, but do our best to guess what was meant.
-                space_before = False
-            else:
-                self.flags.ternary_depth -= 1
-                in_ternary = True
-        elif current_token.text == '?':
-            self.flags.ternary_depth += 1
-
-        # let's handle the operator_position option prior to any conflicting logic
-        if (not isUnary) and (not isGeneratorAsterisk) and \
-            self.opts.preserve_newlines and current_token.text in Tokenizer.positionable_operators:
-
-            isColon = current_token.text == ':'
-            isTernaryColon = isColon and in_ternary
-            isOtherColon = isColon and not in_ternary
-
-            if self.opts.operator_position == OPERATOR_POSITION['before_newline']:
-                # if the current token is : and it's not a ternary statement then we set space_before to false
-                self.output.space_before_token = not isOtherColon
-
-                self.print_token(current_token)
-
-                if (not isColon) or isTernaryColon:
-                    self.allow_wrap_or_preserved_newline(current_token)
-
-                self.output.space_before_token = True
-
-                return
-
-            elif self.opts.operator_position == OPERATOR_POSITION['after_newline']:
-                # if the current token is anything but colon, or (via deduction) it's a colon and in a ternary statement,
-                #   then print a newline.
-                self.output.space_before_token = True
-
-                if (not isColon) or isTernaryColon:
-                    if self.get_token(1).wanted_newline:
-                        self.print_newline(preserve_statement_flags = True)
-                    else:
-                        self.allow_wrap_or_preserved_newline(current_token)
-                else:
-                    self.output.space_before_token = False
-
-                self.print_token(current_token)
-
-                self.output.space_before_token = True
-                return
-
-            elif self.opts.operator_position == OPERATOR_POSITION['preserve_newline']:
-                if not isOtherColon:
-                    self.allow_wrap_or_preserved_newline(current_token)
-
-                # if we just added a newline, or the current token is : and it's not a ternary statement,
-                #   then we set space_before to false
-                self.output.space_before_token = not (self.output.just_added_newline() or isOtherColon)
-
-                self.print_token(current_token)
-
-                self.output.space_before_token = True
-                return
-
-        if isGeneratorAsterisk:
-            self.allow_wrap_or_preserved_newline(current_token)
-            space_before = False
-            next_token = self.get_token(1)
-            space_after = next_token and next_token.type in ['TK_WORD','TK_RESERVED']
-        elif current_token.text == '...':
-            self.allow_wrap_or_preserved_newline(current_token)
-            space_before = self.last_type == 'TK_START_BLOCK'
-            space_after = False
-        elif current_token.text in ['--', '++', '!', '~'] or isUnary:
-            space_before = False
-            space_after = False
-
-            # http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
-            # if there is a newline between -- or ++ and anything else we should preserve it.
-            if current_token.wanted_newline and (current_token.text == '--' or current_token.text == '++'):
-                self.print_newline(preserve_statement_flags = True)
-
-            if self.flags.last_text == ';' and self.is_expression(self.flags.mode):
-                # for (;; ++i)
-                #         ^^
-                space_before = True
-
-            if self.last_type == 'TK_RESERVED':
-                space_before = True
-            elif self.last_type == 'TK_END_EXPR':
-                space_before = not (self.flags.last_text == ']' and current_token.text in ['--', '++'])
-            elif self.last_type == 'TK_OPERATOR':
-                # a++ + ++b
-                # a - -b
-                space_before = current_token.text in ['--', '-','++', '+'] and self.flags.last_text in ['--', '-','++', '+']
-                # + and - are not unary when preceeded by -- or ++ operator
-                # a-- + b
-                # a * +b
-                # a - -b
-                if current_token.text in ['-', '+'] and self.flags.last_text in ['--', '++']:
-                    space_after = True
-
-            if (((self.flags.mode == MODE.BlockStatement and not self.flags.inline_frame) or self.flags.mode == MODE.Statement)
-                    and self.flags.last_text in ['{', ';']):
-                # { foo: --i }
-                # foo(): --bar
-                self.print_newline()
-
-        if space_before:
-            self.output.space_before_token = True
-
-        self.print_token(current_token)
-
-        if space_after:
-            self.output.space_before_token = True
-
-
-
-    def handle_block_comment(self, current_token, preserve_statement_flags):
-        if self.output.raw:
-            self.output.add_raw_token(current_token)
-            if current_token.directives and current_token.directives.get('preserve') == 'end':
-                # If we're testing the raw output behavior, do not allow a directive to turn it off.
-                self.output.raw = self.opts.test_output_raw
-            return
-
-        if current_token.directives:
-            self.print_newline(preserve_statement_flags = preserve_statement_flags)
-            self.print_token(current_token)
-            if current_token.directives.get('preserve') == 'start':
-                self.output.raw = True
-
-            self.print_newline(preserve_statement_flags = True)
-            return
-
-        # inline block
-        if not self.acorn.newline.search(current_token.text) and not current_token.wanted_newline:
-            self.output.space_before_token = True
-            self.print_token(current_token)
-            self.output.space_before_token = True
-            return
-
-        lines = self.acorn.allLineBreaks.split(current_token.text)
-        javadoc = False
-        starless = False
-        last_indent = current_token.whitespace_before
-        last_indent_length = len(last_indent)
-
-        # block comment starts with a new line
-        self.print_newline(preserve_statement_flags = preserve_statement_flags)
-        if  len(lines) > 1:
-            javadoc = not any(l for l in lines[1:] if ( l.strip() == '' or (l.lstrip())[0] != '*'))
-            starless = all(l.startswith(last_indent) or l.strip() == '' for l in lines[1:])
-
-        # first line always indented
-        self.print_token(current_token, lines[0])
-        for line in lines[1:]:
-            self.print_newline(preserve_statement_flags = True)
-            if javadoc:
-                # javadoc: reformat and re-indent
-                self.print_token(current_token, ' ' + line.lstrip())
-            elif starless and len(line) > last_indent_length:
-                # starless: re-indent non-empty content, avoiding trim
-                self.print_token(current_token, line[last_indent_length:])
-            else:
-                # normal comments output raw
-                self.output.add_token(line)
-
-        self.print_newline(preserve_statement_flags = preserve_statement_flags)
-
-    def handle_comment(self, current_token, preserve_statement_flags):
-        if current_token.wanted_newline:
-            self.print_newline(preserve_statement_flags = preserve_statement_flags)
-
-        if not current_token.wanted_newline:
-            self.output.trim(True)
-
-        self.output.space_before_token = True
-        self.print_token(current_token)
-        self.print_newline(preserve_statement_flags = preserve_statement_flags)
-
-
-    def handle_dot(self, current_token):
-        if self.start_of_statement(current_token):
-            # The conditional starts the statement if appropriate.
-            pass
-        else:
-            self.handle_whitespace_and_comments(current_token, True)
-
-        if self.last_type == 'TK_RESERVED' and self.is_special_word(self.flags.last_text):
-            self.output.space_before_token = True
-        else:
-            # allow preserved newlines before dots in general
-            # force newlines on dots after close paren when break_chained - for bar().baz()
-            self.allow_wrap_or_preserved_newline(current_token,
-                self.flags.last_text == ')' and self.opts.break_chained_methods)
-
-        self.print_token(current_token)
-
-    def handle_unknown(self, current_token, preserve_statement_flags):
-        self.print_token(current_token)
-        if current_token.text[-1] == '\n':
-            self.print_newline(preserve_statement_flags = preserve_statement_flags)
-
-    def handle_eof(self, current_token):
-        # Unwind any open statements
-        while self.flags.mode == MODE.Statement:
-            self.restore_mode()
-
-        self.handle_whitespace_and_comments(current_token)
-
-
-
-def mkdir_p(path):
-    try:
-        if path:
-            os.makedirs(path)
-    except OSError as exc: # Python >2.5
-        if exc.errno == errno.EEXIST and os.path.isdir(path):
-            pass
-        else:
-            raise Exception()
-
-# Using object instead of string to allow for later expansion of info about each line
-class OutputLine:
-    def __init__(self, parent):
-        self.__parent = parent
-        self.__character_count = 0
-        self.__indent_count = -1
-
-        self.__items = []
-        self.__empty = True
-
-    def get_character_count(self):
-        return self.__character_count
-
-    def is_empty(self):
-        return self.__empty
-
-    def set_indent(self, level):
-        self.__character_count = self.__parent.baseIndentLength + level * self.__parent.indent_length
-        self.__indent_count = level;
-
-    def last(self):
-        if not self.is_empty():
-            return self.__items[-1]
-        else:
-            return None
-
-    def push(self, input):
-        self.__items.append(input)
-        self.__character_count += len(input)
-        self.__empty = False
-
-
-    def pop(self):
-        item = None
-        if not self.is_empty():
-            item = self.__items.pop()
-            self.__character_count -= len(item)
-            self.__empty = len(self.__items) == 0
-        return item
-
-    def remove_indent(self):
-        if self.__indent_count > 0:
-            self.__indent_count -= 1
-            self.__character_count -= self.__parent.indent_length
-
-    def trim(self):
-        while self.last() == ' ':
-            item = self._items.pop()
-            self.__character_count -= 1
-        self.__empty = len(self.__items) == 0
-
-    def toString(self):
-        result = ''
-        if not self.is_empty():
-            if self.__indent_count >= 0:
-                result = self.__parent.indent_cache[self.__indent_count]
-            result += ''.join(self.__items)
-        return result
-
-
-class Output:
-    def __init__(self, indent_string, baseIndentString = ''):
-
-        self.indent_string = indent_string
-        self.baseIndentString = baseIndentString
-        self.indent_cache = [ baseIndentString ]
-        self.baseIndentLength = len(baseIndentString)
-        self.indent_length = len(indent_string)
-        self.raw = False
-        self.lines = []
-        self.previous_line = None
-        self.current_line = None
-        self.space_before_token = False
-        self.add_outputline()
-
-    def add_outputline(self):
-        self.previous_line = self.current_line
-        self.current_line = OutputLine(self)
-        self.lines.append(self.current_line)
-
-    def get_line_number(self):
-        return len(self.lines)
-
-    def add_new_line(self, force_newline):
-        if len(self.lines) == 1 and self.just_added_newline():
-            # no newline on start of file
-            return False
-
-        if force_newline or not self.just_added_newline():
-            if not self.raw:
-                self.add_outputline()
-            return True
-        return False
-
-    def get_code(self):
-        sweet_code = "\n".join(line.toString() for line in self.lines)
-        return re.sub('[\r\n\t ]+$', '', sweet_code)
-
-    def set_indent(self, level):
-        # Never indent your first output indent at the start of the file
-        if len(self.lines) > 1:
-            while level >= len(self.indent_cache):
-                self.indent_cache.append(self.indent_cache[-1] + self.indent_string)
-
-
-            self.current_line.set_indent(level)
-            return True
-        self.current_line.set_indent(0)
-        return False
-
-    def add_raw_token(self, token):
-        for _ in range(token.newlines):
-            self.add_outputline()
-
-        self.current_line.push(token.whitespace_before)
-        self.current_line.push(token.text)
-        self.space_before_token = False
-
-    def add_token(self, printable_token):
-        self.add_space_before_token()
-        self.current_line.push(printable_token)
-
-    def add_space_before_token(self):
-        if self.space_before_token and not self.just_added_newline():
-            self.current_line.push(' ')
-        self.space_before_token = False
-
-    def remove_redundant_indentation(self, frame):
-        # This implementation is effective but has some issues:
-        #     - can cause line wrap to happen too soon due to indent removal
-        #           after wrap points are calculated
-        # These issues are minor compared to ugly indentation.
-
-        if frame.multiline_frame or frame.mode == MODE.ForInitializer or frame.mode == MODE.Conditional:
-            return
-
-        # remove one indent from each line inside this section
-        index = frame.start_line_index
-        while index < len(self.lines):
-            self.lines[index].remove_indent()
-            index += 1
-
-    def trim(self, eat_newlines = False):
-        self.current_line.trim()
-
-        while eat_newlines and len(self.lines) > 1 and self.current_line.is_empty():
-            self.lines.pop()
-            self.current_line = self.lines[-1]
-            self.current_line.trim()
-
-        if len(self.lines) > 1:
-            self.previous_line = self.lines[-2]
-        else:
-            self.previous_line = None
-
-    def just_added_newline(self):
-        return self.current_line.is_empty()
-
-    def just_added_blankline(self):
-        if self.just_added_newline():
-            if len(self.lines) == 1:
-                return True
-
-            line = self.lines[-2]
-            return line.is_empty()
-
-        return False
-
-class InputScanner:
-    def __init__(self, input):
-        self.__input = input
-        self.__input_length = len(self.__input)
-        self.__position = 0
-
-    def back(self):
-        self.__position -= 1
-
-    def hasNext(self):
-        return self.__position < self.__input_length
-
-    def next(self):
-        val = None
-        if self.hasNext():
-            val = self.__input[self.__position]
-            self.__position += 1
-
-        return val;
-
-    def peek(self, index = 0):
-        val = None
-        index += self.__position;
-        if index >= 0 and index < self.__input_length:
-            val = self.__input[index];
-
-        return val;
-
-    def peekCharCode(self, index = 0):
-        val = 0
-        index += self.__position;
-        if index >= 0 and index < self.__input_length:
-            val = ord(self.__input[index])
-
-        return val
-
-    def test(self, pattern, index = 0):
-        index += self.__position;
-        return index >= 0 and index < self.__input_length and pattern.match(self.__input, index)
-
-    def testChar(self, pattern, index = 0):
-        val = self.peek(index)
-        return val != None and pattern.match(val)
-
-    def match(self, pattern):
-        pattern_match = None
-        if self.hasNext():
-            pattern_match = pattern.match(self.__input, self.__position)
-            if pattern_match:
-                self.__position += len(pattern_match.group(0));
-
-        return pattern_match
-
-
-class Tokenizer:
-
-    whitespace = ["\n", "\r", "\t", " "]
-    digit = re.compile('[0-9]')
-    digit_bin = re.compile('[01]')
-    digit_oct = re.compile('[01234567]')
-    digit_hex = re.compile('[0123456789abcdefABCDEF]')
-
-    positionable_operators = '!= !== % & && * ** + - / : < << <= == === > >= >> >>> ? ^ | ||'.split(' ')
-    punct = (positionable_operators +
-        # non-positionable operators - these do not follow operator position settings
-        '! %= &= *= **= ++ += , -- -= /= :: <<= = => >>= >>>= ^= |= ~ ...'.split(' '))
-
-    # Words which always should start on a new line
-    line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',')
-    reserved_words = line_starters + ['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']
-
-    def __init__ (self, input_string, opts, indent_string):
-        self.input = InputScanner(input_string)
-        self.opts = opts
-        self.indent_string = indent_string
-        self.acorn = Acorn()
-        #  /* ... */ comment ends with nearest */ or end of file
-        self.block_comment_pattern = re.compile('([\s\S]*?)((?:\*\/)|$)')
-
-        # comment ends just before nearest linefeed or end of file
-        self.comment_pattern = re.compile(self.acorn.six.u('([^\n\r\u2028\u2029]*)'))
-
-        self.directives_block_pattern = re.compile('\/\* beautify( \w+[:]\w+)+ \*\/')
-        self.directive_pattern = re.compile(' (\w+)[:](\w+)')
-        self.directives_end_ignore_pattern = re.compile('([\s\S]*?)((?:\/\*\sbeautify\signore:end\s\*\/)|$)')
-
-        self.template_pattern = re.compile('((<\?php|<\?=)[\s\S]*?\?>)|(<%[\s\S]*?%>)')
-
-    def tokenize(self):
-        self.in_html_comment = False
-        self.tokens = []
-
-        next = None
-        last = None
-        open = None
-        open_stack = []
-        comments = []
-
-        while not (not last == None and last.type == 'TK_EOF'):
-            token_values = self.__tokenize_next()
-            next = Token(token_values[1], token_values[0], self.n_newlines, self.whitespace_before_token)
-
-            while next.type == 'TK_COMMENT' or next.type == 'TK_BLOCK_COMMENT' or next.type == 'TK_UNKNOWN':
-                if next.type == 'TK_BLOCK_COMMENT':
-                    next.directives = token_values[2]
-
-                comments.append(next)
-                token_values = self.__tokenize_next()
-                next = Token(token_values[1], token_values[0], self.n_newlines, self.whitespace_before_token)
-
-            if len(comments) > 0:
-                next.comments_before = comments
-                comments = []
-
-            if next.type == 'TK_START_BLOCK' or next.type == 'TK_START_EXPR':
-                next.parent = last
-                open_stack.append(open)
-                open = next
-            elif (next.type == 'TK_END_BLOCK' or next.type == 'TK_END_EXPR') and \
-                (not open == None and ( \
-                    (next.text == ']' and open.text == '[') or \
-                    (next.text == ')' and open.text == '(') or \
-                    (next.text == '}' and open.text == '{'))):
-                next.parent = open.parent
-                next.opened = open
-                open = open_stack.pop()
-
-            self.tokens.append(next)
-            last = next
-        return self.tokens
-
-    def get_directives (self, text):
-        if not self.directives_block_pattern.match(text):
-            return None
-
-        directives = {}
-        directive_match = self.directive_pattern.search(text)
-        while directive_match:
-            directives[directive_match.group(1)] = directive_match.group(2)
-            directive_match = self.directive_pattern.search(text, directive_match.end())
-
-        return directives
-
-
-    def __tokenize_next(self):
-
-        whitespace_on_this_line = []
-        self.n_newlines = 0
-        self.whitespace_before_token = ''
-
-        c = self.input.next()
-
-        if c == None:
-            return '', 'TK_EOF'
-
-        if len(self.tokens) > 0:
-            last_token = self.tokens[-1]
-        else:
-            # For the sake of tokenizing we can pretend that there was on open brace to start
-            last_token = Token('TK_START_BLOCK', '{')
-
-        while c in self.whitespace:
-            if self.acorn.newline.match(c):
-                # treat \r\n as one newline
-                if not (c == '\n' and self.input.peek(-2) == '\r'):
-                    self.n_newlines += 1
-                    whitespace_on_this_line = []
-            else:
-                whitespace_on_this_line.append(c)
-
-            c = self.input.next()
-
-            if c == None:
-                return '', 'TK_EOF'
-
-        if len(whitespace_on_this_line) != 0:
-            self.whitespace_before_token = ''.join(whitespace_on_this_line)
-
-        if self.digit.match(c) or (c == '.' and self.input.testChar(self.digit)):
-            allow_decimal = True
-            allow_e = True
-            local_digit = self.digit
-
-            if c == '0' and self.input.testChar(re.compile('[XxOoBb]')):
-                # switch to hex/oct/bin number, no decimal or e, just hex/oct/bin digits
-                allow_decimal = False
-                allow_e = False
-                if self.input.testChar(re.compile('[Bb]')):
-                    local_digit = self.digit_bin
-                elif self.input.testChar(re.compile('[Oo]')):
-                    local_digit = self.digit_oct
-                else:
-                    local_digit = self.digit_hex
-                c += self.input.next()
-            elif c == '.':
-                # Already have a decimal for this literal, don't allow another
-                allow_decimal = False
-            else:
-                # we know this first loop will run.  It keeps the logic simpler.
-                c = ''
-                self.input.back()
-
-            # Add the digits
-            while self.input.testChar(local_digit):
-                c += self.input.next()
-
-                if allow_decimal and self.input.peek() == '.':
-                    c += self.input.next()
-                    allow_decimal = False
-
-                # a = 1.e-7 is valid, so we test for . then e in one loop
-                if allow_e and self.input.testChar(re.compile('[Ee]')):
-                    c += self.input.next()
-
-                    if self.input.testChar(re.compile('[+-]')):
-                        c += self.input.next()
-
-                    allow_e = False
-                    allow_decimal = False
-
-            return c, 'TK_WORD'
-
-        if self.acorn.isIdentifierStart(self.input.peekCharCode(-1)):
-            if self.input.hasNext():
-                while self.acorn.isIdentifierChar(self.input.peekCharCode()):
-                    c += self.input.next()
-                    if not self.input.hasNext():
-                        break
-
-            if not (last_token.type == 'TK_DOT' \
-                        or (last_token.type == 'TK_RESERVED' and last_token.text in ['set', 'get'])) \
-                    and c in self.reserved_words:
-                if c == 'in' or c == 'of': # in and of are operators, need to hack
-                    return c, 'TK_OPERATOR'
-
-                return c, 'TK_RESERVED'
-
-            return c, 'TK_WORD'
-
-        if c in '([':
-            return c, 'TK_START_EXPR'
-
-        if c in ')]':
-            return c, 'TK_END_EXPR'
-
-        if c == '{':
-            return c, 'TK_START_BLOCK'
-
-        if c == '}':
-            return c, 'TK_END_BLOCK'
-
-        if c == ';':
-            return c, 'TK_SEMICOLON'
-
-        if c == '/':
-            comment = ''
-            inline_comment = True
-            if self.input.peek() == '*': # peek /* .. */ comment
-                self.input.next()
-                comment_match = self.input.match(self.block_comment_pattern)
-                comment = '/*' + comment_match.group(0)
-
-                directives = self.get_directives(comment)
-                if directives and directives.get('ignore') == 'start':
-                    comment_match = self.input.match(self.directives_end_ignore_pattern)
-                    comment += comment_match.group(0)
-                comment = re.sub(self.acorn.allLineBreaks, '\n', comment)
-                return comment, 'TK_BLOCK_COMMENT', directives
-
-            if self.input.peek() == '/': # peek // comment
-                self.input.next()
-                comment_match = self.input.match(self.comment_pattern)
-                comment = '//' + comment_match.group(0)
-                return comment, 'TK_COMMENT'
-
-        startXmlRegExp = re.compile('<()([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*(\'[^\']*\'|"[^"]*"|{[\s\S]+?}))*\s*(/?)\s*>')
-
-        self.has_char_escapes = False
-
-        if c == '`' or c == "'" or c == '"' or \
-            ( \
-                (c == '/') or \
-                (self.opts.e4x and c == "<" and self.input.test(startXmlRegExp, -1)) \
-            ) and ( \
-                (last_token.type == 'TK_RESERVED' and last_token.text in ['return', 'case', 'throw', 'else', 'do', 'typeof', 'yield']) or \
-                (last_token.type == 'TK_END_EXPR' and last_token.text == ')' and \
-                            last_token.parent and last_token.parent.type == 'TK_RESERVED' and last_token.parent.text in ['if', 'while', 'for']) or \
-                (last_token.type in ['TK_COMMENT', 'TK_START_EXPR', 'TK_START_BLOCK', 'TK_END_BLOCK', 'TK_OPERATOR', \
-                                   'TK_EQUALS', 'TK_EOF', 'TK_SEMICOLON', 'TK_COMMA'])):
-            sep = c
-            esc = False
-            esc1 = 0
-            esc2 = 0
-            resulting_string = c
-            in_char_class = False
-
-            if sep == '/':
-                # handle regexp
-                in_char_class = False
-                while self.input.hasNext() and \
-                        (esc or in_char_class or self.input.peek()!= sep) and \
-                        not self.input.testChar(self.acorn.newline):
-                    resulting_string += self.input.peek()
-                    if not esc:
-                        esc = self.input.peek() == '\\'
-                        if self.input.peek() == '[':
-                            in_char_class = True
-                        elif self.input.peek() == ']':
-                            in_char_class = False
-                    else:
-                        esc = False
-                    self.input.next()
-
-            elif self.opts.e4x and sep == '<':
-                # handle e4x xml literals
-                xmlRegExp = re.compile('[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*(\'[^\']*\'|"[^"]*"|{[\s\S]+?}))*\s*(/?)\s*>')
-                self.input.back()
-                xmlStr = ""
-                match = self.input.match(xmlRegExp)
-                if match:
-                    rootTag = match.group(2)
-                    rootTag = re.sub(r'^{\s+', '{', re.sub(r'\s+}$', '}', rootTag))
-                    isCurlyRoot = rootTag.startswith('{')
-                    depth = 0
-                    while (match):
-                        isEndTag = match.group(1)
-                        tagName = match.group(2)
-                        isSingletonTag = (match.groups()[-1] != "") or (match.group(2)[0:8] == "![CDATA[")
-                        if not isSingletonTag and (
-                            tagName == rootTag or (isCurlyRoot and re.sub(r'^{\s+', '{', re.sub(r'\s+}$', '}', tagName)))):
-                            if isEndTag:
-                                depth -= 1
-                            else:
-                                depth += 1
-
-                        xmlStr += match.group(0)
-                        if depth <= 0:
-                            break
-
-                        match = self.input.match(xmlRegExp)
-
-
-                    # if we didn't close correctly, keep unformatted.
-                    if not match:
-                        xmlStr += self.input.match(re.compile('[\s\S]*')).group(0)
-
-                    xmlStr = re.sub(self.acorn.allLineBreaks, '\n', xmlStr)
-                    return xmlStr, 'TK_STRING'
-
-            else:
-
-                # handle string
-                def parse_string(self, resulting_string, delimiter, allow_unescaped_newlines = False, start_sub = None):
-                    esc = False
-                    while self.input.hasNext():
-                        current_char = self.input.peek()
-                        if not (esc or (current_char != delimiter and
-                                (allow_unescaped_newlines or not self.acorn.newline.match(current_char)))):
-                            break
-
-                        # Handle \r\n linebreaks after escapes or in template strings
-                        if (esc or allow_unescaped_newlines) and self.acorn.newline.match(current_char):
-                            if current_char == '\r' and self.input.peek(1) == '\n':
-                                self.input.next()
-                                current_char = self.input.peek()
-
-                            resulting_string += '\n'
-                        else:
-                            resulting_string += current_char
-
-                        if esc:
-                            if current_char == 'x' or current_char == 'u':
-                                self.has_char_escapes = True
-
-                            esc = False
-                        else:
-                            esc = current_char == '\\'
-
-                        self.input.next()
-
-                        if start_sub and resulting_string.endswith(start_sub):
-                            if delimiter == '`':
-                                resulting_string = parse_string(self, resulting_string, '}', allow_unescaped_newlines, '`')
-                            else:
-                                resulting_string = parse_string(self, resulting_string, '`', allow_unescaped_newlines, '${')
-
-                            if self.input.hasNext():
-                                resulting_string += self.input.next()
-
-                    return resulting_string
-
-                if sep == '`':
-                    resulting_string = parse_string(self, resulting_string, '`', True, '${')
-                else:
-                    resulting_string = parse_string(self, resulting_string, sep)
-
-
-            if self.has_char_escapes and self.opts.unescape_strings:
-                resulting_string = self.unescape_string(resulting_string)
-
-            if self.input.peek() == sep:
-                resulting_string += self.input.next()
-
-                if sep == '/':
-                    # regexps may have modifiers /regexp/MOD, so fetch those too
-                    # Only [gim] are valid, but if the user puts in garbage, do what we can to take it.
-                    while self.input.hasNext() and self.acorn.isIdentifierStart(self.input.peekCharCode()):
-                        resulting_string += self.input.next()
-
-            resulting_string = re.sub(self.acorn.allLineBreaks, '\n', resulting_string)
-
-            return resulting_string, 'TK_STRING'
-
-        if c == '#':
-
-            # she-bang
-            if len(self.tokens) == 0 and self.input.peek() == '!':
-                resulting_string = c
-                while self.input.hasNext() and c != '\n':
-                    c = self.input.next()
-                    resulting_string += c
-                return resulting_string.strip() + '\n', 'TK_UNKNOWN'
-
-
-            # Spidermonkey-specific sharp variables for circular references
-            # https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
-            # http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
-            sharp = '#'
-            if self.input.hasNext() and self.input.testChar(self.digit):
-                while True:
-                    c = self.input.next()
-                    sharp += c
-                    if (not self.input.hasNext()) or c == '#' or c == '=':
-                        break
-            if c == '#':
-                pass
-            elif self.input.peek() == '[' and self.input.peek(1) == ']':
-                sharp += '[]'
-                self.input.next()
-                self.input.next()
-            elif self.input.peek() == '{' and self.input.peek(1) == '}':
-                sharp += '{}'
-                self.input.next()
-                self.input.next()
-            return sharp, 'TK_WORD'
-
-        if c == '<' and self.input.peek() in ['?', '%']:
-            self.input.back()
-            template_match = self.input.match(self.template_pattern)
-            if template_match:
-                c = template_match.group(0)
-                c = re.sub(self.acorn.allLineBreaks, '\n', c)
-                return c, 'TK_STRING'
-
-
-        if c == '<' and self.input.match(re.compile('\!--')):
-            c = '<!--'
-            while self.input.hasNext() and not self.input.testChar(self.acorn.newline):
-                c += self.input.next()
-
-            self.in_html_comment = True
-            return c, 'TK_COMMENT'
-
-        if c == '-' and self.in_html_comment and self.input.match(re.compile('->')):
-            self.in_html_comment = False
-            return '-->', 'TK_COMMENT'
-
-        if c == '.':
-            if self.input.peek() == '.' and self.input.peek(1) == '.':
-                c += self.input.next() + self.input.next()
-                return c, 'TK_OPERATOR'
-
-            return c, 'TK_DOT'
-
-        if c in self.punct:
-            while self.input.hasNext() and c + self.input.peek() in self.punct:
-                c += self.input.next()
-                if not self.input.hasNext():
-                    break
-
-            if c == ',':
-                return c, 'TK_COMMA'
-            if c == '=':
-                return c, 'TK_EQUALS'
-
-            return c, 'TK_OPERATOR'
-
-        return c, 'TK_UNKNOWN'
-
-    def unescape_string(self, s):
-        # You think that a regex would work for this
-        # return s.replace(/\\x([0-9a-f]{2})/gi, function(match, val) {
-        #         return String.fromCharCode(parseInt(val, 16));
-        #     })
-        # However, dealing with '\xff', '\\xff', '\\\xff' makes this more fun.
-        out = self.acorn.six.u('')
-        escaped = 0
-
-        input_scan = InputScanner(s)
-        matched = None
-
-        while input_scan.hasNext():
-            # Keep any whitespace, non-slash characters
-            # also keep slash pairs.
-            matched = input_scan.match(re.compile(r'([\s]|[^\\]|\\\\)+'))
-
-            if matched:
-                out += matched.group(0)
-
-            if input_scan.peek() != '\\':
-                continue
-
-            input_scan.next()
-            if input_scan.peek() == 'x':
-                matched = input_scan.match(re.compile('x([0-9A-Fa-f]{2})'))
-            elif input_scan.peek() == 'u':
-                matched = input_scan.match(re.compile('u([0-9A-Fa-f]{4})'));
-            else:
-                out += '\\'
-                if input_scan.hasNext():
-                    out += input_scan.next()
-                continue
-
-            # If there's some error decoding, return the original string
-            if not matched:
-                return s
-
-            escaped = int(matched.group(1), 16)
-
-            if escaped > 0x7e and escaped <= 0xff and matched.group(0).startswith('x'):
-                # we bail out on \x7f..\xff,
-                # leaving whole string escaped,
-                # as it's probably completely binary
-                return s
-            elif escaped >= 0x00 and escaped < 0x20:
-                # leave 0x00...0x1f escaped
-                out += '\\' + matched.group(0)
-                continue
-            elif escaped == 0x22 or escaped == 0x27 or escaped == 0x5c:
-                # single-quote, apostrophe, backslash - escape these
-                out += ('\\' + chr(escaped))
-            else:
-                out += self.acorn.six.unichr(escaped)
-
-        return out
-
-def isFileDifferent(filepath, expected):
-    try:
-        return (''.join(io.open(filepath, 'rt', newline='').readlines()) != expected)
-    except:
-        return True
-
-
-def main():
-
-    argv = sys.argv[1:]
-
-    try:
-        opts, args = getopt.getopt(argv, "s:c:e:o:rdEPjabkil:xhtfvXnCO:w:",
-            ['indent-size=','indent-char=','eol=''outfile=', 'replace', 'disable-preserve-newlines',
-            'space-in-paren', 'space-in-empty-paren', 'jslint-happy', 'space-after-anon-function',
-            'brace-style=', 'keep-array-indentation', 'indent-level=', 'unescape-strings',
-            'help', 'usage', 'stdin', 'eval-code', 'indent-with-tabs', 'keep-function-indentation', 'version',
-            'e4x', 'end-with-newline','comma-first','operator-position=','wrap-line-length','editorconfig'])
-    except getopt.GetoptError as ex:
-        print(ex, file=sys.stderr)
-        return usage(sys.stderr)
-
-    js_options = default_options()
-
-    file = None
-    outfile = 'stdout'
-    replace = False
-    if len(args) == 1:
-        file = args[0]
-
-    for opt, arg in opts:
-        if opt in ('--keep-array-indentation', '-k'):
-            js_options.keep_array_indentation = True
-        if opt in ('--keep-function-indentation','-f'):
-            js_options.keep_function_indentation = True
-        elif opt in ('--outfile', '-o'):
-            outfile = arg
-        elif opt in ('--replace', '-r'):
-            replace = True
-        elif opt in ('--indent-size', '-s'):
-            js_options.indent_size = int(arg)
-        elif opt in ('--indent-char', '-c'):
-            js_options.indent_char = arg
-        elif opt in ('--eol', '-e'):
-            js_options.eol = arg
-        elif opt in ('--indent-with-tabs', '-t'):
-            js_options.indent_with_tabs = True
-        elif opt in ('--disable-preserve-newlines', '-d'):
-            js_options.preserve_newlines = False
-        elif opt in ('--space-in-paren', '-P'):
-            js_options.space_in_paren = True
-        elif opt in ('--space-in-empty-paren', '-E'):
-            js_options.space_in_empty_paren = True
-        elif opt in ('--jslint-happy', '-j'):
-            js_options.jslint_happy = True
-        elif opt in ('--space_after_anon_function', '-a'):
-            js_options.space_after_anon_function = True
-        elif opt in ('--eval-code'):
-            js_options.eval_code = True
-        elif opt in ('--brace-style', '-b'):
-            js_options.brace_style = arg
-        elif opt in ('--unescape-strings', '-x'):
-            js_options.unescape_strings = True
-        elif opt in ('--e4x', '-X'):
-            js_options.e4x = True
-        elif opt in ('--end-with-newline', '-n'):
-            js_options.end_with_newline = True
-        elif opt in ('--comma-first', '-C'):
-            js_options.comma_first = True
-        elif opt in ('--operator-position', '-O'):
-            js_options.operator_position = sanitizeOperatorPosition(arg)
-        elif opt in ('--wrap-line-length ', '-w'):
-            js_options.wrap_line_length = int(arg)
-        elif opt in ('--stdin', '-i'):
-            file = '-'
-        elif opt in ('--editorconfig'):
-            js_options.editorconfig = True
-        elif opt in ('--version', '-v'):
-            return print(__version__)
-        elif opt in ('--help', '--usage', '-h'):
-            return usage()
-
-
-    if not file:
-        file = '-'
-
-    try:
-        if outfile == 'stdout' and replace and not file == '-':
-            outfile = file
-
-        # Editorconfig used only on files, not stdin
-        if getattr(js_options, 'editorconfig'):
-            editorconfig_filepath = file
-
-            if editorconfig_filepath == '-':
-                if outfile != 'stdout':
-                    editorconfig_filepath = outfile
-                else:
-                    fileType = 'js'
-                    editorconfig_filepath = 'stdin.' + fileType
-
-            # debug("EditorConfig is enabled for ", editorconfig_filepath);
-            js_options = copy.copy(js_options)
-            set_file_editorconfig_opts(editorconfig_filepath, js_options)
-
-        pretty = beautify_file(file, js_options)
-
-        if outfile == 'stdout':
-            # python automatically converts newlines in text to "\r\n" when on windows
-            # switch to binary to prevent this
-            if sys.platform == "win32":
-                import msvcrt
-                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-
-            if sys.stdout.encoding is None:
-                # sys.stdout.encoding will be None if stdout is redirected (at
-                # least on Python 2), leading to encoding errors when stdout is
-                # redirected and the beautified content contains unicode
-                try:
-                    sys.stdout.buffer.write(pretty.encode(locale.getpreferredencoding()))
-                except:
-                    sys.stdout.write(pretty.encode(locale.getpreferredencoding()))
-            else:
-                sys.stdout.write(pretty)
-	
-        else:
-            if isFileDifferent(outfile, pretty):
-                mkdir_p(os.path.dirname(outfile))
-
-                # python automatically converts newlines in text to "\r\n" when on windows
-                # set newline to empty to prevent this
-                with io.open(outfile, 'wt', newline='') as f:
-                    print('writing ' + outfile, file=sys.stderr)
-                    try:
-                        f.write(pretty)
-                    except TypeError:
-                        # This is not pretty, but given how we did the version import
-                        # it is the only way to do this without having setup.py fail on a missing six dependency.
-                        six = __import__("six")
-                        f.write(six.u(pretty))
-
-
-    except Exception as ex:
-        print(ex, file=sys.stderr)
-        return 1
-
-    # Success
-    return 0
diff --git a/dockerfiles/commul-customization/aai.js b/dockerfiles/commul-customization/aai.js
deleted file mode 100644
index 03edd649911917c8fb7ecfc352a0152ea6141669..0000000000000000000000000000000000000000
--- a/dockerfiles/commul-customization/aai.js
+++ /dev/null
@@ -1,103 +0,0 @@
-'use strict';
-(function(window){
-  function AAI() {
-    var host = 'https://' + window.location.hostname,
-        ourEntityID = host.match("clarin-dev.eurac.edu") ? "https://clarin-dev.eurac.edu" : host;
-    this.defaults = {
-      //host : 'https://ufal-point.mff.cuni.cz',
-      host : host, //better default (useful when testing on ufal-point-dev)
-      // do not add protocol because an error will appear in the DJ dialog
-      // if you see the error, your SP is not listed among djc trusted (edugain is enough to be trusted)
-      responseUrl: window.location.protocol + '//clarin-dev.eurac.edu/aai/discojuiceDiscoveryResponse.html',
-      ourEntityID: ourEntityID + '/Shibboleth.sso/Metadata',
-      serviceName: '',
-      metadataFeed: host + '/xmlui/discojuice/feeds',
-      selector: 'a.signon', // selector for login button
-      autoInitialize: true, // auto attach DiscoJuice to DOM
-      textHelpMore: "First check you are searching under the right country.\nIf your provider is not listed, please read <a href='https://clarin-dev.eurac.edu/how-do-i-sign-up' style='text-decoration: underline; font-weight: bold;'>these instructions</a> to obtain an account."
-    };
-    this.setup = function(options) {
-      var opts = jQuery.extend({}, this.defaults, options),
-          defaultCallback = function(e) {
-            window.location = opts.host + '/Shibboleth.sso/Login?SAMLDS=1&target=' + opts.target + '&entityID=' + window.encodeURIComponent(e.entityID);
-          };
-      //console.log(opts);
-      if(!opts.target){
-        throw 'You need to set the \'target\' parameter.';
-      }
-      // call disco juice setup
-      if (!opts.autoInitialize || $(opts.selector).length > 0) {
-        if(! window.DiscoJuice ){
-          throw 'Failed to find DiscoJuice. Did you include all that is necessary?';
-        }
-        var djc = DiscoJuice.Hosted.getConfig(
-          opts.serviceName,
-          opts.ourEntityID,
-          opts.responseUrl,
-          [ ],
-          opts.host + '/Shibboleth.sso/Login?SAMLDS=1&target='+opts.target+'&entityID=');
-        djc.metadata = [opts.metadataFeed];
-        djc.subtitle = "Login via Your home institution (e.g. university)";
-        djc.textHelp = opts.textHelp;
-        djc.textHelpMore = opts.textHelpMore;
-
-        djc.inlinemetadata = typeof opts.inlinemetadata === 'object' ? opts.inlinemetadata : [];
-        djc.inlinemetadata.push({
-          'country': '_all_',
-          'entityID': 'https://idm.clarin.eu',
-          'geo': {'lat': '51.833298', 'lon': '5.866699'},
-          'title': 'Clarin.eu website account',
-          'weight': -801
-        });
-        djc.inlinemetadata.push({
-          'country': 'IT',
-          'entityID': 'https://idp.eurac.edu/idp/shibboleth',
-          'geo': {'lat': '46.494281', 'lon': '11.346842'},
-          'title': 'Eurac Research',
-          'weight': -1000
-        });
-
-        if(opts.localauth) {
-          djc.inlinemetadata.push(
-            {
-              'entityID': 'local://',
-              'auth': 'local',
-              'title': 'Local authentication',
-              'country': '_all_',
-              'geo': null,
-              'weight': 1000
-            });
-          djc.callback = function(e){
-            var auth = e.auth || null;
-            switch(auth) {
-              case 'local':
-                DiscoJuice.UI.setScreen(opts.localauth);
-                jQuery('input#login').focus();
-                break;
-              //case 'saml':
-              default:
-                defaultCallback(e);
-                break;
-            }
-          };
-        }
-
-        if (opts.callback && typeof opts.callback === 'function') {
-          djc.callback = function(e) {
-            opts.callback(e, opts, defaultCallback);
-          };
-        }
-
-        if (opts.autoInitialize) {
-          jQuery(opts.selector).DiscoJuice( djc );
-        }
-
-        return djc;
-      } //if jQuery(selector)
-    };
-  }
-
-  if (!window.aai) {
-    window.aai = new AAI();
-  }
-})(window);
diff --git a/dockerfiles/commul-customization/aai_config.js b/dockerfiles/commul-customization/aai_config.js
deleted file mode 100644
index b2ff2fd356de75710f1a3a6cd729acdeee5c5a84..0000000000000000000000000000000000000000
--- a/dockerfiles/commul-customization/aai_config.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*global jQuery */
-/*jshint globalstrict: true*/
-'use strict';
-
-jQuery(document).ready(
-    function () {
-        var opts = (function () {
-            var instance = {};
-	    instance.autoInitialize = false;
-            //if ever port is needed (eg. testing other tomcat) it should be in responseUrl and target
-            instance.port = (window.location.port === "" ? "" : ":" + window.location.port);
-            instance.host = window.location.protocol + '//' +
-                window.location.hostname;
-            instance.repoPath = jQuery("a#repository_path").attr("href");
-            if (instance.repoPath.charAt(instance.repoPath.length - 1) !== '/') {
-                instance.repoPath = instance.repoPath + '/';
-        }
-            instance.target = instance.host + instance.port + instance.repoPath;
-            //In order to use the discojuice store (improve score of used IDPs)
-            //Works only with "verified" SPs - ie. ufal-point, displays error on ufal-point-dev
-            instance.responseUrl =
-                (window.location.hostname.search("clarin-dev") >= 0) ?
-                        "" :
-                        instance.host + instance.port + instance.repoPath +
-                            "themes/UFAL/lib/html/disco-juice.html?";
-            instance.metadataFeed = instance.target + "discojuice/feeds";
-            instance.serviceName = "Eurac Research CLARIN Centre";
-            instance.localauth =
-                '<form method="post" action="' + instance.target + 'password-login"> ' +
-                    '<p>Sign in using your local account obtained from the ERCC administrator.</p>' +
-                    '<p style="margin: 5px; color: #888" ><input type="text" name="login_email" style="font-size: 160%; width: 100%" id="login" /> <label for="login">E-Mail Address</label></p>' +
-                    '<p style="margin: 5px; color: #888" ><input type="password" name="login_password" style="font-size: 160%; width: 100%" id="pass" /> <label for="pass">Password</label></p>' +
-                    '<p style="margin: 5px; color: #607890; text-decoration: underline;"><a href="' + instance.target + 'forgot">Forgot your password?</a></p>' +
-                    '<p  style="" ><input type="submit" style="margin: 20px 2px" name="submit" value="Sign in" /></p>' +
-                    '</form>';
-            instance.target = instance.target + "shibboleth-login";
-            return instance;
-    })();
-    if (!("aai" in window)) {
-            throw "Failed to find UFAL AAI object. See https://redmine.ms.mff.cuni.cz/projects/lindat-aai for more details!";
-    }
-        window.aai.setup(opts);
-    }
-); // ready
diff --git a/dockerfiles/commul-customization/clarin.eurac.edu.template.metadata.xml b/dockerfiles/commul-customization/clarin.eurac.edu.template.metadata.xml
deleted file mode 100644
index f5d37257638744dbfac38b4a671d17ee9a3700c8..0000000000000000000000000000000000000000
--- a/dockerfiles/commul-customization/clarin.eurac.edu.template.metadata.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_5d15d5a81bc952da1d34986ebc7713c0d5c9ea61" entityID="https://clarin-dev.eurac.edu/Shibboleth.sso/Metadata">
-    <md:Extensions>
-        <mdattr:EntityAttributes xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute">
-            <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://macedir.org/entity-category" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
-                <saml:AttributeValue>http://www.geant.net/uri/dataprotection-code-of-conduct/v1</saml:AttributeValue>
-            </saml:Attribute>
-            <saml:Attribute
-                xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
-                Name="http://macedir.org/entity-category"
-                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
-                <saml:AttributeValue>http://refeds.org/category/research-and-scholarship</saml:AttributeValue>
-            </saml:Attribute>
-            <saml:Attribute 
-               xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://macedir.org/entity-category" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
-                <saml:AttributeValue>http://clarin.eu/category/clarin-member</saml:AttributeValue>
-            </saml:Attribute>
-        </mdattr:EntityAttributes>
-    </md:Extensions>
-    <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:1.0:protocol">
-        <md:Extensions xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
-            <mdui:UIInfo xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
-                <mdui:DisplayName xml:lang="en">Eurac Research CLARIN Centre</mdui:DisplayName>
-                <mdui:DisplayName xml:lang="de">Eurac Research CLARIN Centre</mdui:DisplayName>
-                <mdui:DisplayName xml:lang="it">Eurac Research CLARIN Centre</mdui:DisplayName>
-                <mdui:Description xml:lang="en">Eurac Research CLARIN Centre: Digital repository for language data</mdui:Description>
-                <mdui:Description xml:lang="de">Eurac Research CLARIN Centre: Digitales Repository für Sprachdaten</mdui:Description>
-                <mdui:Description xml:lang="it">Eurac Research CLARIN Centre: repository digitale di risorse linguistiche</mdui:Description>
-                <mdui:InformationURL xml:lang="en">https://clarin-dev.eurac.edu/repository/xmlui/page/about</mdui:InformationURL>
-                <mdui:InformationURL xml:lang="de">https://clarin-dev.eurac.edu/repository/xmlui/page/about</mdui:InformationURL>
-                <mdui:InformationURL xml:lang="it">https://clarin-dev.eurac.edu/repository/xmlui/page/about</mdui:InformationURL>
-		<mdui:Logo height="85" width="180">https://clarin-dev.eurac.edu/repository/xmlui/themes/UFAL/lib/lindat/public/img/eurac_research.svg</mdui:Logo>                    
-                <mdui:PrivacyStatementURL xml:lang="en">https://clarin-dev.eurac.edu/repository/xmlui/page/registration-privacypolicy</mdui:PrivacyStatementURL>
-                <mdui:PrivacyStatementURL xml:lang="de">https://clarin-dev.eurac.edu/repository/xmlui/page/registration-privacypolicy</mdui:PrivacyStatementURL>
-                <mdui:PrivacyStatementURL xml:lang="it">https://clarin-dev.eurac.edu/repository/xmlui/page/registration-privacypolicy</mdui:PrivacyStatementURL>
-            </mdui:UIInfo>          
-        </md:Extensions>
-        <md:AttributeConsumingService index="1">
-            <md:ServiceName xml:lang="en">Digital Repository for the CLARIN Research Infrastructure provided by Eurac Research</md:ServiceName>
-            <md:ServiceName xml:lang="de">Digitales Repository für die CLARIN-Forschungs-Infrastruktur bereitgestellt durch Eurac Research</md:ServiceName>
-            <md:ServiceName xml:lang="it">Repository Digitale per la Infrastruttura di Ricerca CLARIN erogato da Eurac Research</md:ServiceName>
-            <md:ServiceDescription xml:lang="en">Digital Repository and services related to the CLARIN-IT consortium under the CLARIN Research Infrastructure; focused in the fields of terminology and multilingualism. The repository is based at Eurac Research in South Tyrol and managed by the Institute for Applied Linguistics.</md:ServiceDescription>
-            <md:ServiceDescription xml:lang="it">Digitales Repository und Services mit Bezug zum CLARIN-IT-Consortium im Rahmen der CLARIN Forschungsinfrastruktur; mit Fokus auf den Gebieten der Terminologie und Mehrsprachigkeit. Das Repository wird von Eurac Research gehostet und dort vom Institut für Angewandte Sprachforschung betreut.</md:ServiceDescription>
-            <md:ServiceDescription xml:lang="it">Repository Digitale e servizi relativi al consorzio CLARIN-IT sotto l'Infrastruttura di Ricerca CLARIN; focalizzato nel campo della teminologia e multilinguismo. Il repository è basato a Eurac Research in Alto Adige e gestito del Istituto di Linguistica Applicata.</md:ServiceDescription>
-            <md:RequestedAttribute FriendlyName="eduPersonPrincipalName" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
-            <md:RequestedAttribute FriendlyName="email" Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
-            <md:RequestedAttribute FriendlyName="cn" Name="urn:oid:2.5.4.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
-            <md:RequestedAttribute FriendlyName="schacHomeOrganization" Name="urn:oid:1.3.6.1.4.1.25178.1.2.9" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
-            <md:RequestedAttribute FriendlyName="organizationName" Name="urn:oid:2.5.4.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
-            <md:RequestedAttribute FriendlyName="displayName" Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
-            <md:RequestedAttribute FriendlyName="eduPersonEntitlement" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
-            <md:RequestedAttribute FriendlyName="eduPersonTargetedID" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
-            <md:RequestedAttribute FriendlyName="eduPersonScopedAffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false"/>
-        </md:AttributeConsumingService>
-    </md:SPSSODescriptor>
-    <md:Organization>
-        <md:OrganizationName xml:lang="en">Eurac Research</md:OrganizationName>
-        <md:OrganizationName xml:lang="de">Eurac Research</md:OrganizationName>
-        <md:OrganizationName xml:lang="it">Eurac Research</md:OrganizationName>
-        <md:OrganizationDisplayName xml:lang="en">Eurac Research</md:OrganizationDisplayName>
-        <md:OrganizationDisplayName xml:lang="de">Eurac Research</md:OrganizationDisplayName>
-        <md:OrganizationDisplayName xml:lang="it">Eurac Research</md:OrganizationDisplayName>    	  
-        <md:OrganizationURL xml:lang="en">http://www.eurac.edu/en</md:OrganizationURL>
-        <md:OrganizationURL xml:lang="de">http://www.eurac.edu/de</md:OrganizationURL>
-        <md:OrganizationURL xml:lang="it">http://www.eurac.edu/it</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-        <md:GivenName>Egon</md:GivenName>
-        <md:SurName>Stemle</md:SurName>
-        <md:EmailAddress>mailto:clarin@eurac.edu</md:EmailAddress>
-    </md:ContactPerson>
-    <md:ContactPerson contactType="support">
-        <md:GivenName>Egon</md:GivenName>
-        <md:SurName>Stemle</md:SurName>
-        <md:EmailAddress>mailto:clarin@eurac.edu</md:EmailAddress>
-    </md:ContactPerson>
-    <md:ContactPerson contactType="administrative">
-        <md:GivenName>Andrea</md:GivenName>
-        <md:SurName>Abel</md:SurName>
-        <md:EmailAddress>mailto:linguistics@eurac.edu</md:EmailAddress>
-    </md:ContactPerson>
-</md:EntityDescriptor>
diff --git a/dockerfiles/commul-customization/dspace.cfg b/dockerfiles/commul-customization/dspace.cfg
deleted file mode 100644
index f058e50d7283ef388a573a0a16f2ebb3581b8497..0000000000000000000000000000000000000000
--- a/dockerfiles/commul-customization/dspace.cfg
+++ /dev/null
@@ -1,2199 +0,0 @@
-#
-# DSpace Configuration
-#
-# NOTE: The DSpace Configuration File is separated into several sections:
-#  * General Configurations
-#  * JSPUI & XMLUI Configurations
-#  * JSPUI Specific Configurations
-#  * XMLUI Specific Configurations
-#
-# Revision: $Revision$
-#
-# Date:     $Date$
-#
-
-
-#------------------------------------------------------------------#
-#------------------GENERAL CONFIGURATIONS--------------------------#
-#------------------------------------------------------------------#
-# These configs are used by underlying DSpace API, and are         #
-# therefore applicable to all interfaces                           #
-# Local, simple configuration should be made in build.properties   #
-# Global or more complex configuration can be hardcoded here       #
-#------------------------------------------------------------------#
-##### Basic information ######
-
-# DSpace installation directory
-dspace.dir = ${dspace.install.dir}
-
-# DSpace host name - should match base URL.  Do not include port number.
-dspace.hostname = ${dspace.hostname}
-
-# DSpace base host URL.  Include port number etc.
-dspace.baseUrl = ${dspace.baseUrl}
-
-# DSpace base URL.  Include port number etc., but NOT trailing slash
-# Change to xmlui if you wish to use the xmlui as the default, or remove
-# "/jspui" and set webapp of your choice as the "ROOT" webapp in
-# the servlet engine.
-dspace.url = ${dspace.url}
-
-# Optional: DSpace URL for mobile access
-# This 
-#dspace.mobileUrl = http://mobile.example.com
-
-# Name of the site
-dspace.name = ${dspace.name}
-
-# Default language for metadata values
-default.language = ${default.language}
-
-##### Database settings #####
-
-# URL for connecting to database
-db.url = ${db.url}
-
-# JDBC Driver
-db.driver = ${db.driver}
-
-# Database username and password
-db.username = ${db.username}
-db.password = ${db.password}
-
-# Schema name - if your database contains multiple schemas, you can avoid
-# problems with retrieving the definitions of duplicate object names by
-# specifying the schema name that is used for DSpace.
-# ORACLE USAGE NOTE: In Oracle, schema is equivalent to "username". This means
-# specifying a "db.schema" is often unnecessary (i.e. you can leave it blank),
-# UNLESS your Oracle DB Account (in db.username) has access to multiple schemas.
-db.schema = ${db.schema}
-
-## Connection pool parameters
-
-# Maximum number of DB connections in pool
-db.maxconnections = ${db.maxconnections}
-
-# Maximum time to wait before giving up if all connections in pool are busy (milliseconds)
-db.maxwait = ${db.maxwait}
-
-# Maximum number of idle connections in pool (-1 = unlimited)
-db.maxidle = ${db.maxidle}
-
-# Determine if prepared statement should be cached. (default is true)
-db.statementpool = ${db.statementpool}
-
-# Specify a name for the connection pool (useful if you have multiple applications sharing Tomcat's dbcp)
-# If not specified, defaults to 'dspacepool'
-db.poolname = ${db.poolname}
-
-# Specify a configured database connection pool to be fetched from a
-# directory.  This overrides the pool and driver settings above.  If
-# none can be found, then DSpace will use the above settings to create a
-# pool.
-#db.jndi = jdbc/dspace
-
-##### Email settings ######
-
-# SMTP mail server
-mail.server = ${mail.server}
-
-# SMTP mail server authentication username and password (if required)
-mail.server.username = ${mail.server.username}
-mail.server.password = ${mail.server.password}
-
-# SMTP mail server alternate port (defaults to 25)
-mail.server.port = ${mail.server.port}
-
-# From address for mail
-mail.from.address = ${mail.from.address}
-
-# Name of a pre-configured Session object to be fetched from a directory.
-# This overrides the Session settings above.  If none can be found, then DSpace
-# will use the above settings to create a Session.
-#mail.session.name = Session
-
-# Currently limited to one recipient!
-feedback.recipient = ${mail.feedback.recipient}
-
-# General site administration (Webmaster) e-mail
-mail.admin = ${mail.admin}
-
-# Recipient for server errors and alerts
-alert.recipient = ${mail.alert.recipient}
-
-# Recipient for new user registration emails
-registration.notify = ${mail.registration.notify}
-
-# Set the default mail character set. This may be overridden by providing a line
-# inside the email template "charset: <encoding>", otherwise this default is used.
-mail.charset = UTF-8
-
-# A comma-separated list of hostnames that are allowed to refer browsers to email forms.
-# Default behaviour is to accept referrals only from dspace.hostname
-mail.allowed.referrers = ${dspace.hostname}
-
-mail.extraproperties = ${mail.extraproperties}
-
-# Pass extra settings to the Java mail library. Comma-separated, equals sign between
-# the key and the value. For example:
-#mail.extraproperties = mail.smtp.socketFactory.port=465, \
-#                       mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory, \
-#                       mail.smtp.socketFactory.fallback=false
-
-# An option is added to disable the mailserver. By default, this property is set to false
-# By setting mail.server.disabled = true, DSpace will not send out emails.
-# It will instead log the subject of the email which should have been sent
-# This is especially useful for development and test environments where production data is used when testing functionality.
-mail.server.disabled = ${mail.server.disabled}
-
-##### File Storage ######
-
-# Asset (bitstream) store number 0 (zero)
-assetstore.dir = ${dspace.dir}/assetstore
-
-# Specify extra asset stores like this, counting from 1 upwards:
-# assetstore.dir.1 = /second/assetstore
-# assetstore.dir.2 = /third/assetstore
-
-# Specify the number of the store to use for new bitstreams with this property
-# The default is 0 (zero) which corresponds to the 'assetstore.dir' above
-# assetstore.incoming = 1
-
-
-##### SRB File Storage #####
-
-# The same 'assetstore.incoming' property is used to support the use of SRB
-# (Storage Resource Broker - see http://www.sdsc.edu/srb/) as an _optional_
-# replacement of or supplement to conventional file storage. DSpace will work
-# with or without SRB and full backward compatibility is maintained.
-#
-# The 'assetstore.incoming' property is an integer that references where _new_
-# bitstreams will be stored.  The default (say the starting reference) is zero.
-# The value will be used to identify the storage where all new bitstreams will
-# be stored until this number is changed.  This number is stored in the
-# Bitstream table (store_number column) in the DSpace database, so older
-# bitstreams that may have been stored when 'asset.incoming' had a different
-# value can be found.
-#
-# In the simple case in which DSpace uses local (or mounted) storage the
-# number can refer to different directories (or partitions).  This gives DSpace
-# some level of scalability.  The number links to another set of properties
-# 'assetstore.dir', 'assetstore.dir.1' (remember zero is default),
-# 'assetstore.dir.2', etc., where the values are directories.
-#
-# To support the use of SRB DSpace uses this same scheme but broadened to
-# support:
-# - using SRB instead of the local filesystem
-# - using the local filesystem (native DSpace)
-# - using a mix of SRB and local filesystem
-#
-# In this broadened use the 'asset.incoming' integer will refer one of the
-# following storage locations
-# - a local filesystem directory (native DSpace)
-# - a set of SRB account parameters (host, port, zone, domain, username,
-#       password, home directory, and resource)
-#
-# Should there be any conflict, like '2' refering to a local directory and
-# to a set of SRB parameters, the program will select the local directory.
-#
-# If SRB is chosen from the first install of DSpace, it is suggested that
-# 'assetstore.dir' (no integer appended) be retained to reference a local
-# directory (as above under File Storage) because build.xml uses this value
-# to do a mkdir. In this case, 'assetstore.incoming' can be set to 1 (i.e.
-# uncomment the line in File Storage above) and the 'assetstore.dir' will not
-# be used.
-#
-# Here is an example set of SRB parameters:
-# Assetstore 1 - SRB
-#srb.host.1 = mysrbmcathost.myu.edu
-#srb.port.1 = 5544
-#srb.mcatzone.1 = mysrbzone
-#srb.mdasdomainname.1 = mysrbdomain
-#srb.defaultstorageresource.1 = mydefaultsrbresource
-#srb.username.1 = mysrbuser
-#srb.password.1 = mysrbpassword
-#srb.homedirectory.1 = /mysrbzone/home/mysrbuser.mysrbdomain
-#srb.parentdir.1 = mysrbdspaceassetstore
-#
-# Assetstore n, n+1, ...
-# Follow same pattern as for assetstores above (local or SRB)
-
-
-##### Logging configuration #####
-
-# Override default log4j configuration
-# You may provide your own configuration here, existing alternatives are:
-# log.init.config = ${dspace.dir}/config/log4j.xml
-# log.init.config = ${dspace.dir}/config/log4j-console.properties
-log.init.config = ${dspace.dir}/config/log4j.properties
-
-# Where to put the logs (used in configuration only)
-log.dir = ${dspace.dir}/log
-
-# If enabled, the logging and the Solr statistics system will look for
-# an X-Forwarded-For header. If it finds it, it will use this for the user IP address
-#useProxies = true
-
-##### DOI registration agency credentials ######
-# To mint DOIs you have to use a DOI registration agency like DataCite. Several
-# DataCite members offers services as DOI registration agency, so f.e. EZID or
-# TIB Hannover. To mint DOIs with DSpace you have to get an agreement with an
-# DOI registration agency. You have to edit 
-# [dspace]/config/spring/api/identifier-service.xml and to configure the following
-# properties.
-
-# Credentials used to authenticate against the registration agency:
-identifier.doi.user = username
-identifier.doi.password = password
-# DOI prefix used to mint DOIs. All DOIs minted by DSpace will use this prefix.
-# The Prefix will be assigned by the registration agency.
-identifier.doi.prefix = 10.5072
-# If you want to, you can further separate your namespace. Should all the
-# suffixes of all DOIs minted by DSpace start with a special string to separate
-# it from other services also minting DOIs under your prefix?
-identifier.doi.namespaceseparator = dspace/
-
-##### Plugin management #####
-
-# Where to look for third-party plugin packages.  The value is a colon-separated
-# list of filesystem directories and/or JAR files:  a Java class path.  Plugin
-# classes not found in the usual places will be sought in these places last.  If
-# unset, only the standard places will be searched.
-#plugin.classpath = ${dspace.dir}/plugins/aPlugin.jar
-
-##### Search settings #####
-
-# Where to put search index files
-search.dir = ${dspace.dir}/search
-
-# Higher values of search.max-clauses will enable prefix searches to work on
-# large repositories
-search.max-clauses = 2048
-
-# Which Lucene Analyzer implementation to use.  If this is omitted or
-# commented out, the standard DSpace analyzer (designed for English)
-# is used by default.
-
-# Non-Stemming analyzer.  Does not "stem" words/terms. When using this analyzer,
-# a search for "wellness" will always return items matching "wellness" and not "well".
-# However, similarly a search for "experiments" will only return objects matching 
-# "experiments" and not "experiment" or "experimenting".
-# search.analyzer = org.dspace.search.DSNonStemmingAnalyzer
-
-# Chinese analyzer
-# search.analyzer = org.apache.lucene.analysis.cn.ChineseAnalyzer
-
-search.analyzer = org.dspace.search.DSAnalyzer
-
-# Boolean search operator to use, current supported values are OR and AND
-# If this config item is missing or commented out, OR is used
-# AND requires all search terms to be present
-# OR requires one or more search terms to be present
-search.operator = OR
-
-# Maximum number of terms indexed for a single field in Lucene.
-# Default is 10,000 words - often not enough for full-text indexing.
-# If you change this, you'll need to re-index for the change
-# to take effect on previously added items.
-# -1 = unlimited (Integer.MAX_VALUE)
-search.maxfieldlength = 10000
-
-##### Fields to Index for Search #####
-
-# DC metadata elements.qualifiers to be indexed for search
-# format: - search.index.[number] = [search field]:element.qualifier
-#       - * used as wildcard
-#	- inputform -> In case we have different input-forms for different repository supported locales (e.g input-forms_el.xml, input-forms_pt.xml etc). In this case, the 
-#		stored and the displayed value from all input-forms are indexed. If the stored value is not found in input-forms, it is indexed anyway.
-#		e.g.:search.index.12 = language:dc.language:inputform
-#
-###      changing these will change your search results,     ###
-###  but will NOT automatically change your search displays  ###
-
-search.index.1 = author:dc.contributor.*
-search.index.2 = author:dc.creator.*
-search.index.3 = title:dc.title.*
-search.index.4 = keyword:dc.subject.*
-search.index.5 = abstract:dc.description.abstract
-search.index.6 = author:dc.description.statementofresponsibility
-search.index.7 = series:dc.relation.ispartofseries
-search.index.8 = abstract:dc.description.tableofcontents
-search.index.9 = mime:dc.format.mimetype
-search.index.10 = sponsor:dc.description.sponsorship
-search.index.11 = identifier:dc.identifier.*
-search.index.12 = language:dc.language.iso
-search.index.13 = rights:dc.rights.label
-
-##### Handle settings ######
-
-# Canonical Handle URL prefix
-#
-# By default, DSpace is configured to use http://hdl.handle.net/
-# as the canonical URL prefix when generating dc.identifier.uri
-# during submission, and in the 'identifier' displayed in JSPUI
-# item record pages.
-#
-# If you do not subscribe to CNRI's handle service, you can change this
-# to match the persistent URL service you use, or you can force DSpace
-# to use your site's URL, eg.
-#handle.canonical.prefix = ${dspace.url}/handle/
-#
-# Note that this will not alter dc.identifer.uri metadata for existing
-# items (only for subsequent submissions), but it will alter the URL
-# in JSPUI's 'identifier' message on item record pages for existing items.
-#
-# If omitted, the canonical URL prefix will be http://hdl.handle.net/
-handle.canonical.prefix = ${handle.canonical.prefix}
-
-# CNRI Handle prefix
-handle.prefix = ${handle.prefix}
-
-# Directory for installing Handle server files
-handle.dir = ${handle.dir}
-
-# List any additional prefixes that need to be managed by this handle server 
-# (as for examle handle prefix coming from old dspace repository merged in 
-# that repository)
-# handle.additional.prefixes = prefix1[, prefix2]  
-
-# By default we hide the list handles method in the JSON endpoint as it could 
-# produce heavy load for large repository 
-# handle.hide.listhandles = false
-
-handle.caseSensitive = false
-
-##### Authorization system configuration - Delegate ADMIN #####
-
-# COMMUNITY ADMIN configuration
-# subcommunities and collections
-#core.authorization.community-admin.create-subelement = true
-#core.authorization.community-admin.delete-subelement = true
-# his community
-#core.authorization.community-admin.policies = true
-#core.authorization.community-admin.admin-group = true
-# collections in his community
-#core.authorization.community-admin.collection.policies = true
-#core.authorization.community-admin.collection.template-item = true
-#core.authorization.community-admin.collection.submitters = true
-#core.authorization.community-admin.collection.workflows = true
-#core.authorization.community-admin.collection.admin-group = true
-# item owned by collections in his community
-#core.authorization.community-admin.item.delete = true
-#core.authorization.community-admin.item.withdraw = true
-#core.authorization.community-admin.item.reinstatiate = true
-#core.authorization.community-admin.item.policies = true
-# also bundle...
-#core.authorization.community-admin.item.create-bitstream = true
-#core.authorization.community-admin.item.delete-bitstream = true
-#core.authorization.community-admin.item-admin.cc-license = true
-
-# COLLECTION ADMIN
-#core.authorization.collection-admin.policies = true
-#core.authorization.collection-admin.template-item = true
-#core.authorization.collection-admin.submitters = true
-#core.authorization.collection-admin.workflows = true
-#core.authorization.collection-admin.admin-group = true
-# item owned by his collection
-#core.authorization.collection-admin.item.delete = true
-#core.authorization.collection-admin.item.withdraw = true
-#core.authorization.collection-admin.item.reinstatiate = true
-#core.authorization.collection-admin.item.policies = true
-# also bundle...
-#core.authorization.collection-admin.item.create-bitstream = true
-#core.authorization.collection-admin.item.delete-bitstream = true
-#core.authorization.collection-admin.item-admin.cc-license = true
-
-# ITEM ADMIN
-#core.authorization.item-admin.policies = true
-# also bundle...
-#core.authorization.item-admin.create-bitstream = true
-#core.authorization.item-admin.delete-bitstream = true
-#core.authorization.item-admin.cc-license = true
-
-
-#### Restricted item visibilty settings ###
-# By default RSS feeds, OAI-PMH and subscription emails will include ALL items
-# regardless of permissions set on them.
-#
-# If you wish to only expose items through these channels where the ANONYMOUS
-# user is granted READ permission, then set the following options to false
-#
-# Warning: In large repositories, setting harvest.includerestricted.oai to false may cause
-# performance problems as all items will need to have their authorization permissions checked,
-# but because DSpace has not implemented resumption tokens in ListIdentifiers, ALL items will
-# need checking whenever a ListIdentifers request is made.
-#
-#harvest.includerestricted.rss = true
-#harvest.includerestricted.oai = true
-#harvest.includerestricted.subscription = true
-
-
-#### Proxy Settings ######
-# uncomment and specify both properties if proxy server required
-# proxy server for external http requests - use regular hostname without port number
-http.proxy.host = ${http.proxy.host}
-
-# port number of proxy server
-http.proxy.port = ${http.proxy.port}
-
-
-#### Media Filter / Format Filter plugins (through PluginManager) ####
-# Media/Format Filters help to full-text index content or
-# perform automated format conversions
-
-#Names of the enabled MediaFilter or FormatFilter plugins
-filter.plugins = PDF Text Extractor, HTML Text Extractor, \
-                 PowerPoint Text Extractor, \
-                 Word Text Extractor, JPEG Thumbnail
-
-# [To enable Branded Preview]: uncomment and insert the following into the plugin list
-#                Branded Preview JPEG, \
-
-# [To enable ImageMagick Thumbnail]: 
-#    remove "JPEG Thumbnail" from the plugin list 
-#    uncomment and insert the following line into the plugin list
-#                ImageMagick Image Thumbnail, ImageMagick PDF Thumbnail, \
-
-#Assign 'human-understandable' names to each filter
-plugin.named.org.dspace.app.mediafilter.FormatFilter = \
-  org.dspace.app.mediafilter.XPDF2Text = PDF Text Extractor, \
-  org.dspace.app.mediafilter.HTMLFilter = HTML Text Extractor, \
-  org.dspace.app.mediafilter.XPDF2Thumbnail = PDF Thumbnail, \  
-  org.dspace.app.mediafilter.WordFilter = Word Text Extractor, \
-  org.dspace.app.mediafilter.PowerPointFilter = PowerPoint Text Extractor, \
-  org.dspace.app.mediafilter.JPEGFilter = JPEG Thumbnail, \
-  org.dspace.app.mediafilter.BrandedPreviewJPEGFilter = Branded Preview JPEG, \
-  org.dspace.app.mediafilter.ImageMagickImageThumbnailFilter = ImageMagick Image Thumbnail, \
-  org.dspace.app.mediafilter.ImageMagickPdfThumbnailFilter = ImageMagick PDF Thumbnail
-
-#Configure each filter's input format(s)
-filter.org.dspace.app.mediafilter.XPDF2Thumbnail.inputFormats = Adobe PDF
-filter.org.dspace.app.mediafilter.XPDF2Text.inputFormats = Adobe PDF
-filter.org.dspace.app.mediafilter.HTMLFilter.inputFormats = HTML, Text
-filter.org.dspace.app.mediafilter.WordFilter.inputFormats = Microsoft Word
-filter.org.dspace.app.mediafilter.PowerPointFilter.inputFormats = Microsoft Powerpoint, Microsoft Powerpoint XML
-filter.org.dspace.app.mediafilter.JPEGFilter.inputFormats = BMP, GIF, JPEG, image/png
-filter.org.dspace.app.mediafilter.BrandedPreviewJPEGFilter.inputFormats = BMP, GIF, JPEG, image/png
-filter.org.dspace.app.mediafilter.ImageMagickImageThumbnailFilter.inputFormats = BMP, GIF, image/png, JPG, TIFF, JPEG, JPEG 2000
-filter.org.dspace.app.mediafilter.ImageMagickPdfThumbnailFilter.inputFormats = Adobe PDF
-
-#Publicly accessible thumbnails of restricted content.
-#List the MediaFilter name's that would get publicly accessible permissions
-#Any media filters not listed will instead inherit the permissions of the parent bitstream
-#filter.org.dspace.app.mediafilter.publicPermission = JPEGFilter, XPDF2Thumbnail
-
-#Custom settings for PDFFilter
-# If true, all PDF extractions are written to temp files as they are indexed...this
-# is slower, but helps ensure that PDFBox software DSpace uses doesn't eat up
-# all your memory
-#pdffilter.largepdfs = true
-# If true, PDFs which still result in an Out of Memory error from PDFBox
-# are skipped over...these problematic PDFs will never be indexed until
-# memory usage can be decreased in the PDFBox software
-#pdffilter.skiponmemoryexception = true
-
-# Custom settigns for ImageMagick Thumbnail Filters
-# ImageMagick and GhostScript must be installed on the server, set the path to ImageMagick and GhostScript executable
-#   http://www.imagemagick.org/
-#   http://www.ghostscript.com/
-# Note: thumbnail.maxwidth and thumbnail.maxheight are used to set Thumbnail dimensions
-# org.dspace.app.mediafilter.ImageMagickThumbnailFilter.ProcessStarter = /usr/bin
-#
-# bitstreams generated by this process will contain the following description and may be overwritten
-# org.dspace.app.mediafilter.ImageMagickThumbnailFilter.bitstreamDescription = IM Thumbnail
-#
-# bitstream descriptions that do not conform to the following regular expression will not be overwritten
-# org.dspace.app.mediafilter.ImageMagickThumbnailFilter.replaceRegex = ^Generated Thumbnail$
-# 
-# While PDFs may contain transparent spaces, JPEG cannot. As DSpace use JPEG
-# for the generated thumbnails, PDF containing transparent spaces may lead
-# to problems. To solve this the exported PDF page is flatten before it is
-# resized and stored as JPEG. You can switch this behavior off by setting the
-# next property false, if necessary for any reasons.
-# org.dspace.app.mediafilter.ImageMagickThumbnailFilter.flatten = true
-
-#### Crosswalk and Packager Plugin Settings ####
-# Crosswalks are used to translate external metadata formats into DSpace's internal format (DIM)
-# Packagers are used to ingest/export 'packages' (both content files and metadata)
-
-# Configure table-driven MODS dissemination crosswalk
-#  (add lower-case name for OAI-PMH)
-crosswalk.mods.properties.MODS = crosswalks/mods.properties
-crosswalk.mods.properties.mods = crosswalks/mods.properties
-
-# Configure XSLT-driven submission crosswalk for MODS
-crosswalk.submission.MODS.stylesheet= crosswalks/mods-submission.xsl
-
-# Configure XSLT-driven submission crosswalk for EPDCX. Originally developed for use with SWORD.
-crosswalk.submission.EPDCX.stylesheet = crosswalks/sword-swap-ingest.xsl
-
-# Configure the QDCCrosswalk dissemination plugin for Qualified DC
-#  (add lower-case name for OAI-PMH)
-crosswalk.qdc.namespace.QDC.dc = http://purl.org/dc/elements/1.1/
-crosswalk.qdc.namespace.QDC.dcterms = http://purl.org/dc/terms/
-crosswalk.qdc.schemaLocation.QDC  = \
-  http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd \
-  http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd
-crosswalk.qdc.properties.QDC = crosswalks/QDC.properties
-
-crosswalk.qdc.namespace.qdc.dc = http://purl.org/dc/elements/1.1/
-crosswalk.qdc.namespace.qdc.dcterms = http://purl.org/dc/terms/
-crosswalk.qdc.schemaLocation.qdc  = \
-  http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd \
-  http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd
-crosswalk.qdc.properties.qdc = crosswalks/QDC.properties
-
-#### XSLTDisseminationCrosswalks ####
-# XSLTDisseminationCrosswalks uses the selfnamed plugin
-# org.dspace.content.crosswalk.XSLTDisseminationCrosswalk configured above.
-# If you remove all XSLTDisseminationCrosswalk you should disable this plugin
-# to avoid an error log message every time you load DSpace!
-##
-## Configure XSLT-driven submission crosswalk for MARC21
-##
-crosswalk.dissemination.marc.stylesheet = crosswalks/DIM2MARC21slim.xsl
-crosswalk.dissemination.marc.schemaLocation = \
-    http://www.loc.gov/MARC21/slim \
-    http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd
-crosswalk.dissemination.marc.preferList = true
-##
-## Configure XSLT-driven submission crosswalk for DataCite
-##
-crosswalk.dissemination.DataCite.stylesheet = crosswalks/DIM2DataCite.xsl
-## For DataCite via EZID, comment above and uncomment this:
-#crosswalk.dissemination.DataCite.stylesheet = crosswalks/DIM2EZID.xsl
-crosswalk.dissemination.DataCite.schemaLocation = \
-    http://datacite.org/schema/kernel-2.2 \
-    http://schema.datacite.org/meta/kernel-2.2/metadata.xsd
-crosswalk.dissemination.DataCite.preferList = false
-
-# Crosswalk Plugin Configuration:
-#   The purpose of Crosswalks is to translate an external metadata format to/from
-#   the DSpace Internal Metadata format (DIM) or the DSpace Database.
-#   Crosswalks are often used by one or more Packager plugins (see below).
-plugin.named.org.dspace.content.crosswalk.IngestionCrosswalk = \
-  org.dspace.content.crosswalk.AIPDIMCrosswalk = DIM, \
-  org.dspace.content.crosswalk.AIPTechMDCrosswalk = AIP-TECHMD, \
-  org.dspace.content.crosswalk.PREMISCrosswalk = PREMIS, \
-  org.dspace.content.crosswalk.OREIngestionCrosswalkHttps = ore, \
-  org.dspace.content.crosswalk.NullIngestionCrosswalk = NIL, \
-  org.dspace.content.crosswalk.OAIDCIngestionCrosswalk = dc, \
-  org.dspace.content.crosswalk.DIMIngestionCrosswalk = dim, \
-  org.dspace.content.crosswalk.METSRightsCrosswalk = METSRIGHTS, \
-  org.dspace.content.crosswalk.RoleCrosswalk = DSPACE-ROLES, \
-  cz.cuni.mff.ufal.ORELicenseIngestionCrosswalk = ore_licenses
-
-plugin.selfnamed.org.dspace.content.crosswalk.IngestionCrosswalk = \
-  org.dspace.content.crosswalk.XSLTIngestionCrosswalk, \
-  org.dspace.content.crosswalk.QDCCrosswalk
-
-plugin.named.org.dspace.content.crosswalk.StreamIngestionCrosswalk = \
-  org.dspace.content.crosswalk.NullStreamIngestionCrosswalk = NULLSTREAM, \
-  org.dspace.content.crosswalk.CreativeCommonsRDFStreamIngestionCrosswalk = DSPACE_CCRDF, \
-  org.dspace.content.crosswalk.LicenseStreamIngestionCrosswalk = DSPACE_DEPLICENSE
-
-plugin.named.org.dspace.content.crosswalk.DisseminationCrosswalk = \
-  org.dspace.content.crosswalk.AIPDIMCrosswalk = DIM, \
-  org.dspace.content.crosswalk.AIPTechMDCrosswalk = AIP-TECHMD, \
-  org.dspace.content.crosswalk.SimpleDCDisseminationCrosswalk = DC, \
-  org.dspace.content.crosswalk.SimpleDCDisseminationCrosswalk = dc, \
-  org.dspace.content.crosswalk.PREMISCrosswalk = PREMIS, \
-  org.dspace.content.crosswalk.METSDisseminationCrosswalk = METS, \
-  org.dspace.content.crosswalk.METSDisseminationCrosswalk = mets, \
-  org.dspace.content.crosswalk.METSRightsCrosswalk = METSRIGHTS, \
-  org.dspace.content.crosswalk.OREDisseminationCrosswalk = ore, \
-  org.dspace.content.crosswalk.DIMDisseminationCrosswalk = dim, \
-  org.dspace.content.crosswalk.RoleCrosswalk = DSPACE-ROLES, \
-  cz.cuni.mff.ufal.LicensesDisseminationCrosswalk = UFAL_LICENSES, \  
-  
-
-# regarding the XSLTDisseminationCrosswalk see the section were it is
-# configured to avoid error logs! Disable it if you remove its configuration.
-plugin.selfnamed.org.dspace.content.crosswalk.DisseminationCrosswalk = \
-  org.dspace.content.crosswalk.MODSDisseminationCrosswalk , \
-  org.dspace.content.crosswalk.QDCCrosswalk, \
-  org.dspace.content.crosswalk.XHTMLHeadDisseminationCrosswalk, \
-  org.dspace.content.crosswalk.XSLTDisseminationCrosswalk
-
-plugin.named.org.dspace.content.crosswalk.StreamDisseminationCrosswalk = \
-  org.dspace.content.crosswalk.CreativeCommonsRDFStreamDisseminationCrosswalk = DSPACE_CCRDF, \
-  org.dspace.content.crosswalk.CreativeCommonsTextStreamDisseminationCrosswalk = DSPACE_CCTEXT, \
-  org.dspace.content.crosswalk.LicenseStreamDisseminationCrosswalk = DSPACE_DEPLICENSE
-
-# Packager Plugin Configuration:
-#   Configures the ingest and dissemination packages that DSpace supports.
-#   These Ingester and Disseminator classes support a specific package file format
-#   (e.g. METS) which DSpace understands how to import/export.  Each Packager
-#   plugin often will use one (or more) Crosswalk plugins to translate metadata (see above).
-plugin.named.org.dspace.content.packager.PackageDisseminator = \
-  org.dspace.content.packager.DSpaceAIPDisseminator = AIP, \
-  org.dspace.content.packager.DSpaceMETSDisseminator = METS, \
-  org.dspace.content.packager.RoleDisseminator = DSPACE-ROLES
-
-# Do NOT cache AIP/METS Disseminator plugin instances, as their exported obj lists
-# (in AbstractPackageDisseminator) need to be reset each time a new export occurs
-plugin.reusable.org.dspace.content.packager.DSpaceAIPDisseminator = false
-plugin.reusable.org.dspace.content.packager.DSpaceMETSDisseminator = false
-
-plugin.named.org.dspace.content.packager.PackageIngester = \
-  org.dspace.content.packager.DSpaceAIPIngester = AIP, \
-  org.dspace.content.packager.PDFPackager  = Adobe PDF, PDF, \
-  org.dspace.content.packager.DSpaceMETSIngester = METS, \
-  org.dspace.content.packager.RoleIngester = DSPACE-ROLES
-
-# Do NOT cache AIP/METS Ingester plugin instances, as their imported obj lists
-# (in AbstractPackageIngester) need to be reset each time a new import occurs
-plugin.reusable.org.dspace.content.packager.DSpaceAIPIngester = false
-plugin.reusable.org.dspace.content.packager.DSpaceMETSIngester = false
-
-#### METS ingester configuration:
-# These settings configure how DSpace will ingest a METS-based package
-
-# Configures the METS-specific package ingesters (defined above)
-# 'default' settings are specified by 'default' key
-
-# Default Option to save METS manifest in the item: (default is false)
-mets.default.ingest.preserveManifest = false
-
-# Default Option to make use of collection templates when using the METS ingester (default is false)
-mets.default.ingest.useCollectionTemplate = false
-
-# Default crosswalk mappings
-# Maps a METS 'mdtype' value to a DSpace crosswalk for processing.
-# When the 'mdtype' value is same as the name of a crosswalk, that crosswalk
-# will be called automatically (e.g. mdtype='PREMIS' calls the crosswalk named
-# 'PREMIS', unless specified differently in below mapping)
-# Format is 'mets.default.ingest.crosswalk.<mdType> = <DSpace-crosswalk-name>'
-mets.default.ingest.crosswalk.DC = QDC
-mets.default.ingest.crosswalk.DSpaceDepositLicense = DSPACE_DEPLICENSE
-mets.default.ingest.crosswalk.Creative\ Commons = DSPACE_CCRDF
-mets.default.ingest.crosswalk.CreativeCommonsRDF = DSPACE_CCRDF
-mets.default.ingest.crosswalk.CreativeCommonsText = NULLSTREAM
-mets.default.ingest.crosswalk.EPDCX = EPDCX
-
-# Locally cached copies of METS schema documents to save time on ingest.  This
-# will often speed up validation & ingest significantly.  Before enabling
-# these settings, you must manually cache all METS schemas in
-# [dspace]/config/schemas/ (does not exist by default).  Most schema documents
-# can be found on the http://www.loc.gov/ website.
-# Enable the below settings to pull these *.xsd files from your local cache.
-# (Setting format: mets.xsd.<abbreviation> = <namespace> <local-file-name>)
-#mets.xsd.mets = http://www.loc.gov/METS/ mets.xsd
-#mets.xsd.xlink = http://www.w3.org/1999/xlink xlink.xsd
-#mets.xsd.mods = http://www.loc.gov/mods/v3 mods.xsd
-#mets.xsd.xml = http://www.w3.org/XML/1998/namespace xml.xsd
-#mets.xsd.dc = http://purl.org/dc/elements/1.1/ dc.xsd
-#mets.xsd.dcterms = http://purl.org/dc/terms/ dcterms.xsd
-#mets.xsd.premis = http://www.loc.gov/standards/premis PREMIS.xsd
-#mets.xsd.premisObject = http://www.loc.gov/standards/premis PREMIS-Object.xsd
-#mets.xsd.premisEvent = http://www.loc.gov/standards/premis PREMIS-Event.xsd
-#mets.xsd.premisAgent = http://www.loc.gov/standards/premis PREMIS-Agent.xsd
-#mets.xsd.premisRights = http://www.loc.gov/standards/premis PREMIS-Rights.xsd
-
-#### AIP Ingester & Disseminator Configuration
-# These settings configure how DSpace will ingest/export its own
-# AIP (Archival Information Package) format for backups and restores
-# (Please note, as the DSpace AIP format is also METS based, it will also
-# use many of the 'METS ingester configuration' settings directly above)
-
-# AIP-specific ingestion crosswalk mappings
-# (overrides 'mets.default.ingest.crosswalk' settings)
-# Format is 'mets.dspaceAIP.ingest.crosswalk.<mdType> = <DSpace-crosswalk-name>'
-mets.dspaceAIP.ingest.crosswalk.DSpaceDepositLicense = NULLSTREAM
-mets.dspaceAIP.ingest.crosswalk.CreativeCommonsRDF = NULLSTREAM
-mets.dspaceAIP.ingest.crosswalk.CreativeCommonsText = NULLSTREAM
-
-# Create EPerson if necessary for Submitter when ingesting AIP (default=false)
-# (by default, EPerson creation is already handled by 'DSPACE-ROLES' Crosswalk)
-#mets.dspaceAIP.ingest.createSubmitter = false
-
-## AIP-specific Disseminator settings
-# These settings allow you to customize which metadata formats are exported in AIPs
-
-# Technical metadata in AIP (exported to METS <techMD> section)
-# Format is <label-for-METS>:<DSpace-crosswalk-name> [, ...] (label is optional)
-# If unspecfied, defaults to "PREMIS"
-aip.disseminate.techMD = PREMIS, DSPACE-ROLES
-
-# Source metadata in AIP (exported to METS <sourceMD> section)
-# Format is <label-for-METS>:<DSpace-crosswalk-name> [, ...] (label is optional)
-# If unspecfied, defaults to "AIP-TECHMD"
-aip.disseminate.sourceMD = AIP-TECHMD
-
-# Preservation metadata in AIP (exported to METS <digipovMD> section)
-# Format is <label-for-METS>:<DSpace-crosswalk-name> [, ...] (label is optional)
-# If unspecified, defaults to nothing in <digiprovMD> section
-#aip.disseminate.digiprovMD =
-
-# Rights metadata in AIP (exported to METS <rightsMD> section)
-# Format is <label-for-METS>:<DSpace-crosswalk-name> [, ...] (label is optional)
-# If unspecified, default to adding all Licenses (CC and Deposit licenses),
-# as well as METSRights information
-aip.disseminate.rightsMD = DSpaceDepositLicense:DSPACE_DEPLICENSE, \
-    CreativeCommonsRDF:DSPACE_CCRDF, CreativeCommonsText:DSPACE_CCTEXT, METSRIGHTS
-
-# Descriptive metadata in AIP (exported to METS <dmdSec> section)
-# Format is <label-for-METS>:<DSpace-crosswalk-name> [, ...] (label is optional)
-# If unspecfied, defaults to "MODS, DIM"
-aip.disseminate.dmd = MODS, DIM
-
-
-#### Event System Configuration ####
-
-# default synchronous dispatcher (same behavior as traditional DSpace)
-event.dispatcher.default.class = org.dspace.event.BasicDispatcher
-
-#
-# uncomment below and comment out original property to enable the legacy lucene indexing
-# event.dispatcher.default.consumers = versioning, search, browse, eperson, harvester
-#
-# add the browse consumer if you want to switch back to the DBMS Browse DAOs implementation
-# as the SOLR implementation rely on the discovery consumer
-#
-# event.dispatcher.default.consumers = versioning, browse, discovery, eperson, harvester
-#
-# Add doi here if you are using org.dspace.identifier.DOIIdentifierProvider to generate DOIs.
-# Adding doi here makes DSpace send metadata updates to your doi registration agency.
-# Add rdf here, if you are using dspace-rdf to export your repository content as RDF.
-event.dispatcher.default.consumers = versioning, discovery, eperson, harvester, eudatreplication, xoai, bitstream
-
-# The noindex dispatcher will not create search or browse indexes (useful for batch item imports)
-event.dispatcher.noindex.class = org.dspace.event.BasicDispatcher
-event.dispatcher.noindex.consumers = eperson
-
-# consumer to maintain the search index
-event.consumer.search.class = org.dspace.search.SearchConsumer
-event.consumer.search.filters = Community|Collection|Item|Bundle+Add|Create|Modify|Modify_Metadata|Delete|Remove
-
-# consumer to maintain the discovery index
-event.consumer.discovery.class = org.dspace.discovery.IndexEventConsumer
-event.consumer.discovery.filters = Community|Collection|Item|Bundle+Add|Create|Modify|Modify_Metadata|Delete|Remove
-
-# consumer to maintain the browse index
-event.consumer.browse.class = org.dspace.browse.BrowseConsumer
-event.consumer.browse.filters = Community|Collection|Item|Bundle+Add|Create|Modify|Modify_Metadata|Delete|Remove
-
-# consumer related to EPerson changes
-event.consumer.eperson.class = org.dspace.eperson.EPersonConsumer
-event.consumer.eperson.filters = EPerson+Create
-
-# consumer to clean up harvesting data
-event.consumer.harvester.class = org.dspace.harvest.HarvestConsumer
-event.consumer.harvester.filters = Item+Delete
-
-# consumer to update metadata of DOIs
-event.consumer.doi.class = org.dspace.identifier.doi.DOIConsumer
-event.consumer.doi.filters = Item+Modify_Metadata
-
-# consumer to update the triplestore of dspace-rdf
-event.consumer.rdf.class = org.dspace.rdf.RDFConsumer
-event.consumer.rdf.filters = Community|Collection|Item|Bundle|Bitstream|Site+Add|Create|Modify|Modify_Metadata|Delete|Remove
-
-# test consumer for debugging and monitoring
-#event.consumer.test.class = org.dspace.event.TestConsumer
-#event.consumer.test.filters = All+All
-
-# consumer to maintain versions
-event.consumer.versioning.class = org.dspace.versioning.VersioningConsumer
-event.consumer.versioning.filters = Item+Install
-
-# authority consumer
-event.consumer.authority.class = org.dspace.authority.indexer.AuthorityConsumer
-event.consumer.authority.filters = Item+Modify|Modify_Metadata
-
-# consumer for eudatreplication
-event.consumer.eudatreplication.class = cz.cuni.mff.ufal.dspace.b2safe.ItemModifyConsumer
-event.consumer.eudatreplication.filters = Community|Collection|Item+Create|Modify
-
-# consumer to maintain the oai index
-event.consumer.xoai.class = cz.cuni.mff.ufal.event.OAIIndexEventConsumer
-event.consumer.xoai.filters = Community|Collection|Item|Bundle|Bitstream+Add|Create|Modify|Modify_Metadata|Delete|Remove
-
-# consumer processing bitstreams
-event.consumer.bitstream.class = cz.cuni.mff.ufal.curation.ProcessBitstreams
-event.consumer.bitstream.filters = Bitstream+Add|Create|Delete|Remove
-
-# ...set to true to enable testConsumer messages to standard output
-#testConsumer.verbose = true
-
-#### Embargo Settings ####
-# DC metadata field to hold the user-supplied embargo terms
-embargo.field.terms = local.embargo.termslift
-
-# DC metadata field to hold computed "lift date" of embargo
-embargo.field.lift = local.embargo.termslift
-
-# string in terms field to indicate indefinite embargo
-embargo.terms.open = forever
-
-# implementation of embargo setter plugin - replace with local implementation if applicable
-plugin.single.org.dspace.embargo.EmbargoSetter = org.dspace.embargo.DefaultEmbargoSetter
-
-# implementation of embargo lifter plugin - - replace with local implementation if applicable
-plugin.single.org.dspace.embargo.EmbargoLifter = org.dspace.embargo.DefaultEmbargoLifter
-
-#### Checksum Checker Settings ####
-# Default dispatcher in case none specified
-plugin.single.org.dspace.checker.BitstreamDispatcher=org.dspace.checker.SimpleDispatcher
-
-# check history retention
-checker.retention.default=10y
-checker.retention.CHECKSUM_MATCH=8w
-
-
-### Item export and download settings ###
-# The directory where the exports will be done and compressed
-org.dspace.app.itemexport.work.dir = ${dspace.dir}/exports
-
-# The directory where the compressed files will reside and be read by the downloader
-org.dspace.app.itemexport.download.dir = ${dspace.dir}/exports/download
-
-# The length of time in hours each archive should live for. When new archives are
-# created this entry is used to delete old ones
-org.dspace.app.itemexport.life.span.hours = 48
-
-# The maximum size in Megabytes the export should be.  This is enforced before the
-# compression.  Each bitstream's size in each item being exported is added up, if their
-# cummulative sizes are more than this entry the export is not kicked off
-org.dspace.app.itemexport.max.size = 200
-
-### Batch Item import settings ###
-# The directory where the results of imports will be placed (mapfile, upload file)
-org.dspace.app.batchitemimport.work.dir = ${dspace.dir}/imports
-
-# Enable performance optimization for select-collection-step collection query
-# Enable when having 
-# a large number of collections and no Shibboleth or LDAP authentication.
-# default = false, (disabled)
-#org.dspace.content.Collection.findAuthorizedPerformanceOptimize = true
-
-# For backwards compatibility, the subscription emails by default include any modified items
-# uncomment the following entry for only new items to be emailed
-# eperson.subscription.onlynew = true
-
-
-# Identifier providers.
-# Following are configuration values for the EZID DOI provider, with appropriate
-# values for testing.  Replace the values with your assigned "shoulder" and
-# credentials.
-#identifier.doi.ezid.shoulder = 10.5072/FK2/
-#identifier.doi.ezid.user = apitest
-#identifier.doi.ezid.password = apitest
-# A default publisher, for Items not previously published.
-# (If generateDataciteXML bean property is enabled. Set default publisher in the
-# XSL file configured by: crosswalk.dissemination.DataCite.stylesheet file.)
-#identifier.doi.ezid.publisher = a publisher
-
-
-#---------------------------------------------------------------#
-#--------------JSPUI & XMLUI CONFIGURATIONS---------------------#
-#---------------------------------------------------------------#
-# These configs are used by both JSP and XML User Interfaces,   #
-# except where explicitly stated otherwise.                     #
-#---------------------------------------------------------------#
-
-# Determine if super administrators (those whom are in the Administrators group)
-# can login as another user from the "edit eperson" page. This is useful for
-# debugging problems in a running dspace instance, especially in the workflow
-# process. The default value is false, i.e. no one may assume the login of another user.
-webui.user.assumelogin = true
-
-# whether to display the contents of the licence bundle (often just the deposit
-# licence in standard DSpace installation
-webui.licence_bundle.show = false
-
-##### Hide Item Metadata Fields  #####
-# Fields named here are hidden in the following places UNLESS the
-# logged-in user is an Administrator:
-#  1. XMLUI metadata XML view, and Item splash pages (long and short views).
-#  2. JSPUI Item splash pages
-# To designate a field as hidden, add a property here in the form:
-#    metadata.hide.SCHEMA.ELEMENT.QUALIFIER = true
-#
-# This default configuration hides the dc.description.provenance field,
-# since that usually contains email addresses which ought to be kept
-# private and is mainly of interest to administrators:
-metadata.hide.dc.description.provenance = true
-metadata.hide.local.submission.note = submitter
-
-##### Settings for Submission Process #####
-
-# Should the submit UI block submissions marked as theses?
-webui.submit.blocktheses = false
-
-# Whether or not we REQUIRE that a file be uploaded
-# during the 'Upload' step in the submission process
-# Defaults to true; If set to 'false', submitter has option to skip upload
-webui.submit.upload.required = false
-
-# If the browser supports it, JSPUI uses html5 File API to enhance file upload.
-# If this property is set to false the enhanced file upload is not used even
-# if the browser would support it.
-#webui.submit.upload.html5 = true
-
-# Whether or not to use the 'advanced' form of the access step.
-# Defaults to false, ie the simple form is used.
-#webui.submission.restrictstep.enableAdvancedForm = false
-
-# Special Group for UI: all the groups nested inside this group
-# will be loaded in the multiple select list of the RestrictStep
-#webui.submission.restrictstep.groups = SubmissionAdmin
-
-#### Creative Commons settings ######
-
-# The url to the web service API
-cc.api.rooturl = http://api.creativecommons.org/rest/1.5
-
-# Metadata field to hold CC license URI of selected license
-# NB: DSpace (both JSPUI and XMLUI) presentation code expects 'dc.rights.uri' to hold CC data. If you change
-# this to another field, please consult documentation on how to update UI configuration 
-cc.license.uri = dc.rights.uri
-
-# Metadata field to hold CC license name of selected license (if defined)
-# NB: DSpace (both JSPUI and XMLUI) presentation code expects 'dc.rights' to hold CC data. If you change
-# this to another field, please consult documentation on how to update UI configuration
-cc.license.name = dc.rights
-
-# Assign license name during web submission
-cc.submit.setname = true
-
-# Store license bitstream (RDF license text) during web submission
-cc.submit.addbitstream = true
-
-# ONLY JSPUI, enable Creative Commons admin 
-webui.submit.enable-cc = false
-
-# A list of license classes that should be excluded from selection process
-# class names - comma-separated list -  must exactly match what service returns.
-# At time of implementation, these are:
-# publicdomain - "Public Domain"
-# standard - "Creative Commons"
-# recombo - "Sampling"
-# zero - "CC0"
-# mark - "Public Domain Mark"
-cc.license.classfilter = recombo, mark
-
-# Jurisdiction of the creative commons license -- is it ported or not?
-# Use the key from the url seen in the response from the api call,
-# http://api.creativecommons.org/rest/1.5/support/jurisdictions
-# Commented out means the license is unported.
-# (e.g. nz = New Zealand, uk = England and Wales, jp = Japan)
-cc.license.jurisdiction = us
-
-# Locale for CC dialogs
-# A locale in the form language or language-country.
-# If no default locale is defined the CC default locale will be used
-cc.license.locale = en
-
-
-##### Settings for Thumbnail creation #####
-
-# whether to display thumbnails on browse and search results pages (1.2+)
-# If you have customised the Browse columnlist, then you must also
-# include a 'thumbnail' column in your configuration (1.5+)
-# (This configuration is not used by XMLUI.  To show thumbnails in the
-#  XMLUI, you just need to create a theme which displays them)
-webui.browse.thumbnail.show = false
-
-# max dimensions of the browse/search thumbs. Must be <= thumbnail.maxwidth
-# and thumbnail.maxheight. Only need to be set if required to be smaller than
-# dimension of thumbnails generated by mediafilter (1.2+)
-#webui.browse.thumbnail.maxheight = 80
-#webui.browse.thumbnail.maxwidth = 80
-
-# whether to display the thumb against each bitstream (1.2+)
-# (This configuration is not used by XMLUI.  To show thumbnails in the
-#  XMLUI, you just need to create a theme which displays them)
-webui.item.thumbnail.show = true
-
-# where should clicking on a thumbnail from browse/search take the user
-# Only values currently supported are "item" and "bitstream"
-#webui.browse.thumbnail.linkbehaviour = item
-
-# maximum width and height of generated thumbnails
-thumbnail.maxwidth  = 80
-thumbnail.maxheight = 80
-
-# Blur before scaling.  A little blur before scaling does wonders for keeping
-# moire in check.
-thumbnail.blurring = true
-
-# High quality scaling option.  Setting to true can dramatically increase
-# image quality, but it takes longer to create thumbnails.
-thumbnail.hqscaling = true
-
-
-#### Settings for Item Preview ####
-
-webui.preview.enabled = false
-# max dimensions of the preview image
-webui.preview.maxwidth = 600
-webui.preview.maxheight = 600
-
-# Blur before scaling.  A little blur before scaling does wonders for keeping
-# moire in check.
-webui.preview.blurring = true
-
-# High quality scaling option.  Setting to true can dramatically increase
-# image quality, but it will take much longer to create previews.
-webui.preview.hqscaling = true
-
-# the brand text
-webui.preview.brand = My Institution Name
-
-# an abbreviated form of the above text, this will be used
-# when the preview image cannot fit the normal text
-webui.preview.brand.abbrev = MyOrg
-
-# the height of the brand
-webui.preview.brand.height = 20
-
-# font settings for the brand text
-webui.preview.brand.font = SansSerif
-webui.preview.brand.fontpoint = 12
-#webui.preview.dc = rights
-
-
-##### Settings for item count (strength) information ####
-
-# whether to display collection and community strengths
-# (Since DSpace 4.0, this config option is used by XMLUI, too.
-# XMLUI only makes strengths available to themes if this is set to true! 
-# To show strengths in the XMLUI, you also need to create a theme which displays them)
-webui.strengths.show = false
-
-# if showing strengths, should they be counted in real time or
-# fetched from cache?
-#
-# Counts fetched in real time will perform an actual count of the
-# database contents every time a page with this feature is requested,
-# which will not scale.  The default behaviour is to use a cache (see 
-# ItemCounter configuration)
-#
-# The default is to use a cache
-#
-# webui.strengths.cache = true
-
-
-###### ItemCounter Configuration ######
-#
-# Define the DAO class to use. This must correspond to your choice of
-# storage for the browse system (RDBMS: PostgreSQL or Oracle, Solr). 
-# By default, since DSpace 4.0, the Solr implementation is used.
-#
-# Only if you use a DBMS implementation and want to use the cache 
-# (recommended!), you must run the following command periodically 
-# to update the count:
-#
-# [dspace]/bin/itemcounter	(NOT required if you use the Solr implementation)
-#
-#
-# PostgreSQL:
-# ItemCountDAO.class = org.dspace.browse.ItemCountDAOPostgres
-#
-# Oracle:
-# ItemCountDAO.class = org.dspace.browse.ItemCountDAOOracle
-#
-# Solr:
-# ItemCountDAO.class = org.dspace.browse.ItemCountDAOSolr
-
-
-###### Browse Configuration ######
-#
-# Define the DAO class to use this must meet your storage choice for 
-# the browse system (RDBMS: PostgreSQL or Oracle, Solr). 
-# By default, since DSpace 4.0, the Solr implementation is used
-#
-# PostgreSQL:
-# browseDAO.class = org.dspace.browse.BrowseDAOPostgres
-# browseCreateDAO.class = org.dspace.browse.BrowseCreateDAOPostgres
-#
-# Oracle:
-# browseDAO.class = org.dspace.browse.BrowseDAOOracle
-# browseCreateDAO.class = org.dspace.browse.BrowseCreateDAOOracle
-#
-# Solr:
-# browseDAO.class = org.dspace.browse.SolrBrowseDAO
-# browseCreateDAO.class = org.dspace.browse.SolrBrowseCreateDAO
-
-
-
-#
-# Use this to configure the browse indices. Each entry will receive a link in the
-# navigation. Each entry can be configured in one of two ways. The first is:
-#
-# webui.browse.index.<n> = <index name> : metadata : \
-#                                                       <schema prefix>.<element>[.<qualifier>|.*] : \
-#                                                       (date | title | text) : (asc | desc)
-#
-# This form represent a unique index of metadata values from the item.
-#
-# (date | title | text | <other>) refers to the datatype of the field.
-#                       date: the index type will be treated as a date object
-#                       title: the index type will be treated like a title, which will include
-#                                       a link to the item page
-#                       text: the index type will be treated as plain text.  If single mode is
-#                                       specified then this will link to the full mode list
-#           <other>: any other datatype will be treated the same as 'text', although
-#                   it will apply any custom ordering normalisation configured below
-#
-#   The final part of the configuration is optional, and specifies the default ordering
-#   for the index - whether it is ASCending (the default, and best for text indexes), or
-#   DESCending (useful for dates - ie. most recent submissions)
-#
-#   NOTE: the text to render the index will use the <index name> parameter to select
-#   the message key from Messages.properties using a key of the form:
-#
-# browse.type.metadata.<index name>
-#
-# The other form is for indexes of the items themselves, ie. each entry will be displayed
-# according to the configuration of by webui.itemlist.columns:
-#
-# webui.browse.index.<n> = <index name> : item : <sort option name> : (asc | desc)
-#
-# sort option name: this is the sorting to be applied to the display. It must match the
-#                   name given to one of the webui.itemlist.sort-option entries given below.
-#
-#   The final part of the configuration is optional, and specifies the default ordering
-#   for the index - whether it is ASCending (the default, and best for text indexes), or
-#   DESCending (useful for dates - ie. most recent submissions)
-
-#   NOTE: the text to render the index will use the <sort option name> parameter to select
-#   the message key from Messages.properties (for JSPUI) using a key of the form:
-#
-# browse.type.item.<sort option name>
-#
-# Note: the index numbers <n> must start from 1 and increment continuously by 1
-# thereafter.  Deviation from this will cause an error during install or
-# configuration update
-#
-# For compatibility with previous versions:
-#
-webui.browse.index.1 = dateissued:item:dateissued
-webui.browse.index.2 = author:metadata:dc.contributor.*,dc.creator:text
-webui.browse.index.3 = title:item:title
-webui.browse.index.4 = subject:metadata:dc.subject.*:text
-webui.browse.index.5 = publisher:metadata:dc.publisher:text
-webui.browse.index.6 = language:metadata:dc.language.iso:iso_lang
-webui.browse.index.7 = type:metadata:dc.type:text
-webui.browse.index.8 = rights:metadata:dc.rights.label:text
-
-## example of authority-controlled browse category - see authority control config
-#webui.browse.index.5 = lcAuthor:metadataAuthority:dc.contributor.author:authority
-
-# Enable/Disable tag cloud in browsing.
-# webui.browse.index.tagcloud.<n> = true | false
-# where n is the index number from the above options
-# Default value is false. If no option exists for a specific index, it is assumed to be false.
-# Changes to this option do NOT require re-indexing of discovery.
-#
-#webui.browse.index.tagcloud.4 = true
-
-# Set the options for what can be sorted by
-#
-# Sort options will be available when browsing a list of items (i.e. an 'item' browse,
-# or search results).  You can define an arbitrary number of fields
-# to sort on, irrespective of which fields you display using webui.itemlist.columns
-#
-# the format is:
-#
-# webui.itemlist.sort-option.<n> = <option name> : \
-#                                                                       <schema prefix>.<element>[.<qualifier>|.*] : \
-#                                                                       (date | text | ...) : (show | hide)
-#
-# This is defined much the same as above.  The parameter after the metadata
-# just lets the sorter know which normalisation to use - standard normalisations are title,
-# text or date - however additional normalisations can be defined using the PluginManager.
-#
-# The final parts of the configuration is optional -  whether to SHOW (the default) or
-# HIDE the option from the sorting controls in the user interface. This can be useful if
-# you need to define a specific date sort for use by the recent items lists,
-# but otherwise don't want users to choose that option.
-#
-webui.itemlist.sort-option.1 = title:dc.title:title
-webui.itemlist.sort-option.2 = dateissued:dc.date.issued:date
-webui.itemlist.sort-option.3 = dateaccessioned:dc.date.accessioned:date
-
-# By default, the display of metadata in the browse indexes is case sensitive
-# So, you will get separate entries for the terms
-#
-#   Olive oil
-#   olive oil
-#
-# However, clicking through from either of these will result in the same set of items
-# (ie. any item that contains either representation in the correct field).
-#
-# Uncommenting the option below will make the metadata items case-insensitive. This will
-# result in a single entry in the example above. However the value displayed may be either 'Olive oil'
-# or 'olive oil' - depending on what representation was present in the first item indexed.
-#
-# If you care about the display of the metadata in the browse index - well, you'll have to go and
-# fix the metadata in your items.
-#
-# webui.browse.metadata.case-insensitive = true
-
-# Set the options for the size (number of characters) of the fields stored in the database.
-#
-# The default is 0, which is unlimited size for fields holding indexed data.  Some
-# database implementations (e.g. Oracle) will enforce their own limit on this field
-# size. Reducing the field size will decrease the potential size of your database and
-# increase the speed of the browse, but it will also increase the chance of
-# mis-ordering of similar fields.  Below are commented out, but proposed values for
-# reasonably performance versus result quality
-#
-# Size of field for the browse value (this will affect display, and value sorting)
-#
-# webui.browse.value_columns.max = 500
-
-# Size of field for hidden sort columns (this will affect only sorting, not display)
-#
-# webui.browse.sort_columns.max = 200
-
-# Omission mark to place after truncated strings in display.  The default is "..."
-#
-# webui.browse.value_columns.omission_mark = ...
-
-# Set the options for how the indexes are sorted
-#
-# All sorts of normalisations are carried out by the OrderFormatDelegate.
-# The plugin manager can be used to specify your own delegates for each datatype.
-#
-# The default datatypes (and delegates) are:
-#
-# author = org.dspace.sort.OrderFormatAuthor
-# title  = org.dspace.sort.OrderFormatTitle
-# text   = org.dspace.sort.OrderFormatText
-#
-# If you redefine a default datatype here, the configuration will be used in preference
-# to the default, however, if you do not explicitly redefine a datatype, then the
-# default will still be used in addition to the datatypes you do specify.
-#
-# As of 1.5.2, the multi-lingual MARC 21 title ordering is configured as default.
-# To use the previous title ordering, comment out the configuration below
-
-plugin.named.org.dspace.sort.OrderFormatDelegate= \
-        org.dspace.sort.OrderFormatTitleMarc21=title
-
-#UFAL iso_lang to human readable in browse
-plugin.named.org.dspace.sort.OrderFormatDelegate= \
-         cz.cuni.mff.ufal.dspace.sort.OrderFormatIsoLang=iso_lang       
-
-## Set the options for how authors are displayed in the browse listing
-
-# Define which field is the author/editor etc listing.  This should be listed in the
-# field webui.itemlist.columns, otherwise it will have no effect.
-# This cannot be a field already marked out as a title or a date, as this
-# will also have no effect.  This is used in conjunction with the
-# webui.browse.author-limit field below, to truncate author lists.  For
-# configuring links to author publication lists use webui.browse.link below.
-# (This setting is not used by the XMLUI as it is controlled by your theme)
-#
-# webui.browse.author-field = dc.contributor.*
-
-# define how many authors to display before truncating and completing with "et al"
-# (or language pack specific alternative)
-#
-# Use -1 for unlimited (which is what will be used if this option
-# is omitted)
-#
-# webui.browse.author-limit = 3
-
-# which fields should link to other browse listings.  This should associated
-# the name of one of the above browse indices with a metadata field listed
-# in <webui.itemlist.columns> above.  The form is:
-#
-# webui.browse.link.<n> = <index name>:<display column metadata>
-#
-# Note that cross linking will only work for fields other than title.
-#
-# The effect this has is to create links to browse views for the item clicked on.
-# If it is a "single" type, it will link to a view of all the items which share
-# that metadata element in common (i.e. all the papers by a single author).  If
-# it is a "full" type, it will link to a view of the standard full browse page,
-# starting with the value of the link clicked on.
-# (This setting is not used by the XMLUI, as links are controlled by your theme)
-#
-# The default below defines the authors to link to other publications by that author
-#
-webui.browse.link.1 = author:dc.contributor.*
-
-### Render scientific formulas symbols in view/browse
-# Use MathJax to render properly encoded text formulas to be visual for people
-#webui.browse.render-scientific-formulas = true
-
-#### Display browse frequencies
-#
-# webui.browse.metadata.show-freq.<n> = true | false
-# where n is the same index as in webui.browse.index.<n> configurations
-#
-# For the browse indexes that this property is omitted, it is assumed as true
-# please note that only a few overhead is required to compute frequencies when
-# DBMS BrowseDAO is used and not overhead at all when SOLRBrowseDAO is used
-# webui.browse.metadata.show-freq.1 = false
-# webui.browse.metadata.show-freq.2 = false
-# webui.browse.metadata.show-freq.3 = false
-# webui.browse.metadata.show-freq.4 = true
-
-#### Additional configuration for Recent Submissions code ####
-
-# the sort option name (from webui.itemlist.sort-option above) to use for
-# displaying recent submissions.  (this
-# is used by the Recent Submissions system and any other time based
-# browse query such as FeedServlet)
-#
-recent.submissions.sort-option = dateaccessioned
-
-# how many recent submissions should be displayed at any one time
-# Set to 0 since discovery uses a separate configuration for this
-recent.submissions.count = 0
-
-# name of the browse index to display collection's items.
-# You can set a "item" type of browse index only.                      
-#   default = title
-#webui.collectionhome.browse-name = title
-
-# how mamy items should be displayed per page in collection home page
-#   default = 20
-#webui.collectionhome.perpage = 20
-
-# whether does use "dateaccessioned" as a sort option
-#   If true and the sort option "dateaccessioned" exists, use "dateaccessioned" as a sort option.
-#   Otherwise use the sort option pertaining the specified browse index.
-#   default = true
-#webui.collectionhome.use.dateaccessioned = true
-
-# tell the community and collection pages that we are using the Recent
-# Submissions code
-#plugin.sequence.org.dspace.plugin.SiteHomeProcessor = \
-#        org.dspace.app.webui.components.TopCommunitiesSiteProcessor,\
-#        org.dspace.app.webui.components.RecentSiteSubmissions
-
-#plugin.sequence.org.dspace.plugin.CommunityHomeProcessor = \
-#        org.dspace.app.webui.components.RecentCommunitySubmissions
-
-#plugin.sequence.org.dspace.plugin.CollectionHomeProcessor = \
-#        org.dspace.app.webui.components.RecentCollectionSubmissions,\
-#        org.dspace.app.webui.components.CollectionItemList
-
-#### JSPUI Discovery (extra Discovery setting that applies only to JSPUI) ####
-# uncomment the following configuration if you want to restore the legacy Lucene
-# search provider with JSPUI (be sure to re-enable also the search consumer)
-# plugin.single.org.dspace.app.webui.search.SearchRequestProcessor = \
-#		org.dspace.app.webui.search.LuceneSearchRequestProcessor
-#
-# default since DSpace 4.0 is to use the Discovery search provider
-plugin.single.org.dspace.app.webui.search.SearchRequestProcessor = \
-		org.dspace.app.webui.discovery.DiscoverySearchRequestProcessor
-
-#### XMLUI Discovery (extra Discovery setting that applies only to XMLUI) ####
-# uncomment the following configuration if you want to restore the legacy Lucene
-# search provider with XMLUI (be sure to re-enable also the search consumer)
-# plugin.single.org.dspace.app.xmlui.aspect.administrative.mapper.SearchRequestProcessor = \
-#		org.dspace.app.xmlui.aspect.administrative.mapper.LuceneSearchRequestProcessor
-#
-# default since DSpace 4.0 is to use the Discovery search provider
-plugin.single.org.dspace.app.xmlui.aspect.administrative.mapper.SearchRequestProcessor = \
-		org.dspace.app.xmlui.aspect.administrative.mapper.DiscoverySearchRequestProcessor
-
-#### Sidebar Facets ####
-# to show facets on the site home page, community, collection
-# comment out the following lines if you disable Discovery or don't want
-# to show facets on side bars
-# TagCloudProcessor is responsible for displaying a tag-cloud facet on the 
-# site home page, community or collection home page
-plugin.sequence.org.dspace.plugin.CommunityHomeProcessor = \
-        org.dspace.app.webui.components.RecentCommunitySubmissions,\
-        org.dspace.app.webui.discovery.SideBarFacetProcessor
-#        org.dspace.app.webui.tagcloud.TagCloudProcessor
-
-plugin.sequence.org.dspace.plugin.CollectionHomeProcessor = \
-        org.dspace.app.webui.components.CollectionItemList,\
-        org.dspace.app.webui.discovery.SideBarFacetProcessor
-#        org.dspace.app.webui.tagcloud.TagCloudProcessor
-#        org.dspace.app.webui.components.RecentCollectionSubmissions,\
-
-plugin.sequence.org.dspace.plugin.SiteHomeProcessor = \
-        org.dspace.app.webui.components.TopCommunitiesSiteProcessor,\
-        org.dspace.app.webui.components.RecentSiteSubmissions,\
-        org.dspace.app.webui.discovery.SideBarFacetProcessor
-#        org.dspace.app.webui.tagcloud.TagCloudProcessor
-
-#### JSON JSPUI Request Handler ####
-# define any JSON handler here
-#
-# comment out this line if you disable Discovery
-plugin.named.org.dspace.app.webui.json.JSONRequest = \
-	org.dspace.app.webui.discovery.DiscoveryJSONRequest = discovery,\
-	org.dspace.app.webui.json.SubmissionLookupJSONRequest = submissionLookup,\
-	org.dspace.app.webui.json.UploadProgressJSON = uploadProgress,\
-	org.dspace.app.webui.handle.HandleJSONResolver = hdlresolver,\
-	org.dspace.app.webui.json.CreativeCommonsJSONRequest = creativecommons
-
-### i18n -  Locales / Language ####
-# Default Locale
-# A Locale in the form country or country_language or country_language_variant
-# if no default locale is defined the server default locale will be used.
-default.locale = en
-
-# All the Locales, that are supported by this instance of DSpace
-# A comma-separated list of Locales. All types of Locales country, country_language, country_language_variant
-# Note that the appropriate file are present, especially that all the Messages_x.properties are there
-# may be used, e. g: webui.supported.locales = en, de
-webui.supported.locales = ${supported.locales}
-
-#### Submission License substitution variables ####
-# it is possible include contextual information in the submission license using substitution variables
-# the text substitution is driven by a plugin implementation
-plugin.named.org.dspace.content.license.LicenseArgumentFormatter = \
-	org.dspace.content.license.SimpleDSpaceObjectLicenseFormatter = collection, \
-	org.dspace.content.license.SimpleDSpaceObjectLicenseFormatter = item, \
-	org.dspace.content.license.SimpleDSpaceObjectLicenseFormatter = eperson
-
-#### Syndication Feed (RSS) Settings ######
-
-# enable syndication feeds - links display on community and collection home pages
-# (This setting is not used by XMLUI, as you enable feeds in your theme)
-webui.feed.enable = true
-# number of DSpace items per feed (the most recent submissions)
-webui.feed.items = 10
-# maximum number of feeds in memory cache
-# value of 0 will disable caching
-webui.feed.cache.size = 100
-# number of hours to keep cached feeds before checking currency
-# value of 0 will force a check with each request
-webui.feed.cache.age = 24
-# which syndication formats to offer
-# use one or more (comma-separated) values from list:
-# rss_0.90, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0
-webui.feed.formats = rss_1.0,rss_2.0,atom_1.0
-# URLs returned by the feed will point at the global handle server (e.g. http://hdl.handle.net/123456789/1)
-# Set to true to use local server URLs (i.e. http://myserver.myorg/handle/123456789/1)
-webui.feed.localresolve = false
-
-# Customize each single-value field displayed in the
-# feed information for each item.  Each of
-# the below fields takes a *single* metadata field
-#
-# The form is <schema prefix>.<element>[.<qualifier>|.*]
-webui.feed.item.title = dc.title
-webui.feed.item.date = dc.date.issued
-
-# Customise the metadata fields to show in the feed for each item's description.
-# Elements will be displayed in the order that they are specified here.
-#
-# The form is <schema prefix>.<element>[.<qualifier>|.*][(date)], ...
-#
-# Similar to the item display UI, the name of the field for display
-# in the feed will be drawn from the current UI dictionary,
-# using the key:
-# "metadata.<field>"
-#
-# e.g.   "metadata.dc.title"
-#        "metadata.dc.contributor.author"
-#        "metadata.dc.date.issued"
-webui.feed.item.description = dc.title, dc.contributor.author, \
-                                                          dc.contributor.editor, dc.description.abstract, \
-                                                          dc.description
-# name of field to use for authors (Atom only) - repeatable
-webui.feed.item.author = dc.contributor.author
-
-# Customize the extra namespaced DC elements added to the item (RSS) or entry
-# (Atom) element.  These let you include individual metadata values in a
-# structured format for easy extraction by the recipient, instead of (or in
-# addition to) appending these values to the Description field.
-## dc:creator value(s)
-#webui.feed.item.dc.creator = dc.contributor.author
-## dc:date value (may be contradicted by webui.feed.item.date)
-#webui.feed.item.dc.date = dc.date.issued
-## dc:description (e.g. for a distinct field that is ONLY the abstract)
-#webui.feed.item.dc.description = dc.description.abstract
-
-# Customize the image icon included with the site-wide feeds:
-# Must be an absolute URL, e.g.
-## webui.feed.logo.url = ${dspace.url}/themes/mysite/images/mysite-logo.png
-
-# iTunes Podcast Enhanced RSS Feed Properties
-# Add all the communities / collections, separated by commas (no spaces) that should
-# have the iTunes podcast metadata added to their RSS feed.
-# Default: Disabled, No collections or communities have iTunes Podcast enhanced metadata in their feed.
-# webui.feed.podcast.collections =123456789/2,123456789/3 
-# webui.feed.podcast.communities =123456789/1
-
-# Which MIMETypes of Bitstreams would you like to have podcastable in your item?
-# Separate multiple entries with commas.
-#webui.feed.podcast.mimetypes=audio/x-mpeg
-
-# For the iTunes Podcast Feed, if you would like to specify an external media file,
-# not on your DSpace server to be enclosed within the entry for each item, 
-# specify which metadata field will hold the URI to the external media file. 
-# This is useful if you store the metadata in DSpace, and a separate streaming server to host the media.
-# Default: dc.source.uri
-#webui.feed.podcast.sourceuri = dc.source.uri
-
-#### OpenSearch Settings ####
-# NB: for result data formatting, OpenSearch uses Syndication Feed Settings
-# so even if Syndication Feeds are not enabled, they must be configured
-# enable open search
-websvc.opensearch.enable = false
-# context for html request URLs - change only for non-standard servlet mapping
-websvc.opensearch.uicontext = simple-search
-# context for RSS/Atom request URLs - change only for non-standard servlet mapping
-websvc.opensearch.svccontext = open-search/
-# present autodiscovery link in every page head
-websvc.opensearch.autolink = true
-# number of hours to retain results before recalculating
-websvc.opensearch.validity = 48
-# short name used in browsers for search service
-# should be 16 or fewer characters
-websvc.opensearch.shortname = ${lr.dspace.name.short}
-# longer (up to 48 characters) name
-websvc.opensearch.longname = ${dspace.name}
-# brief service description
-websvc.opensearch.description = ${dspace.name}
-# location of favicon for service, if any must be 16X16 pixels
-websvc.opensearch.faviconurl = ${dspace.url}/themes/UFALHome/images/favicon.ico
-# sample query - should return results
-websvc.opensearch.samplequery = photosynthesis
-# tags used to describe search service
-websvc.opensearch.tags = IR DSpace
-# result formats offered - use 1 or more comma-separated from: html,atom,rss
-# NB: html is required for autodiscovery in browsers to function,
-# and must be the first in the list if present
-websvc.opensearch.formats = html,atom,rss
-
-
-#### Content Inline Disposition Threshold ####
-#
-# Set the max size of a bitstream that can be served inline
-# Use -1 to force all bitstream to be served inline
-# The 'webui.*' setting is for the JSPUI, and
-# the 'xmlui.*' setting is for the XMLUI
-webui.content_disposition_threshold = 8388608
-xmlui.content_disposition_threshold = 8388608
-
-
-#### Multi-file HTML document/site settings #####
-#
-# When serving up composite HTML items, how deep can the request be for us to
-# serve up a file with the same name?
-#
-# e.g. if we receive a request for "foo/bar/index.html"
-# and we have a bitstream called just "index.html"
-# we will serve up that bitstream for the request if webui.html.max-depth-guess
-# is 2 or greater.  If webui.html.max-depth-guess is 1 or less, we would not
-# serve that bitstream, as the depth of the file is greater.
-#
-# If webui.html.max-depth-guess is zero, the request filename and path must
-# always exactly match the bitstream name.  Default value is 3.
-#
-# The 'webui.*' setting is for the JSPUI, and
-# the 'xmlui.*' setting is for the XMLUI
-#
-# webui.html.max-depth-guess = 3
-# xmlui.html.max-depth-guess = 3
-
-
-#### Sitemap settings #####
-# the directory where the generated sitemaps are stored
-sitemap.dir = ${dspace.dir}/sitemaps
-
-#
-# Comma-separated list of search engine URLs to 'ping' when a new Sitemap has
-# been created.  Include everything except the Sitemap URL itself (which will
-# be URL-encoded and appended to form the actual URL 'pinged').
-#
-sitemap.engineurls = http://www.google.com/webmasters/sitemaps/ping?sitemap=
-
-# Add this to the above parameter if you have an application ID with Yahoo
-# (Replace REPLACE_ME with your application ID)
-# http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=REPLACE_ME&url=
-#
-# No known Sitemap 'ping' URL for MSN/Live search
-
-#####  SHERPA/Romeo Integration Settings ####
-# the SHERPA/RoMEO endpoint
-sherpa.romeo.url = http://www.sherpa.ac.uk/romeo/api29.php
-
-# to disable the sherpa/romeo integration
-# uncomment the follow line 
-# webui.submission.sherparomeo-policy-enabled = false
-
-# please register for a free api access key to get many benefits
-# http://www.sherpa.ac.uk/news/romeoapikeys.htm
-# sherpa.romeo.apikey = YOUR-API-KEY
-
-#####  Authority Control Settings  #####
-#plugin.named.org.dspace.content.authority.ChoiceAuthority = \
-# org.dspace.content.authority.SampleAuthority = Sample, \
-# org.dspace.content.authority.LCNameAuthority = LCNameAuthority, \
-# org.dspace.content.authority.SHERPARoMEOPublisher = SRPublisher, \
-# org.dspace.content.authority.SHERPARoMEOJournalTitle = SRJournalTitle, \
-#  org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
-
-plugin.named.org.dspace.content.authority.ChoiceAuthority = \
-   org.dspace.content.authority.OpenAIREAuthority = OpenAIRE
-#Uncomment to enable ORCID authority control
-#plugin.named.org.dspace.content.authority.ChoiceAuthority = \
-#    org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
-
-## The DCInputAuthority plugin is automatically configured with every
-## value-pairs element in input-forms.xml, namely:
-##   common_identifiers, common_types, common_iso_languages
-##
-## The DSpaceControlledVocabulary plugin is automatically configured
-## with every *.xml file in [dspace]/config/controlled-vocabularies,
-## and creates a plugin instance for each, using base filename as the name.
-## eg: nsi, srsc.
-## Each DSpaceControlledVocabulary plugin comes with three configuration options:
-# vocabulary.plugin._plugin_.hierarchy.store = <true|false>    # default: true
-# vocabulary.plugin._plugin_.hierarchy.suggest = <true|false>  # default: true
-# vocabulary.plugin._plugin_.delimiter = "<string>"            # default: "::"
-##
-## An example using "srsc" can be found later in this section
-
-#plugin.selfnamed.org.dspace.content.authority.ChoiceAuthority = \
-# org.dspace.content.authority.DCInputAuthority, \
-# org.dspace.content.authority.DSpaceControlledVocabulary
-
-## configure LC Names plugin
-#lcname.url = http://alcme.oclc.org/srw/search/lcnaf
-
-##
-## This sets the default lowest confidence level at which a metadata value is included
-## in an authority-controlled browse (and search) index.  It is a symbolic
-## keyword, one of the following values (listed in descending order):
-##   accepted
-##   uncertain
-##   ambiguous
-##   notfound
-##   failed
-##   rejected
-##   novalue
-##   unset
-## See manual or org.dspace.content.authority.Choices source for descriptions.
-authority.minconfidence = ambiguous
-
-# Configuration settings for ORCID based authority control, uncomment the lines below to enable configuration
-#solr.authority.server=${solr.server}/authority
-#choices.plugin.dc.contributor.author = SolrAuthorAuthority
-#choices.presentation.dc.contributor.author = authorLookup
-#authority.controlled.dc.contributor.author = true
-#
-#authority.author.indexer.field.1=dc.contributor.author
-
-## demo: use LC plugin for author
-#choices.plugin.dc.contributor.author =  LCNameAuthority
-#choices.presentation.dc.contributor.author = lookup
-#authority.controlled.dc.contributor.author = true
-##
-## This sets the lowest confidence level at which a metadata value is included
-## in an authority-controlled browse (and search) index.  It is a symbolic
-## keyword from the same set as for the default "authority.minconfidence"
-#authority.minconfidence.dc.contributor.author = accepted
-
-choices.plugin.dc.relation = OpenAIRE
-choices.presentation.dc.relation = suggest
-choices.closed.dc.relation = true
-authority.controlled.dc.relation = true
-
-## demo: subject code autocomplete, using srsc as authority
-## (DSpaceControlledVocabulary plugin must be enabled)
-## Warning: when enabling this feature any controlled vocabulary configuration in the input-forms.xml for the metadata field will be overridden.
-#choices.plugin.dc.subject = srsc
-#choices.presentation.dc.subject = select
-#vocabulary.plugin.srsc.hierarchy.store = true
-#vocabulary.plugin.srsc.hierarchy.suggest = true
-#vocabulary.plugin.srsc.delimiter = "::"
-
-## Demo: publisher name lookup through SHERPA/RoMEO:
-#choices.plugin.dc.publisher = SRPublisher
-#choices.presentation.dc.publisher = suggest
-
-## demo: journal title lookup, with ISSN as authority
-#choices.plugin.dc.title.alternative = SRJournalTitle
-#choices.presentation.dc.title.alternative = suggest
-#authority.controlled.dc.title.alternative = true
-
-## demo: use choice authority (without authority-control) to restrict dc.type on EditItemMetadata page
-#choices.plugin.dc.type = common_types
-#choices.presentation.dc.type = select
-
-## demo: same idea for dc.language.iso
-#choices.plugin.dc.language.iso = common_iso_languages
-#choices.presentation.dc.language.iso = select
-
-# Change number of choices shown in the select in Choices lookup popup
-#xmlui.lookup.select.size = 12
-
-
-#### Ordering of bitstreams ####
-
-## Specify the ordering that bitstreams are listed.
-##
-## Bitstream field to sort on.  Values: sequence_id or name. Default: sequence_id
-webui.bitstream.order.field = bitstream_order
-
-## Direction of sorting order. Values: DESC or ASC. Default: ASC
-#webui.bitstream.order.direction = ASC
-
-
-##### Google Scholar Metadata Configuration #####
-google-metadata.config = ${dspace.dir}/config/crosswalks/google-metadata.properties
-google-metadata.enable = true
-
-#---------------------------------------------------------------#
-#--------------JSPUI SPECIFIC CONFIGURATIONS--------------------#
-#---------------------------------------------------------------#
-# These configs are only used by the JSP User Interface         #
-#---------------------------------------------------------------#
-##### JSPUI Layout #####
-# set this value if you want to use a diffent main template. 
-# The value must match the name of a subfolder of dspace-jspui/src/main/webapp/layout
-# jspui.template.name = 
-
-##### Show community or collection logo in list #####
-# jspui.home-page.logos = true
-# jspui.community-home.logos = true
-# jspui.community-list.logos = true
-
-##### Item Home Processor #####
-
-plugin.sequence.org.dspace.plugin.ItemHomeProcessor = \
-        org.dspace.app.webui.components.VersioningItemHome
-
-##### Upload File settings #####
-
-# Where to temporarily store uploaded files
-upload.temp.dir = ${dspace.dir}/upload
-
-# Maximum size of uploaded files in bytes, negative setting will result in no limit being set
-# 512Mb
-# not in XMLUI - search in cocoon properties instead
-upload.max = 536870912
-
-
-###### Statistical Report Configuration Settings ######
-
-# should the stats be publicly available?  should be set to false if you only
-# want administrators to access the stats, or you do not intend to generate
-# any
-report.public = false
-
-# directory where live reports are stored
-report.dir = ${dspace.dir}/reports/
-
-
-
-###### Web Interface Settings ######
-
-
-# Customise the DC metadata fields to show in the default simple item view.
-#
-# The form is <schema prefix>.<element>[.<qualifier>|.*][(date)|(link)|(nobreakline)], ...
-#
-# For example:
-#    dc.title               = Dublin Core element 'title' (unqualified)
-#    dc.title.alternative   = DC element 'title', qualifier 'alternative'
-#    dc.title.*             = All fields with Dublin Core element 'title'
-#                             (any or no qualifier)
-#    dc.identifier.uri(link) = DC identifier.uri, render as a link
-#    dc.date.issued(date)   = DC date.issued, render as a date
-#    dc.subject(nobreakline)   = DC subject.keyword, rendered as separated values 
-#                               (see also webui.itemdisplay.nobreakline.separator option)
-#    dc.language(inputform)   = If the dc.language is in a controlled vocabulary, then the displayed value will be shown based on the stored value from the value-pairs-name in input forms.
-#			      The input-forms will be loaded based on the session locale. If the displayed value is not found, then the value will be shown as is. 	
-#    "link/date" options can be combined with "nobreakline" option using a space among them i.e "dc.identifier.uri(link nobreakline)"
-#
-# If an item has no value for a particular field, it won't be displayed.
-# The name of the field for display will be drawn from the current UI
-# dictionary, using the key:
-#
-# "metadata.<style>.<field>" or if undefined the key "metadata.<field>"
-#
-# e.g.   "metadata.default.dc.title" or "metadata.default.dc.title"
-#        "metadata.dc.contributor.*" or "metadata.default.dc.contributor.*"
-#        "metadata.dc.date.issued" or "metadata.default.dc.date.issued"
-#
-#webui.itemdisplay.default = dc.title, dc.title.alternative, dc.contributor.*, \
-#                            dc.subject(nobreakline), dc.date.issued(date), dc.publisher, \
-#                            dc.identifier.citation, dc.relation.ispartofseries, \
-#                            dc.description.abstract, dc.description, \
-#                            dc.identifier.govdoc, dc.identifier.uri(link), \
-#                            dc.identifier.isbn, dc.identifier.issn, \
-#                            dc.identifier.ismn, dc.identifier
-#
-# When using "resolver" in webui.itemdisplay to render identifiers as resolvable
-# links, the base URL is taken from <code>webui.resolver.<n>.baseurl</code>
-# where <code>webui.resolver.<n>.urn</code> matches the urn specified in the metadata value.
-# The value is appended to the "baseurl" as is, so the baseurl need to end with slash almost in any case.
-# If no urn is specified in the value it will be displayed as simple text.
-#
-#webui.resolver.1.urn = doi
-#webui.resolver.1.baseurl = http://dx.doi.org/
-#webui.resolver.2.urn = hdl
-#webui.resolver.2.baseurl = http://hdl.handle.net/
-#
-# For the doi and hdl urn defaults values are provided, respectively http://dx.doi.org and
-# http://hdl.handle.net are used.<br>
-#
-# If a metadata value with style: "doi", "handle" or "resolver" matches a URL
-# already, it is simply rendered as a link with no other manipulation.
-
-# If nobreakline option is applied for a field in itemdisplay then the following option defines the separator string.
-# If a non-breaking space is needed before or after the separator, this can be included using &nbsp; 
-# (i.e. webui.itemdisplay.separator = ;&nbsp;)
-# If ommitted, the default separator is ';&nbsp;'
-webui.itemdisplay.nobreakline.separator = ;
-
-# Specify which strategy use for select the style for an item
-plugin.single.org.dspace.app.webui.util.StyleSelection = \
-                       org.dspace.app.webui.util.CollectionStyleSelection
-                       #org.dspace.app.webui.util.MetadataStyleSelection
-
-# If use CollectionStyleSelection
-# Specify which collections use which views by Handle.
-#
-# webui.itemdisplay.<style>.collections = <collection handle>, ...
-#
-# FIXME: This should be more database-driven
-#
-# webui.itemdisplay.thesis.collections = 123456789/24, 123456789/35
-
-# If use MetadataStyleSelection, you MUST
-# Specify which metadata use as name of the style
-#
-# webui.itemdisplay.metadata-style = schema.element[.qualifier|.*]
-# webui.itemdisplay.metadata-style = dc.type
-
-# Customise the DC fields to use in the item listing page.  Elements will be
-# displayed left to right in the order that they are specified here.
-#
-# The form is <schema prefix>.<element>[.<qualifier>|.*][(date)], ...
-#
-# Although not a requirement, it would make sense to include among the listed
-# fields at least the date and title fields as specified by the
-# webui.browse.index.* configuration options below.
-#
-# If you have enabled thumbnails (webui.browse.thumbnail.show), you must also
-# include a 'thumbnail' entry in your columns - this is where the thumbnail will be displayed
-#
-# If you want to mark each item include a 'mark_[value]' (without the brackets - replace the word 'value' with anything that 
-# has a meaning for your mark) entry in your columns - this is where the icon will be displayed.
-# Do not forget to add a Spring bean with id = "org.dspace.app.itemmarking.ItemMarkingExtractor.[value]" 
-# in file 'config/spring/api/item-marking.xml'. This bean is responsible for drawing the appropriate mark for each item.
-# You can add more than one 'mark_[value]' options (with different value) in case you need to mark items more than one time for
-# different purposes. Remember to add the respective beans in file 'config/spring/api/item-marking.xml'.
-#
-# webui.itemlist.columns = thumbnail, dc.date.issued(date), dc.title, dc.contributor.*
-#
-# You can customise the width of each column with the following line - you can have numbers (pixels)
-# or percentages. For the 'thumbnail' column, a setting of '*' will use the max width specified
-# for browse thumbnails (webui.browse.thumbnail.maxwidth, thumbnail.maxwidth)
-# webui.itemlist.widths = *, 130, 60%, 40%
-
-# Additionally, you can override the DC fields used on the listing page for
-# a given browse index and/or sort option. As a sort option or index may be defined
-# on a field that isn't normally included in the list, this allows you to display
-# the fields that have been indexed / sorted on.
-#
-# There are a number of forms the configuration can take, and the order in which
-# they are listed below is the priority in which they will be used (so a combination
-# of an index name and sort name will take precedence over just the browse name).
-#
-# webui.itemlist.browse.<index name>.sort.<sort name>.columns
-# webui.itemlist.sort.<sort name>.columns
-# webui.itemlist.browse.<browse name>.columns
-# webui.itemlist.<sort or index name>.columns
-#
-# In the last case, a sort option name will always take precedence over a browse
-# index name. Note also, that for any additional columns you list, you will need to
-# ensure there is an itemlist.<field name> entry in the messages file.
-#
-# The following example would display the date of accession in place of the issue date
-# whenever the dateaccessioned browse index or sort option is selected.
-#
-# Just like webui.itemlist.columns, you will need to include a 'thumbnail' entry to display
-# and thumbnails in the item list
-#
-# webui.itemlist.dateaccessioned.columns = thumbnail, dc.date.accessioned(date), dc.title, dc.contributor.*
-#
-# As above, you can customise the width of the columns for each configured column list, substituting '.widths' for
-# '.columns' in the property name. See the setting for webui.itemlist.widths for more details
-# webui.itemlist.dateaccessioned.widths = *, 130, 60%, 40%
-
-# You can also set the overall size of the item list table with the following setting. It can lead to faster
-# table rendering when used with the column widths above, but not generally recommended.
-# webui.itemlist.tablewidth = 100%
-
-
-#### Additional configuration for Item Mapper ####
-
-# the index name (from webui.browse.index above) to use for
-# displaying items by author
-#
-itemmap.author.index = author
-
-
-### MyDSpace display of group membership ####
-#
-# if omitted, the default behaviour is false
-#
-# webui.mydspace.showgroupmemberships = false
-
-
-### Configure the search indices to appear in advanced search drop down lists
-#
-jspui.search.index.display.1 = ANY
-jspui.search.index.display.2 = author
-jspui.search.index.display.3 = title
-jspui.search.index.display.4 = keyword
-jspui.search.index.display.5 = abstract
-jspui.search.index.display.6 = series
-jspui.search.index.display.7 = sponsor
-jspui.search.index.display.8 = identifier
-jspui.search.index.display.9 = language
-
-
-##### SFX Server (OpenURL) #####
-
-# SFX query is appended to this URL.  If this property is commented out or
-# omitted, SFX support is switched off.
-# sfx.server.url = http://sfx.myu.edu:8888/sfx?
-
-# This image will be displayed in the SFX link. If commented out, the SFX link will be only a text link.
-# This customization usually contains an institution-branded SFX button.
-# sfx.server.image_url = http://sfx.my.edu:8888/sfx.gif
-
-
-#### Item Recommendation Settings #####
-
-# show a link to the item recommendation page from item display page
-webui.suggest.enable = false
-#
-# Enable only, if the user is logged in.
-# If not set the  default value is  false
-# webui.suggest.loggedinusers.only = true
-
-
-#### Controlled Vocabulary Settings #####
-
-# Enable or disable the controlled vocabulary add-on
-# Warning: this feature is not compatible with WAI (it requires javascript to function)
-#
-# webui.controlledvocabulary.enable = true
-
-
-#### Session invalidation #####
-
-# Enable or disable session invalidation upon login or logout.
-# This feature is enabled by default to help prevent session hijacking
-# but may cause problems for shibboleth, etc
-#
-# webui.session.invalidate = true
-
-# If you would like to use Google Analytics to track general website statistics then
-# use the following parameter to provide your Analytics key. First sign up for an
-# account at http://analytics.google.com, then create an entry for your repository
-# website. Analytics will give you a snipet of JavaScript code to place on your site,
-# inside that snipet is your Google Analytics key usually found in this line:
-# _uacct = "UA-XXXXXXX-X"
-# Take this key (just the UA-XXXXXX-X part) and place it here in this parameter.
-# jspui.google.analytics.key=UA-XXXXXX-X
-
-#---------------------------------------------------------------#
-#--------------XMLUI SPECIFIC CONFIGURATIONS--------------------#
-#---------------------------------------------------------------#
-# These configs are only used by the XML User Interface         #
-#---------------------------------------------------------------#
-
-
-# Force all authenticated connections to use SSL, only non-authenticated
-# connections are allowed over plain http. If set to true, then you need to
-# ensure that the 'dspace.hostname' parameter is set to the correctly.
-#xmlui.force.ssl = true
-
-# Determine if new users should be allowed to register or edit their own metadata.
-# These parameters are useful in conjunction with shibboleth where you want to
-# disallow registration and disable the user's ability to edit their metadata
-# because both come from Shibboleth.
-xmlui.user.registration=false
-#xmlui.user.editmetadata=true
-
-# Check if the user has a consistent ip address from the start of the login process
-# to the end of the login process. Disabling this check is not recommended unless
-# absolutely necessary as the ip check can be helpful for preventing session 
-# hijacking. Possible reasons to set this to false: many-to-many wireless networks
-# that prevent consistent ip addresses or complex proxying of requests.
-# The default value is set to true.
-#xmlui.session.ipcheck = true
-
-# After a user has logged into the system, which url should they be directed too?
-# Leave this parameter blank or undefined to direct users to the homepage, or
-# "/profile" for the user's profile, or another reasonable choice is "/submissions"
-# to see if the user has any tasks awaiting their attention. The default is the
-# repository home page.
-#xmlui.user.loginredirect=/profile
-
-# Allow the user to override which theme is used to display a particular page.
-# When submitting a request add the HTTP parameter "themepath" which corresponds
-# to a particular theme, that specified theme will be used instead of the any
-# other configured theme. Note that this is a potential security hole allowing
-# execution of unintended code on the server, this option is only for development
-# and debugging it should be turned off for any production repository. The default
-# value unless otherwise specified is "false"
-#xmlui.theme.allowoverrides = false
-
-# Enabling this property will concatenate CSS, JS and JSON files where possible.
-# CSS files can be concatenated if multiple CSS files with the same media attribute
-# are used in the same page. Links to the CSS files are automatically referring to the
-# concatenated resulting CSS file.
-# The theme sitemap should be updated to use the ConcatenationReader for all js, css and json
-# files before enabling this property.
-#xmlui.theme.enableConcatenation = false
-
-# Enabling this property will minify CSS, JS and JSON files where possible.
-# The theme sitemap should be updated to use the ConcatenationReader for all js, css and json
-# files before enabling this property.
-#xmlui.theme.enableMinification = false
-
-# Themes only allow specific file formats (extensions) to be accessible, for security reasons.
-# While the default list should work for most sites, you may wish to customize it.  The default
-# list is commented out below. To customize, just uncomment and add more file extensions.
-xmlui.theme.whitelist = css, js, json, gif, jpg, jpeg, png, bmp, ico, htm, html, svg, ttf, woff, woff2, eot, js.map, css.map
-
-### Settings for Item lists in Mirage theme ###
-# What should the emphasis be in the display of item lists?
-# Possible values : 'file', 'metadata'. If your repository is
-# used mainly for scientific papers 'metadata' is probably the
-# best way. If you have a lot of images and other files 'file'
-# will be the best starting point
-# (metdata is the default value if this option is not specified)
-#xmlui.theme.mirage.item-list.emphasis = file
-
-### Settings for the Item page in Mirage2 theme ###
-# Whether the title or the label of a file should be used to display it on the item page
-mirage2.item-view.bitstream.href.label.1 = label
-# Whether the title or the label of a file should be used as a fallback to display it on the item page
-mirage2.item-view.bitstream.href.label.2 = title
-
-# Determine which bundles administrators and collection administrators may upload
-# into an existing item through the administrative interface. If the user does not
-# have the appropriate privileges (add & write) on the bundle then that bundle will
-# not be shown to the user as an option.
-#xmlui.bundle.upload = ORIGINAL, METADATA, THUMBNAIL, LICENSE, CC-LICENSE
-
-# On the community-list page should all the metadata about a community/collection
-# be available to the theme. This parameter defaults to true, but if you are
-# experiencing performance problems on the community-list page you should experiment
-# with turning this option off.
-#xmlui.community-list.render.full = false
-
-# Normally, Manakin will fully verify any cache pages before using a cache copy.
-# This means that when the community-list page is viewed the database is queried
-# for each community/collection to see if their metadata has been modified. This
-# can be expensive for repositories with a large community tree. To help solve
-# this problem you can set the cache to be assumed valued for a specific set of time.
-# The downside of this is that new or editing communities/collections may not show up
-# the website for a period of time.
-#xmlui.community-list.cache = 12 hours
-
-# Optionally you may configure Manakin to take advantage of metadata stored as a
-# bitstream. These metadata files should be inside the "METADATA" bundle and named
-# either MODS.xml or METS.xml. If either of the following options are turned on then
-# these files will be made available to the theme when rendering an item.
-#xmlui.bitstream.mods = true
-#xmlui.bitstream.mets = true
-
-# If you would like to use Google Analytics to track general website statistics then
-# use the following parameter to provide your Analytics key. First sign up for an
-# account at http://analytics.google.com, then create an entry for your repository
-# website. Analytics will give you a snipet of JavaScript code to place on your site,
-# inside that snipet is your Google Analytics key usually found in this line:
-# _uacct = "UA-XXXXXXX-X"
-# Take this key (just the UA-XXXXXX-X part) and place it here in this parameter.
-xmlui.google.analytics.key=${xmlui.google.analytics.key}
-
-# Assign how many page views will be recorded and displayed in the control panel's
-# activity viewer. The activity tab allows an administrator to debug problems in a
-# running DSpace by understanding who and how their dspace is currently being used.
-# The default value is 250.
-xmlui.controlpanel.activity.max = 500
-
-# Determine where the control panel's activity viewer receives an event's IP address
-# from. If your DSpace is in a load balanced enviornment or otherwise behind a
-# context-switch then you will need to set the paramater to the HTTP parameter that
-# records the original IP address.
-#xmlui.controlpanel.activity.ipheader = X-Forwarded-For
-
-#---------------------------------------------------------------#
-#----------------REQUEST ITEM CONFIGURATION---------------------#
-#---------------------------------------------------------------#
-
-# Configuration of request-item. Possible values:
-# all - Anonymous users can request an item
-# logged - Login is mandatory to request an item
-# empty/commented out - request-copy not allowed
-#request.item.type = all
-# Helpdesk E-mail
-mail.helpdesk = ${mail.admin}
-# Should all Request Copy emails go to the helpdesk instead of the item submitter?
-request.item.helpdesk.override = false
-
-#------------END REQUEST ITEM CONFIGURATION---------------------#
-
-# lindat-dspace configuration
-#
-# - most of lindat-dspace configuration is inside modules/lr.cfg but we had
-# to change some of te default configuration in this file
-# - changes are minimal e.g., using hidden configuration or changing the value
-# of a variable that was commented out
-# - other changes introduce new variables which are used from e.g., emails because
-# variables from modules/* are not interpolated
-#
-
-##### Settings for Thumbnail creation #####
-xpdf.path.pdftotext = /usr/bin/pdftotext
-xpdf.path.pdftoppm = /usr/bin/pdftoppm
-xpdf.path.pdfinfo = /usr/bin/pdfinfo
-
-#### Stackable Authentication Methods #####
-
-# Authentication Method Used
-authenticationMethod = cz.cuni.mff.ufal.dspace.authenticate.ShibAuthentication
-
-# Stack of authentication methods
-#  (See org.dspace.authenticate.AuthenticationManager)
-# Example:
-# plugin.sequence.org.dspace.authenticate.AuthenticationMethod = \
-#       org.dspace.authenticate.ShibAuthentication, \
-#        org.dspace.authenticate.PasswordAuthentication
-plugin.sequence.org.dspace.authenticate.AuthenticationMethod = \
-        ${authenticationMethod}
-
-# hidden dspace configuration option in HandlePlugin
-# - do not check prefix authority, just handles
-handle.plugin.checknameauthority = false
-
-# SOLR Server url
-solr.server = ${solr.server}
-solr.log.server = ${solr.server}
-
-#log4j loglevels
-loglevel.other = ${loglevel.other}
-loglevel.dspace = ${loglevel.dspace}
-
-# CurrentActivity setting #
-currentActivityAction.recordBotEvents = true
-currentActivityAction.botStrings = google/, msnbot/, googlebot/, webcrawler/, \
-                    inktomi, teoma, baiduspider, bot, ufal-dev
-
-# Send the report to this address by default
-info.recipient = ${info.recipient}
-
-# Name used in e.g., email templates
-lr.dspace.name.short = ${lr.dspace.name.short}
-
-##### HELP DESK #####
-lr.help.mail = ${lr.help.mail}
-lr.help.phone = ${lr.help.phone}
-
diff --git a/dockerfiles/commul-customization/entrypoint.sh b/dockerfiles/commul-customization/entrypoint.sh
index c1f25038763419e9ce4a4f03d7783597a12e22ce..d39a43dcee87570eb636c66a84c620bc564aa2b3 100644
--- a/dockerfiles/commul-customization/entrypoint.sh
+++ b/dockerfiles/commul-customization/entrypoint.sh
@@ -15,38 +15,33 @@ perl -pi -e 's/\$\{HANDLE_USER\}/$ENV{HANDLE_USER}/; s/\$\{HANDLE_PASSWORD\}/$EN
 # initialize statistics & co
 cd /opt/repository/workspace/scripts
 make init_statistics
-/opt/tomcat8/bin/catalina.sh start
 
-# https://ubuntuforums.org/showthread.php?t=979694
-# Start process in the background and send its output to file descriptor 3
-exec 3< <(while (true); do
-    LOGID=$(( (LOGID+1) % 5))
-    LOG="/tmp/entrypoint.log.$LOGID"
-    echo > $LOG
-    timeout -k 30 300 make update_oai | tee -a $LOG
-    timeout -k 30 300 make update_statistics | tee -a $LOG
-    timeout -k 30 300 make update_sitemap | tee -a $LOG
-    timeout -k 30 300 make lift_embargos | tee -a $LOG
-    timeout -k 30 300 make update_openaire_cache | tee -a $LOG
-    timeout -k 30 300 make update_discovery | tee -a $LOG
-    timeout -k 30 300 make send_info | tee -a $LOG
-    date >> $LOG
-    echo "INIT DONE."
-    sleep 86400
-done)
-
-# Read the output of the process line by line until one line contains Ready
-while read line; do
-   case "$line" in
-   "INIT DONE.")
-      break
-      ;;
-   esac
-done <&3
-
-# Close the file descriptor
-exec <&3 3<&-
-/opt/tomcat8/bin/catalina.sh stop -force
+# Start cron job in the background
+cron_hack(){
+    INIT="false"
+    while (true); do
+        # the first time, wait for tomcat to start...
+        [ "$INIT" = "false" ] && sleep 180 && INIT="true"
+
+        set -x
+        LOGID=$(( (LOGID+1) % 5))
+        LOG="/tmp/entrypoint.log.$LOGID"
+        echo "$LOG" > $LOG
+        timeout -k 30 300 make update_oai | tee -a $LOG
+        timeout -k 30 300 make update_statistics | tee -a $LOG
+        timeout -k 30 300 make update_sitemap | tee -a $LOG
+        timeout -k 30 300 make lift_embargos | tee -a $LOG
+        timeout -k 30 300 make update_openaire_cache | tee -a $LOG
+        timeout -k 30 300 make update_discovery | tee -a $LOG
+        timeout -k 30 300 make send_info | tee -a $LOG
+        date >> $LOG
+        echo "INIT DONE."
+        wget https://healthchecks.local.iiegn.eu/ping/24a81cdc-2906-4faa-89b3-0d57541abef6 -T 10 -t 5 -O /dev/null
+        set +x
+        sleep 86400
+    done
+}
+cron_hack &
 
 # start tomcat
 /opt/tomcat8/bin/catalina.sh run
diff --git a/dockerfiles/commul-customization/local.properties b/dockerfiles/commul-customization/local.properties
index 0ceba3100143d76d7271fcb6c8f5395318c45bf9..5310f7103476875d524258dc9371abbf3a359fd8 100644
--- a/dockerfiles/commul-customization/local.properties
+++ b/dockerfiles/commul-customization/local.properties
@@ -283,7 +283,7 @@ lr.shibboleth.discofeed.url = https://clarin-dev.eurac.edu/Shibboleth.sso/DiscoF
 #
 # discojuice/aai url, without trailing slash
 # don't change this on ufal-point-dev!
-lr.aai.url = https://clarin-dev.eurac.edu/aai
+#lr.aai.url = https://clarin-dev.eurac.edu/aai
 
 # For reports
 harvesterInfo.url = http://catalog.clarin.eu/oai-harvester/
diff --git a/dockerfiles/commul-customization/default_locale b/dockerfiles/default_locale
similarity index 100%
rename from dockerfiles/commul-customization/default_locale
rename to dockerfiles/default_locale
diff --git a/dockerfiles/nginx/Dockerfile b/dockerfiles/nginx/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..8f9504cb581ab7a48dd203bfd98bd0da14357c20
--- /dev/null
+++ b/dockerfiles/nginx/Dockerfile
@@ -0,0 +1,111 @@
+##############################################################################
+# Dockerfile to build nginx and shibboleth for LINDAT Dspace container
+# Based on Ubuntu
+##############################################################################
+ARG UBUNTU_VERSION=16.04
+
+FROM ubuntu:$UBUNTU_VERSION
+ARG UBUNTU_VERSION
+
+ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
+LABEL maintainer="Alexander König <Alexander.Koenig@eurac.edu>" \
+      maintainer="Egon W. Stemle <egon.stemle@eurac.edu>"
+
+ENV TERM linux
+# APT(-GET) tweaks
+# Set some sane defaults for apt inside docker
+ENV DEBIAN_FRONTEND=noninteractive
+COPY apt.local.conf /etc/apt/apt.conf.d/99local.conf
+RUN apt-get update && \
+    apt-get upgrade
+
+# install cpanm and dependencies
+RUN apt-get update \
+    && apt-get install make gcc wget cpanminus
+
+RUN cpanm -n File::Spec::Functions
+RUN cpanm Term::ReadLine
+
+# install jdk, ant, psql, mvn, make, libxml, xsltproc, zip, wget
+RUN apt-get update \
+    && apt-get install ant curl libxml2-utils maven openjdk-8-jdk unzip xsltproc
+
+# set up a proper locale
+RUN apt-get update && apt-get install locales
+RUN locale-gen en_US.UTF-8
+COPY default_locale /etc/default/locale
+RUN chmod 0755 /etc/default/locale
+
+ENV LC_ALL=en_US.UTF-8
+ENV LANG=en_US.UTF-8
+ENV LANGUAGE=en_US.UTF-8
+
+# build nginx
+RUN apt-get update && apt-get install zlib1g zlib1g-dev libpcre3 libpcre3-dev curl
+RUN cpanm File::Spec::Functions
+RUN cpanm Term::ReadLine
+COPY build.sh /tmp/build.sh
+RUN chmod a+x /tmp/build.sh
+WORKDIR /tmp/
+RUN ./build.sh
+# copy the init script
+COPY init.d_nginx /etc/init.d/nginx
+RUN chmod a+x /etc/init.d/nginx
+# add a symlink
+RUN ln -s /opt/nginx/sbin/nginx /usr/sbin/nginx
+# copy over static html
+COPY html/ /opt/nginx/html/
+# copy over robots.txt
+COPY robots-clarin-dev.txt /opt/nginx/html/robots.txt
+COPY google4a439c0ac1ac30d0.html /opt/nginx/html/
+RUN chown -R www-data:www-data /opt/nginx/html/
+
+#RUN mkdir /opt/nginx/html/img
+#COPY commul-customization/index.html /opt/nginx/html/
+#COPY commul-customization/eurac.png /opt/nginx/html/img/
+
+# install php
+RUN apt-get update && apt-get install php-fpm php-xml
+# copy over aa-statistics script
+RUN mkdir /opt/nginx/html/php
+COPY aa-statistics.php /opt/nginx/html/php/
+
+# install shibboleth
+COPY shibboleth_sp_with_fastcgi.sh /tmp/
+WORKDIR /tmp
+RUN chmod u+x /tmp/shibboleth_sp_with_fastcgi.sh
+RUN /tmp/shibboleth_sp_with_fastcgi.sh
+# copy the init script
+RUN cp /opt/shibboleth-sp-fastcgi/etc/shibboleth/shibd-debian /etc/init.d/shibd
+RUN chmod a+x /etc/init.d/shibd
+
+# create the test secure folder and set up perl fastcgi
+RUN mkdir /opt/nginx/html/secure
+RUN apt-get update && apt-get install fcgiwrap
+RUN cpanm CGI URI XML::Twig LWP::Protocol::https
+COPY shib_test.pl /opt/nginx/html/secure/
+COPY shib_fastcgi_params /opt/nginx/conf/
+COPY attribute-map.xml /opt/shibboleth-sp-fastcgi/etc/shibboleth/
+RUN chown -R www-data:www-data /opt/nginx/html/secure
+RUN chmod a+x /opt/nginx/html/secure/shib_test.pl
+
+# install supervisor
+RUN apt-get update && apt-get install python-setuptools
+RUN easy_install supervisor
+COPY supervisord.conf /etc/
+RUN mkdir -p /var/log/supervisor
+# create dirs for php-fpm socket/pid and log files
+RUN mkdir -p /run/php
+RUN mkdir -p /var/log/php-fpm/
+COPY php-fpm.conf /etc/php/7.0/fpm/
+COPY php.ini /etc/php/7.0/fpm/
+
+# copy over config files
+COPY nginx.default.conf /opt/nginx/conf/
+COPY nginx.conf /opt/nginx/conf/
+COPY repository_auth /opt/nginx/conf/
+COPY shibboleth2.xml /opt/shibboleth-sp-fastcgi/etc/shibboleth/
+COPY clarin.eurac.edu.template.metadata.xml /opt/shibboleth-sp-fastcgi/etc/shibboleth/
+COPY shib_clear_headers /opt/nginx/conf/
+
+ENTRYPOINT ["/usr/local/bin/supervisord", "-c", "/etc/supervisord.conf"]
diff --git a/dockerfiles/nginx/Earthfile b/dockerfiles/nginx/Earthfile
new file mode 100644
index 0000000000000000000000000000000000000000..57d34f06fd0be37279146a788675b0ca1d2ddd30
--- /dev/null
+++ b/dockerfiles/nginx/Earthfile
@@ -0,0 +1,51 @@
+# Usage: earthly --push --no-cache +docker
+
+docker-precondition-spf:
+    FROM alpine:latest
+    RUN apk add curl
+    RUN --no-cache curl https://infra.clarin.eu/aai/prod_md_about_spf_idps.xml -o /tmp/prod_md_about_spf_idps.xml
+    SAVE ARTIFACT --keep-ts /tmp/prod_md_about_spf_idps.xml
+
+docker-from-docker:
+    FROM DOCKERFILE .
+
+    COPY +docker-precondition-spf/prod_md_about_spf_idps.xml /opt/shibboleth-sp-fastcgi/var/cache/shibboleth/
+
+    ARG DOCKER_BASE_URL="gitlab.inf.unibz.it:4567"
+    ARG EARTHLY_GIT_PROJECT_NAME  # https://docs.earthly.dev/earthfile/builtin-args
+    ARG GIT_PROJECT_NAME="commul/docker/clarin-dspace"
+    ARG COMMUL_REGISTRY_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace/container_registry/"
+    ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
+
+    ARG AUTHOR="Egon W. Stemle <egon.stemle@eurac.edu>"
+    ARG MAINTAINER="Egon W. Stemle <egon.stemle@eurac.edu>"
+    LABEL author="$AUTHOR"
+    LABEL maintainer="$MAINTAINER"
+
+    # An updated VERSION ARG triggers an update of the texlive installation
+    ARG EARTHLY_TARGET_TAG
+    ARG VERSION=$EARTHLY_TARGET_TAG
+
+    ARG EARTHLY_GIT_HASH
+    ARG GIT_HASH=$EARTHLY_GIT_HASH
+    ARG EARTHLY_TARGET_TAG_DOCKER
+    ARG TARGET_TAG_DOCKER=$EARTHLY_TARGET_TAG_DOCKER
+    ARG DOCKER_URL="$DOCKER_BASE_URL/$GIT_PROJECT_NAME/dspace-bundle/nginx"
+
+    LABEL org.label-schema.schema-version="1.0" \  # http://label-schema.org/rc1/
+          org.label-schema.version="$VERSION" \
+          org.label-schema.vcs-url="$LABEL_VCS_URL" \
+          org.commul.git-hash="$GIT_HASH" \
+          org.commul.registry-url="$COMMUL_REGISTRY_URL" \
+          org.commul.docker-url="$DOCKER_URL"
+
+    RUN echo $VERSION > /tmp/release
+    SAVE ARTIFACT --keep-ts /tmp/release AS LOCAL ./.release
+
+    SAVE IMAGE nginx:latest
+    SAVE IMAGE --push "$DOCKER_URL:latest"
+    SAVE IMAGE --push "$DOCKER_URL:$VERSION"
+
+docker:
+    BUILD +docker-precondition-spf
+    BUILD +docker-from-docker
diff --git a/dockerfiles/commul-customization/aa-statistics.php b/dockerfiles/nginx/aa-statistics.php
similarity index 100%
rename from dockerfiles/commul-customization/aa-statistics.php
rename to dockerfiles/nginx/aa-statistics.php
diff --git a/dockerfiles/nginx/apt.local.conf b/dockerfiles/nginx/apt.local.conf
new file mode 100644
index 0000000000000000000000000000000000000000..43cafde125414542a43d945bad74b2ad66e97c1d
--- /dev/null
+++ b/dockerfiles/nginx/apt.local.conf
@@ -0,0 +1,3 @@
+# Set some sane defaults for docker
+APT { GET { Assume-Yes "true"; }; };
+APT { GET { Fix-Broken "true"; }; };
diff --git a/dockerfiles/commul-customization/attribute-map.xml b/dockerfiles/nginx/attribute-map.xml
similarity index 100%
rename from dockerfiles/commul-customization/attribute-map.xml
rename to dockerfiles/nginx/attribute-map.xml
diff --git a/dockerfiles/commul-customization/nginx_build.sh b/dockerfiles/nginx/build.sh
similarity index 100%
rename from dockerfiles/commul-customization/nginx_build.sh
rename to dockerfiles/nginx/build.sh
diff --git a/dockerfiles/nginx/clarin.eurac.edu.template.metadata.xml b/dockerfiles/nginx/clarin.eurac.edu.template.metadata.xml
new file mode 100644
index 0000000000000000000000000000000000000000..27f0a34ee7779090cb09ec5be717b300faee8185
--- /dev/null
+++ b/dockerfiles/nginx/clarin.eurac.edu.template.metadata.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+                     xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
+                     xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+                     xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
+                     xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init"
+                     xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute"
+                     xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi"
+                     xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
+                     xmlns:remd="http://refeds.org/metadata"
+                     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+                     xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
+                     xmlns:shibmd="urn:mace:shibboleth:metadata:1.0"
+                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                     entityID="https://clarin-dev.eurac.edu/Shibboleth.sso/Metadata">
+   <md:Extensions>
+      <mdattr:EntityAttributes>
+         <saml:Attribute Name="http://macedir.org/entity-category"
+                         NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+            <saml:AttributeValue>http://www.geant.net/uri/dataprotection-code-of-conduct/v1</saml:AttributeValue>
+         </saml:Attribute>
+         <saml:Attribute Name="http://macedir.org/entity-category"
+                         NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+            <saml:AttributeValue>http://refeds.org/category/research-and-scholarship</saml:AttributeValue>
+         </saml:Attribute>
+         <saml:Attribute Name="http://macedir.org/entity-category"
+                         NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+            <saml:AttributeValue>http://clarin.eu/category/clarin-member</saml:AttributeValue>
+         </saml:Attribute>
+      </mdattr:EntityAttributes>
+   </md:Extensions>
+   <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:1.0:protocol">
+      <md:Extensions>
+         <mdui:UIInfo>
+            <mdui:DisplayName xml:lang="en">Eurac Research CLARIN Centre</mdui:DisplayName>
+            <mdui:DisplayName xml:lang="de">Eurac Research CLARIN Centre</mdui:DisplayName>
+            <mdui:DisplayName xml:lang="it">Eurac Research CLARIN Centre</mdui:DisplayName>
+            <mdui:Description xml:lang="en">Eurac Research CLARIN Centre: Digital repository for language data</mdui:Description>
+            <mdui:Description xml:lang="de">Eurac Research CLARIN Centre: Digitales Repository für Sprachdaten</mdui:Description>
+            <mdui:Description xml:lang="it">Eurac Research CLARIN Centre: repository digitale di risorse linguistiche</mdui:Description>
+            <mdui:InformationURL xml:lang="en">https://clarin-dev.eurac.edu/repository/xmlui/page/about</mdui:InformationURL>
+            <mdui:InformationURL xml:lang="de">https://clarin-dev.eurac.edu/repository/xmlui/page/about</mdui:InformationURL>
+            <mdui:InformationURL xml:lang="it">https://clarin-dev.eurac.edu/repository/xmlui/page/about</mdui:InformationURL>
+            <mdui:Logo height="85" width="180">https://clarin-dev.eurac.edu/repository/xmlui/themes/UFAL/lib/lindat/public/img/eurac_research.svg</mdui:Logo>
+            <mdui:PrivacyStatementURL xml:lang="en">https://clarin-dev.eurac.edu/repository/xmlui/page/registration-privacypolicy</mdui:PrivacyStatementURL>
+            <mdui:PrivacyStatementURL xml:lang="de">https://clarin-dev.eurac.edu/repository/xmlui/page/registration-privacypolicy</mdui:PrivacyStatementURL>
+            <mdui:PrivacyStatementURL xml:lang="it">https://clarin-dev.eurac.edu/repository/xmlui/page/registration-privacypolicy</mdui:PrivacyStatementURL>
+         </mdui:UIInfo>
+      </md:Extensions>
+      <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+                                    Location="https://clarin-dev.eurac.edu/Shibboleth.sso/Artifact/SOAP"
+                                    index="1"/>
+      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+                              Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SLO/SOAP"/>
+      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+                              Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SLO/Redirect"/>
+      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+                              Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SLO/POST"/>
+      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
+                              Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SLO/Artifact"/>
+      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+                                   Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SAML2/POST"
+                                   index="1"/>
+      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
+                                   Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SAML2/POST-SimpleSign"
+                                   index="2"/>
+      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
+                                   Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SAML2/Artifact"
+                                   index="3"/>
+      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
+                                   Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SAML2/ECP"
+                                   index="4"/>
+      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"
+                                   Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SAML/POST"
+                                   index="5"/>
+      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"
+                                   Location="https://clarin-dev.eurac.edu/Shibboleth.sso/SAML/Artifact"
+                                   index="6"/>
+      <md:AttributeConsumingService index="1">
+         <md:ServiceName xml:lang="en">Digital Repository for the CLARIN Research Infrastructure provided by Eurac Research</md:ServiceName>
+         <md:ServiceName xml:lang="de">Digitales Repository für die CLARIN-Forschungs-Infrastruktur bereitgestellt durch Eurac Research</md:ServiceName>
+         <md:ServiceName xml:lang="it">Repository Digitale per la Infrastruttura di Ricerca CLARIN erogato da Eurac Research</md:ServiceName>
+         <md:ServiceDescription xml:lang="en">Digital Repository and services related to the CLARIN-IT consortium under the CLARIN Research Infrastructure; focused in the fields of terminology and multilingualism. The repository is based at Eurac Research in South Tyrol and managed by the Institute for Applied Linguistics.</md:ServiceDescription>
+         <md:ServiceDescription xml:lang="de">Digitales Repository und Services mit Bezug zum CLARIN-IT-Consortium im Rahmen der CLARIN Forschungsinfrastruktur; mit Fokus auf den Gebieten der Terminologie und Mehrsprachigkeit. Das Repository wird von Eurac Research gehostet und dort vom Institut für Angewandte Sprachforschung betreut.</md:ServiceDescription>
+         <md:ServiceDescription xml:lang="it">Repository Digitale e servizi relativi al consorzio CLARIN-IT sotto l'Infrastruttura di Ricerca CLARIN; focalizzato nel campo della teminologia e multilinguismo. Il repository è basato a Eurac Research in Alto Adige e gestito del Istituto di Linguistica Applicata.</md:ServiceDescription>
+         <md:RequestedAttribute FriendlyName="eduPersonPrincipalName"
+                                Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="true"/>
+         <md:RequestedAttribute FriendlyName="email"
+                                Name="urn:oid:0.9.2342.19200300.100.1.3"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="true"/>
+         <md:RequestedAttribute FriendlyName="cn"
+                                Name="urn:oid:2.5.4.3"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="false"/>
+         <md:RequestedAttribute FriendlyName="schacHomeOrganization"
+                                Name="urn:oid:1.3.6.1.4.1.25178.1.2.9"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="false"/>
+         <md:RequestedAttribute FriendlyName="organizationName"
+                                Name="urn:oid:2.5.4.10"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="false"/>
+         <md:RequestedAttribute FriendlyName="displayName"
+                                Name="urn:oid:2.16.840.1.113730.3.1.241"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="true"/>
+         <md:RequestedAttribute FriendlyName="eduPersonEntitlement"
+                                Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="false"/>
+         <md:RequestedAttribute FriendlyName="eduPersonTargetedID"
+                                Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="true"/>
+         <md:RequestedAttribute FriendlyName="eduPersonScopedAffiliation"
+                                Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9"
+                                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+                                isRequired="false"/>
+      </md:AttributeConsumingService>
+   </md:SPSSODescriptor>
+   <md:Organization>
+      <md:OrganizationName xml:lang="en">Eurac Research</md:OrganizationName>
+      <md:OrganizationName xml:lang="de">Eurac Research</md:OrganizationName>
+      <md:OrganizationName xml:lang="it">Eurac Research</md:OrganizationName>
+      <md:OrganizationDisplayName xml:lang="en">Eurac Research</md:OrganizationDisplayName>
+      <md:OrganizationDisplayName xml:lang="de">Eurac Research</md:OrganizationDisplayName>
+      <md:OrganizationDisplayName xml:lang="it">Eurac Research</md:OrganizationDisplayName>
+      <md:OrganizationURL xml:lang="en">http://www.eurac.edu/en</md:OrganizationURL>
+      <md:OrganizationURL xml:lang="de">http://www.eurac.edu/de</md:OrganizationURL>
+      <md:OrganizationURL xml:lang="it">http://www.eurac.edu/it</md:OrganizationURL>
+   </md:Organization>
+   <md:ContactPerson contactType="technical">
+      <md:GivenName>Egon</md:GivenName>
+      <md:SurName>Stemle</md:SurName>
+      <md:EmailAddress>mailto:clarin@eurac.edu</md:EmailAddress>
+   </md:ContactPerson>
+   <md:ContactPerson contactType="support">
+      <md:GivenName>Egon</md:GivenName>
+      <md:SurName>Stemle</md:SurName>
+      <md:EmailAddress>mailto:clarin@eurac.edu</md:EmailAddress>
+   </md:ContactPerson>
+   <md:ContactPerson contactType="administrative">
+      <md:GivenName>Andrea</md:GivenName>
+      <md:SurName>Abel</md:SurName>
+      <md:EmailAddress>mailto:linguistics@eurac.edu</md:EmailAddress>
+   </md:ContactPerson>
+</md:EntityDescriptor>
diff --git a/dockerfiles/nginx/default_locale b/dockerfiles/nginx/default_locale
new file mode 100644
index 0000000000000000000000000000000000000000..0e74fc3ba0fbd4d77da905e387bc67956333c722
--- /dev/null
+++ b/dockerfiles/nginx/default_locale
@@ -0,0 +1,11 @@
+#  File generated by update-locale
+LANG="en_US.UTF-8"
+LC_NUMERIC="en_US.UTF-8"
+LC_TIME="en_US.UTF-8"
+LC_MONETARY="en_US.UTF-8"
+LC_PAPER="en_US.UTF-8"
+LC_NAME="en_US.UTF-8"
+LC_ADDRESS="en_US.UTF-8"
+LC_TELEPHONE="en_US.UTF-8"
+LC_MEASUREMENT="en_US.UTF-8"
+LC_IDENTIFICATION="en_US.UTF-8"
diff --git a/dockerfiles/commul-customization/google4a439c0ac1ac30d0.html b/dockerfiles/nginx/google4a439c0ac1ac30d0.html
similarity index 100%
rename from dockerfiles/commul-customization/google4a439c0ac1ac30d0.html
rename to dockerfiles/nginx/google4a439c0ac1ac30d0.html
diff --git a/dockerfiles/commul-customization/webpage/images/clarin_ill_1100x375_2.jpg b/dockerfiles/nginx/html/images/clarin_ill_1100x375_2.jpg
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/clarin_ill_1100x375_2.jpg
rename to dockerfiles/nginx/html/images/clarin_ill_1100x375_2.jpg
diff --git a/dockerfiles/commul-customization/webpage/images/clarin_ill_1100x375_2.png b/dockerfiles/nginx/html/images/clarin_ill_1100x375_2.png
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/clarin_ill_1100x375_2.png
rename to dockerfiles/nginx/html/images/clarin_ill_1100x375_2.png
diff --git a/dockerfiles/commul-customization/webpage/images/clarin_ill_1100x375_2_blue11-clean.jpeg b/dockerfiles/nginx/html/images/clarin_ill_1100x375_2_blue11-clean.jpeg
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/clarin_ill_1100x375_2_blue11-clean.jpeg
rename to dockerfiles/nginx/html/images/clarin_ill_1100x375_2_blue11-clean.jpeg
diff --git a/dockerfiles/nginx/html/images/ercc-logo-big.png b/dockerfiles/nginx/html/images/ercc-logo-big.png
new file mode 100644
index 0000000000000000000000000000000000000000..01afcb00d92476107b41ec2260b553bbeb070733
Binary files /dev/null and b/dockerfiles/nginx/html/images/ercc-logo-big.png differ
diff --git a/dockerfiles/commul-customization/webpage/images/ercc-logo.png b/dockerfiles/nginx/html/images/ercc-logo.png
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/ercc-logo.png
rename to dockerfiles/nginx/html/images/ercc-logo.png
diff --git a/dockerfiles/commul-customization/webpage/images/eurac_oki.jpg b/dockerfiles/nginx/html/images/eurac_oki.jpg
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/eurac_oki.jpg
rename to dockerfiles/nginx/html/images/eurac_oki.jpg
diff --git a/dockerfiles/nginx/html/images/favicon_eurac-research-big.png b/dockerfiles/nginx/html/images/favicon_eurac-research-big.png
new file mode 100644
index 0000000000000000000000000000000000000000..5ceed3076077b8aa071e60174558274723ecc71d
Binary files /dev/null and b/dockerfiles/nginx/html/images/favicon_eurac-research-big.png differ
diff --git a/dockerfiles/commul-customization/webpage/images/favicon_eurac-research.png b/dockerfiles/nginx/html/images/favicon_eurac-research.png
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/favicon_eurac-research.png
rename to dockerfiles/nginx/html/images/favicon_eurac-research.png
diff --git a/dockerfiles/commul-customization/webpage/images/mail-icon.svg b/dockerfiles/nginx/html/images/mail-icon.svg
similarity index 100%
rename from dockerfiles/commul-customization/webpage/images/mail-icon.svg
rename to dockerfiles/nginx/html/images/mail-icon.svg
diff --git a/dockerfiles/commul-customization/webpage/index.html b/dockerfiles/nginx/html/index.html
similarity index 100%
rename from dockerfiles/commul-customization/webpage/index.html
rename to dockerfiles/nginx/html/index.html
diff --git a/dockerfiles/commul-customization/webpage/main.css b/dockerfiles/nginx/html/main.css
similarity index 100%
rename from dockerfiles/commul-customization/webpage/main.css
rename to dockerfiles/nginx/html/main.css
diff --git a/dockerfiles/commul-customization/nginx b/dockerfiles/nginx/init.d_nginx
similarity index 100%
rename from dockerfiles/commul-customization/nginx
rename to dockerfiles/nginx/init.d_nginx
diff --git a/dockerfiles/commul-customization/nginx.conf b/dockerfiles/nginx/nginx.conf
similarity index 100%
rename from dockerfiles/commul-customization/nginx.conf
rename to dockerfiles/nginx/nginx.conf
diff --git a/dockerfiles/commul-customization/nginx.default.conf b/dockerfiles/nginx/nginx.default.conf
similarity index 97%
rename from dockerfiles/commul-customization/nginx.default.conf
rename to dockerfiles/nginx/nginx.default.conf
index c9210e7f4d341e67eae4dd2c6da45abf288a899b..f4cc638d18286f07dc9cc4a463f818a48bc865e1 100644
--- a/dockerfiles/commul-customization/nginx.default.conf
+++ b/dockerfiles/nginx/nginx.default.conf
@@ -105,10 +105,6 @@ server {
 
   }
 
-  # define aai location
-  location /aai {
-    alias /opt/repository/sources/lindat-aai-discovery; }
-
   # add path your repository path that will be protected by shibboleth
   location /repository/xmlui/shibboleth-login {
     include repository_auth;
diff --git a/dockerfiles/commul-customization/php-fpm.conf b/dockerfiles/nginx/php-fpm.conf
similarity index 100%
rename from dockerfiles/commul-customization/php-fpm.conf
rename to dockerfiles/nginx/php-fpm.conf
diff --git a/dockerfiles/commul-customization/php.ini b/dockerfiles/nginx/php.ini
similarity index 100%
rename from dockerfiles/commul-customization/php.ini
rename to dockerfiles/nginx/php.ini
diff --git a/dockerfiles/commul-customization/repository_auth b/dockerfiles/nginx/repository_auth
similarity index 100%
rename from dockerfiles/commul-customization/repository_auth
rename to dockerfiles/nginx/repository_auth
diff --git a/dockerfiles/commul-customization/robots-clarin-dev.txt b/dockerfiles/nginx/robots-clarin-dev.txt
similarity index 100%
rename from dockerfiles/commul-customization/robots-clarin-dev.txt
rename to dockerfiles/nginx/robots-clarin-dev.txt
diff --git a/dockerfiles/commul-customization/robots-clarin.txt b/dockerfiles/nginx/robots-clarin.txt
similarity index 100%
rename from dockerfiles/commul-customization/robots-clarin.txt
rename to dockerfiles/nginx/robots-clarin.txt
diff --git a/dockerfiles/commul-customization/shib_clear_headers b/dockerfiles/nginx/shib_clear_headers
similarity index 100%
rename from dockerfiles/commul-customization/shib_clear_headers
rename to dockerfiles/nginx/shib_clear_headers
diff --git a/dockerfiles/commul-customization/shib_fastcgi_params b/dockerfiles/nginx/shib_fastcgi_params
similarity index 100%
rename from dockerfiles/commul-customization/shib_fastcgi_params
rename to dockerfiles/nginx/shib_fastcgi_params
diff --git a/dockerfiles/commul-customization/shib_test.pl b/dockerfiles/nginx/shib_test.pl
similarity index 100%
rename from dockerfiles/commul-customization/shib_test.pl
rename to dockerfiles/nginx/shib_test.pl
diff --git a/dockerfiles/commul-customization/shibboleth2.xml b/dockerfiles/nginx/shibboleth2.xml
similarity index 99%
rename from dockerfiles/commul-customization/shibboleth2.xml
rename to dockerfiles/nginx/shibboleth2.xml
index bfb95df294812013fc682b907c7b90fecb0ce3ff..f746edbbdf4748162df013051709ce7ef16bed27 100644
--- a/dockerfiles/commul-customization/shibboleth2.xml
+++ b/dockerfiles/nginx/shibboleth2.xml
@@ -56,7 +56,8 @@
             handlerSSL="false"
             cookieProps="https"
             exportLocation="/GetAssertion"
-            exportACL="127.0.0.1">
+            exportACL="127.0.0.1"
+            redirectLimit="exact">
 
             <!--
             Configures SSO for a default IdP. To allow for >1 IdP, remove
diff --git a/dockerfiles/commul-customization/shibboleth_sp_with_fastcgi.sh b/dockerfiles/nginx/shibboleth_sp_with_fastcgi.sh
similarity index 100%
rename from dockerfiles/commul-customization/shibboleth_sp_with_fastcgi.sh
rename to dockerfiles/nginx/shibboleth_sp_with_fastcgi.sh
diff --git a/dockerfiles/commul-customization/supervisord.conf b/dockerfiles/nginx/supervisord.conf
similarity index 100%
rename from dockerfiles/commul-customization/supervisord.conf
rename to dockerfiles/nginx/supervisord.conf
diff --git a/dockerfiles/Dockerfile.postgres b/dockerfiles/postgres/Dockerfile
similarity index 50%
rename from dockerfiles/Dockerfile.postgres
rename to dockerfiles/postgres/Dockerfile
index b61c89b0db3ec54552ade2c5f600d22395881035..ea6f2745008cad82ce752b161e2feaa536f2c8c7 100644
--- a/dockerfiles/Dockerfile.postgres
+++ b/dockerfiles/postgres/Dockerfile
@@ -2,44 +2,36 @@
 # Dockerfile to build postgres for LINDAT Dspace container
 # Based on Postgres
 ##############################################################################
-
+ARG DSPACE_APP_VERSION
 ARG POSTGRES_VERSION=9.6
-FROM postgres:$POSTGRES_VERSION
-ARG POSTGRES_VERSION
 
-ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
-LABEL maintainer="Alexander König <Alexander.Koenig@eurac.edu>" \
-      maintainer="Egon W. Stemle <egon.stemle@eurac.edu>"
+FROM gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/dspace-app/2020.02.1:$DSPACE_APP_VERSION as dspace-app
+
+FROM postgres:$POSTGRES_VERSION
 
 ENV TERM linux
 # APT(-GET) tweaks
 # Set some sane defaults for apt inside docker
 ENV DEBIAN_FRONTEND=noninteractive
-COPY apt.local.conf /etc/apt/apt.conf.d/99local.conf
-#
 #
 RUN apt-get update && \
-    apt-get upgrade
-
-# Install git
-RUN apt-get update && apt-get install git
+    apt-get -y upgrade && \
+    apt-get -y install git && \
+    rm -rf /var/lib/apt/lists/*
 
 # copy int db script
 RUN mkdir -p /docker-entrypoint-initdb.d
-COPY commul-customization/init-dspace-dbs.sh /docker-entrypoint-initdb.d/
+COPY init-dspace-dbs.sh /docker-entrypoint-initdb.d/
 RUN chmod +x /docker-entrypoint-initdb.d/*
 
+# FIXME: still needed?
 # copy over modified config file
 #COPY commul-customization/postgresql.conf /tmp/
 #COPY commul-customization/updateConfig.sh /docker-entrypoint-initdb.d/_updateConfig.sh
 
-# copy script generating utilities db
+# Adapt license definitions file
 RUN mkdir /tmp/sql/
-COPY adapt_utilities_sql.sh /tmp/sql/
-RUN /tmp/sql/adapt_utilities_sql.sh
-
-ARG LABEL_VERSION
-ARG LABEL_BUILD_DATE
-LABEL org.label-schema.version=$LABEL_VERSION \
-      org.label-schema.build-date=$LABEL_BUILD_DATE \
-      org.label-schema.vcs-url=$LABEL_VCS_URL
+COPY --from=dspace-app /app/utilities/utilities.sql /tmp/sql/
+COPY --from=dspace-app /app/utilities/license_definition.txt /tmp/sql
+RUN chmod -R a+w /tmp/sql/ && \
+    perl -pi -e "s#afile :utildir '/license_definition.txt'#afile '/tmp/sql/license_definition.txt'#;" /tmp/sql/utilities.sql
diff --git a/dockerfiles/postgres/Earthfile b/dockerfiles/postgres/Earthfile
new file mode 100644
index 0000000000000000000000000000000000000000..bec324345d81cb4f2c80e102a0ee6aaeade40676
--- /dev/null
+++ b/dockerfiles/postgres/Earthfile
@@ -0,0 +1,42 @@
+# Usage: earthly --push --no-cache +docker
+ARG DSPACE_APP_VERSION
+
+docker-from-docker:
+    FROM DOCKERFILE --build-arg DSPACE_APP_VERSION=$DSPACE_APP_VERSION .
+    ARG DOCKER_BASE_URL="gitlab.inf.unibz.it:4567"
+    ARG EARTHLY_GIT_PROJECT_NAME  # https://docs.earthly.dev/earthfile/builtin-args
+    ARG GIT_PROJECT_NAME="commul/docker/clarin-dspace"
+    ARG COMMUL_REGISTRY_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace/container_registry/"
+    ARG LABEL_VCS_URL="https://gitlab.inf.unibz.it/commul/docker/clarin-dspace"
+
+    ARG AUTHOR="Egon W. Stemle <egon.stemle@eurac.edu>"
+    ARG MAINTAINER="Egon W. Stemle <egon.stemle@eurac.edu>"
+    LABEL author="$AUTHOR"
+    LABEL maintainer="$MAINTAINER"
+
+    # An updated VERSION ARG triggers an update of the texlive installation
+    ARG EARTHLY_TARGET_TAG
+    ARG VERSION=$EARTHLY_TARGET_TAG
+
+    ARG EARTHLY_GIT_HASH
+    ARG GIT_HASH=$EARTHLY_GIT_HASH
+    ARG EARTHLY_TARGET_TAG_DOCKER
+    ARG TARGET_TAG_DOCKER=$EARTHLY_TARGET_TAG_DOCKER
+    ARG DOCKER_URL="$DOCKER_BASE_URL/$GIT_PROJECT_NAME/dspace-bundle/postgres"
+
+    LABEL org.label-schema.schema-version="1.0" \  # http://label-schema.org/rc1/
+          org.label-schema.version="$VERSION" \
+          org.label-schema.vcs-url="$LABEL_VCS_URL" \
+          org.commul.git-hash="$GIT_HASH" \
+          org.commul.registry-url="$COMMUL_REGISTRY_URL" \
+          org.commul.docker-url="$DOCKER_URL"
+
+    RUN echo $VERSION > /tmp/release
+    SAVE ARTIFACT --keep-ts /tmp/release AS LOCAL ./.release
+
+    SAVE IMAGE postgres:latest
+    SAVE IMAGE --push "$DOCKER_URL:latest"
+    SAVE IMAGE --push "$DOCKER_URL:$VERSION"
+
+docker:
+    BUILD --build-arg DSPACE_APP_VERSION=$DSPACE_APP_VERSION +docker-from-docker
diff --git a/dockerfiles/commul-customization/init-dspace-dbs.sh b/dockerfiles/postgres/init-dspace-dbs.sh
similarity index 100%
rename from dockerfiles/commul-customization/init-dspace-dbs.sh
rename to dockerfiles/postgres/init-dspace-dbs.sh
diff --git a/dockerfiles/commul-customization/init-dspace-dbs.sh.dist b/dockerfiles/postgres/init-dspace-dbs.sh.dist
similarity index 100%
rename from dockerfiles/commul-customization/init-dspace-dbs.sh.dist
rename to dockerfiles/postgres/init-dspace-dbs.sh.dist
diff --git a/dockerfiles/commul-customization/postgresql.conf b/dockerfiles/postgres/postgresql.conf
similarity index 100%
rename from dockerfiles/commul-customization/postgresql.conf
rename to dockerfiles/postgres/postgresql.conf
diff --git a/dockerfiles/commul-customization/updateConfig.sh b/dockerfiles/postgres/updateConfig.sh
similarity index 100%
rename from dockerfiles/commul-customization/updateConfig.sh
rename to dockerfiles/postgres/updateConfig.sh
diff --git a/dockerfiles/release.sh b/dockerfiles/release.sh
index 1e75372ca58f5bf57756049ece3184dc1d983947..3701a15aad4b302c76a416806c4c23b09784d576 100755
--- a/dockerfiles/release.sh
+++ b/dockerfiles/release.sh
@@ -1,25 +1,8 @@
 #!/bin/bash
 set -e
 
-VERSION=${1:-latest}
-TYPE=${2:-staging}
-
-# export DOCKER_BUILDKIT=1
-docker build \
-    --build-arg LABEL_VERSION="$VERSION" \
-    --build-arg LABEL_BUILD_DATE="$(date -R)" \
-    -t "gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/$TYPE/dspace:$VERSION" . -f Dockerfile.dspace
-docker build \
-    --build-arg LABEL_VERSION="$VERSION" \
-    --build-arg LABEL_BUILD_DATE="$(date -R)" \
-    -t "gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/$TYPE/nginx:$VERSION" . -f Dockerfile.nginx
-docker build \
-    --build-arg LABEL_VERSION="$VERSION" \
-    --build-arg LABEL_BUILD_DATE="$(date -R)" \
-    -t "gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/$TYPE/postgres:$VERSION" . -f Dockerfile.postgres
-
-docker push "gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/$TYPE/dspace:$VERSION"
-docker push "gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/$TYPE/nginx:$VERSION"
-docker push "gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/$TYPE/postgres:$VERSION"
+ERCC_TAG="$(git describe --tags --abbrev=0 $(git rev-list --tags --max-count=1))"
+VERSION=${ERCC_TAG:-latest}
 
+earthly --push +docker
 echo sed ../kubernetes/*-deployment.yaml -e \"'s#\(.*image: gitlab.inf.unibz.it:4567/.*:\).*#\1'"${VERSION}#"\"
diff --git a/dockerfiles/ubuntu-16.04.sources.list b/dockerfiles/ubuntu-16.04.sources.list
deleted file mode 100644
index 0e7283d3053ca70eff1cc1c191000c2e840cc6c3..0000000000000000000000000000000000000000
--- a/dockerfiles/ubuntu-16.04.sources.list
+++ /dev/null
@@ -1,4 +0,0 @@
-# http://layer0.authentise.com/docker-4-useful-tips-you-may-not-know-about.html
-deb mirror://mirrors.ubuntu.com/mirrors.txt xenial main restricted universe multiverse
-deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-updates main restricted universe multiverse
-deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-security main restricted universe multiverse
diff --git a/dspace-entrypoint.sh b/dspace-entrypoint.sh
deleted file mode 100644
index 4d6624c9b62669d28c3308bc2aa3e581c88c0368..0000000000000000000000000000000000000000
--- a/dspace-entrypoint.sh
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/bin/bash
-#
-# Wiki https://github.com/ufal/clarin-dspace/wiki/Installation
-#
-#
-
-MAJOR=0
-BUILD=2
-VERSION="${MAJOR}.${BUILD}"
-
-
-#set -ex
-
-# let's define some variables
-export DSPACE_INSTANCE_NAME=repository
-export DSPACE_SOURCE_DIRECTORY=/opt/repository/sources/dspace
-export DSPACE_WORKSPACE=/opt/repository/workspace
-export DSPACE_INSTALLATION_DIRECTORY=/opt/repository/installations
-
-AAI_CONFIGFILE="/opt/lindat-dspace/installation/webapps/xmlui/themes/UFAL/lib/js/aai_config.js"
-DSPACE_CONFIGFILE="$DSPACE_WORKSPACE/sources/local.properties"
-
-#
-# functions
-#
-_logger () {
-  MSG=$1
-  if [ ${DEBUG} ]; then
-    echo -ne "${MSG}"
-#  else
-#    echo -ne "${MSG}" >> ${LogFile}
-  fi
-}
-
-
-_loggerDate() {
-  _logger "[$(date)] $*"
-}
-
-
-_exit() {
-  if [ -z $1 ]; then
-    E_CODE=0
-  else
-    E_CODE=$1
-  fi
-  rm -rf ${TemporaryPath}
-  _loggerDate "Script completed\n"
-  exit ${E_CODE}
-}
-
-
-_printVersion() {
-  echo "${BASENAME} version ${VERSION}"
-}
-
-_printHelp() {
-  echo "${BASENAME}"
-  echo "Assembly some stuff, creating things..."
-  echo
-  echo "Supported options:"
-  echo "	-d|--debug	enable debug"
-  echo "	-V|--version	report program version"
-  echo "	-h|--help	print this help"
-  echo
-}
-
-_printComment () {
-  MSG=$1
-  echo "<"'!'"-- ${MSG} -->"
-}
-
-_checkenv () {
-set -x
- _loggerDate "Checking env variables "
- echo $*
- tot_args=$#
- echo $tot_args
- count=0
-  while [ "$1" ]
-   do
-     echo "."
-     shift
-     ((count++))
-  done
-  echo $tot_args $count
-  if [ "$tot_args" -ne "$count" ];then
-    exit 1
-  fi
-set +x
-}
-
-#
-# main script
-#
-
-# argument parsing
-while [ $1 ]; do
-  case $1 in
-    -d|--debug)      DEBUG=1
-                     shift
-                     ;;
-    -V|--version)    _printVersion
-                     exit 0
-                     ;;
-    -h|--help)       _printHelp
-                     exit 0
-                     ;;
-    -t|--test)       _notifyByIcingaPassiveCheck
-                     exit 0
-                     ;;
-    *)               _printHelp
-                     exit 0
-                     ;;
-  esac
-done
-
-_loggerDate "Starting ${BASENAME}\n"
-
-_loggerDate "Cloning lindat-dspace repository..."
-
-if [ ! -d $DSPACE_SOURCE_DIRECTORY ]
-then
- _logger "in $DSPACE_SOURCE_DIRECTORY \n"
- git clone https://github.com/ufal/lindat-dspace.git -b lindat $DSPACE_SOURCE_DIRECTORY
-else
- _logger "skip! $DSPACE_SOURCE_DIRECTORY already exists \n"
-fi
-
-cd $DSPACE_SOURCE_DIRECTORY/utilities/project_helpers
-
-_loggerDate "Creating workspace..."
-
-if [ ! -d $DSPACE_WORKSPACE ]
-then
- _logger "$DSPACE_WORKSPACE \n"
- ./setup.sh /opt/repository/workspace
-else
- _logger "skip! $DSPACE_WORKSPACE already exists \n"
-fi
-
-
-_loggerDate "Copy makefile..."
-if [ ! -f $DSPACE_WORKSPACE/config/variable.makefile ]
-then
-  cp /tmp/commul-customization/variable.makefile $DSPACE_WORKSPACE/config/
-  _logger "$DSPACE_WORKSPACE/config/variable.makefile\n"
-else
-  _logger "skip! $DSPACE_WORKSPACE/config/variable.makefile already exists\n"
-fi
-_loggerDate "Copy local.properties..."
-if [ ! -f $DSPACE_CONFIGFILE ]
-then
-  set -x
-  cp /tmp/commul-customization/local.properties $DSPACE_CONFIGFILE
-  set +x
-else
-  _logger "skip! $DSPACE_CONFIGFILE already exists\n"
-fi
-
-
-_loggerDate "Compilation and Deployment of DSpace..."
-cd $DSPACE_WORKSPACE/scripts/
-
-if [ ! -f  $DSPACE_WORKSPACE/scripts/install_libs.done ]
-then
-  make install_libs
-  touch $DSPACE_WORKSPACE/scripts/install_libs.done
-else
- _logger "already done \n"
-fi
-
-
-if [ ! -f  $DSPACE_WORKSPACE/scripts/fresh_install.done ]
-then
-  make compile
-  make fresh_install
-  touch $DSPACE_WORKSPACE/scripts/fresh_install.done
-else
- _logger "already done \n"
-fi
-
-if [ ! -f  $DSPACE_WORKSPACE/scripts/postinstall.done ]
-then
-  make postinstall
-  touch $DSPACE_WORKSPACE/scripts/postinstall.done
-  _logger "OK\n"
-else
- _logger "already done \n"
-fi
-
-_loggerDate "Copy aai_config.js..."
-if [ ! -f $AAI_CONFIGFILE ]
-then
-  set -x
-  cp /tmp/commul-customization/aai_config.js $AAI_CONFIGFILE
-  set +x
-else
-  _logger "skip! $AAI_CONFIGFILE already exists\n"
-fi
-
-_loggerDate "Create dspace admin..."
-if [ ! -f  $DSPACE_WORKSPACE/scripts/tomcatadmin.done ]
-then
-  su tomcat8 -c "/opt/lindat-dspace/installation/bin/dspace create-administrator"
-  touch $DSPACE_WORKSPACE/scripts/tomcatadmin.done
-  _logger "OK\n"
-else
- _logger "already done \n"
-fi
-
-_loggerDate "Starting Tomcat..."
-/etc/init.d/tomcat8 start
-sleep infinity
diff --git a/kubernetes/dspace-deployment.yaml b/kubernetes/dspace-deployment.yaml
index a8b0e6a277585b936b7b6cd24e897fd1b9f9067d..18479881f6126cd6cf22b1a3c6060b8f64af2674 100644
--- a/kubernetes/dspace-deployment.yaml
+++ b/kubernetes/dspace-deployment.yaml
@@ -56,7 +56,7 @@ spec:
             secretKeyRef:
               key: mail.pass
               name: dspace-secrets
-        image: gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/staging/dspace:1.3.6-RC1
+        image: gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/dspace-bundle/dspace:1.4.0-rc18
         name: clarin-dspace
         imagePullPolicy: Always
         ports:
@@ -68,15 +68,33 @@ spec:
         volumeMounts:
         - mountPath: /opt/lindat-dspace/installation/assetstore
           name: dspace-assetstore
+        - mountPath: /opt/lindat-dspace/installation/log
+          name: log-dspace
+        - mountPath: /opt/tomcat8/logs
+          name: log-tomcat
+        - mountPath: /opt/shibboleth-sp-fastcgi/var/log/shibboleth
+          name: log-shibboleth
+        readinessProbe:
+          httpGet:
+            path: /repository/xmlui/
+            port: 8080
+          initialDelaySeconds: 120
+          failureThreshold: 7
+          periodSeconds: 15
+          timeoutSeconds: 5
         livenessProbe:
           exec:
             command:
               - /bin/sh
               - -c
-              - reply=$(curl -s -o /dev/null -w %{http_code} https://clarin-dev.eurac.edu/repository/xmlui/); if [ "$reply" -lt 200 -o "$reply" -ge 400 ]; then exit 1; fi; ps aux | grep -v grep | grep -E "sleep|timeout" && exit 0 || exit 1;
-          initialDelaySeconds: 900
+              - REPLY=$(curl -s -o /dev/null -w %{http_code} https://clarin-dev.eurac.edu/repository/xmlui/);
+                [ "$REPLY" -lt 200 -o "$REPLY" -ge 400 ] && echo "REPLY was $REPLY" && exit 1;
+                ping -q -c3 -W3 postgres || exit 1;
+                ps aux | grep -v grep | grep -E "sleep|timeout" || exit 1;
+          initialDelaySeconds: 240
+          failureThreshold: 3
           periodSeconds: 15
-          timeoutSeconds: 3
+          timeoutSeconds: 10
       restartPolicy: Always
       imagePullSecrets:
         - name: gitlab-scientificnet-org-registry
@@ -93,4 +111,40 @@ spec:
               name: client.fs.commul.admin
             user: fs.commul.admin
           name: dspace-assetstore
+        - cephfs:
+            monitors:
+            - 10.8.55.201:6789
+            - 10.8.55.202:6789
+            - 10.8.55.203:6789
+            - 10.7.55.201:6789
+            - 10.7.55.202:6789
+            path: /eurac/commul/projects/clarin/kubernetes/dspace-dev/log/dspace
+            secretRef:
+              name: client.fs.commul.admin
+            user: fs.commul.admin
+          name: log-dspace
+        - cephfs:
+            monitors:
+            - 10.8.55.201:6789
+            - 10.8.55.202:6789
+            - 10.8.55.203:6789
+            - 10.7.55.201:6789
+            - 10.7.55.202:6789
+            path: /eurac/commul/projects/clarin/kubernetes/dspace-dev/log/tomcat
+            secretRef:
+              name: client.fs.commul.admin
+            user: fs.commul.admin
+          name: log-tomcat
+        - cephfs:
+            monitors:
+            - 10.8.55.201:6789
+            - 10.8.55.202:6789
+            - 10.8.55.203:6789
+            - 10.7.55.201:6789
+            - 10.7.55.202:6789
+            path: /eurac/commul/projects/clarin/kubernetes/dspace-dev/log/shibboleth
+            secretRef:
+              name: client.fs.commul.admin
+            user: fs.commul.admin
+          name: log-shibboleth
 status: {}
diff --git a/kubernetes/nginx-deployment.yaml b/kubernetes/nginx-deployment.yaml
index 51d512cd8e850bdf9b33dd4d2d23f4ef9b0a5596..f4254e721c1ecfe5ada5531eb5b81f3cb9fb5bb1 100644
--- a/kubernetes/nginx-deployment.yaml
+++ b/kubernetes/nginx-deployment.yaml
@@ -20,7 +20,7 @@ spec:
         io.kompose.service: nginx
     spec:
       containers:
-      - image: gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/staging/nginx:1.3.6-RC1
+      - image: gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/dspace-bundle/nginx:1.4.0-rc18
         imagePullPolicy: Always
         name: clarin-nginx
         ports:
@@ -32,6 +32,8 @@ spec:
         - mountPath: /etc/ssl/nginx
           name: nginx-ssl-certs
           readOnly: true
+        - mountPath: /opt/shibboleth-sp-fastcgi/var/log/shibboleth
+          name: log-shibboleth
         livenessProbe:
           httpGet:
             host: clarin-dev.eurac.edu
@@ -59,4 +61,16 @@ spec:
               name: client.fs.commul.admin
             user: fs.commul.admin
           name: nginx-shib-certs
+        - cephfs:
+            monitors:
+            - 10.8.55.201:6789
+            - 10.8.55.202:6789
+            - 10.8.55.203:6789
+            - 10.7.55.201:6789
+            - 10.7.55.202:6789
+            path: /eurac/commul/projects/clarin/kubernetes/dspace-dev/log/shibboleth
+            secretRef:
+              name: client.fs.commul.admin
+            user: fs.commul.admin
+          name: log-shibboleth
 status: {}
diff --git a/kubernetes/postgres-deployment.yaml b/kubernetes/postgres-deployment.yaml
index b878e95d59028435fcf88a1213cc21b72eeeee17..052a194a8db8953ef1df039b272913b67f0a5bae 100644
--- a/kubernetes/postgres-deployment.yaml
+++ b/kubernetes/postgres-deployment.yaml
@@ -48,7 +48,7 @@ spec:
             secretKeyRef:
               key: dspace.utils.name
               name: dspace-secrets
-        image: gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/staging/postgres:1.3.6-RC1
+        image: gitlab.inf.unibz.it:4567/commul/docker/clarin-dspace/dspace-bundle/postgres:1.4.0-rc18
         imagePullPolicy: Always
         name: clarin-postgres
         resources: {}