diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e27991ebf8822ddb357c4dbc44c51e54e237a3d..4467ece33e62e9f29dac413c1828847ed9b766c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## new in jupyter-openbis-extension 0.4.0
+
+- made it compatible to pybis-1.9.x
+- minor bugfixes and improvements
+
+## new in jupyter-openbis-extension 0.3.0
+
+- removed search-as-you-type feature, as it is not mature yet
+- fixed notebook path problem in special environments
+- improved download path
+- connection dialog: show that connection is being established
+- upload dialog: improved file chooser
+- upload dialog: save notebook automatically before upload
+
 ## new in jupyter-openbis-extension 0.2.4
 
 - improved entity selection
diff --git a/jupyter-openbis-extension/__init__.py b/jupyter-openbis-extension/__init__.py
index d3d298723cee99d050e7464c5bac6a4660c7483d..c4c2f3ea1bd3b4b9375e676f33f3c6fd73ebcab2 100644
--- a/jupyter-openbis-extension/__init__.py
+++ b/jupyter-openbis-extension/__init__.py
@@ -1,7 +1,7 @@
 name = 'jupyter-openbis-extension.server'
 __author__ = 'Swen Vermeul'
 __email__ = 'swen@ethz.ch'
-__version__ = '0.2.4'
+__version__ = '0.4.0'
 
 def _jupyter_server_extension_paths():
     return [{
diff --git a/jupyter-openbis-extension/connection.py b/jupyter-openbis-extension/connection.py
index be36cbb321ce71e2b164d9d06762937d18912706..557bc4966487975ee684799b4d2e2473fe4264ac 100644
--- a/jupyter-openbis-extension/connection.py
+++ b/jupyter-openbis-extension/connection.py
@@ -12,6 +12,7 @@ def register_connection(connection_info):
         verify_certificates = connection_info.get('verify_certificates', False),
         username            = connection_info.get('username'),
         password            = connection_info.get('password'),
+        http_only           = connection_info.get('http_only', False),
         status              = 'not connected',
     )
     openbis_connections[conn.name] = conn
@@ -32,7 +33,8 @@ class OpenBISConnection:
 
         openbis = Openbis(
             url = self.url,
-            verify_certificates = self.verify_certificates
+            verify_certificates = self.verify_certificates,
+            allow_http_but_do_not_use_this_in_production_and_only_within_safe_networks = self.http_only
         )
         self.openbis = openbis
         self.status = "not connected"
@@ -71,6 +73,14 @@ class OpenBISConnection:
 
 class OpenBISConnections(IPythonHandler):
 
+    def _notebook_dir(self):
+        notebook_dir = os.getcwd()
+        if 'SingleUserNotebookApp' in self.config and 'notebook_dir' in self.config.SingleUserNotebookApp:
+            notebook_dir = self.config.SingleUserNotebookApp.notebook_dir
+        elif 'notebook_dir' in self.config.NotebookApp:
+            notebook_dir = self.config.NotebookApp.notebook_dir
+        return notebook_dir
+
     def post(self):
         """create a new connection
 
@@ -96,9 +106,9 @@ class OpenBISConnections(IPythonHandler):
             connections.append(conn.get_info())
 
         self.write({
-            'status'     : 200,
-            'connections': connections,
-            'cwd'        : os.getcwd()
+            'status'       : 200,
+            'connections'  : connections,
+            'notebook_dir' : self._notebook_dir()
         })
         return
 
@@ -107,6 +117,14 @@ class OpenBISConnectionHandler(IPythonHandler):
     """Handle the requests to /openbis/conn
     """
 
+    def _notebook_dir(self):
+        notebook_dir = os.getcwd()
+        if 'SingleUserNotebookApp' in self.config and 'notebook_dir' in self.config.SingleUserNotebookApp:
+            notebook_dir = self.config.SingleUserNotebookApp.notebook_dir
+        elif 'notebook_dir' in self.config.NotebookApp:
+            notebook_dir = self.config.NotebookApp.notebook_dir
+        return notebook_dir
+
     def put(self, connection_name):
         """reconnect to a current connection
         :return: an updated connection object
@@ -136,11 +154,16 @@ class OpenBISConnectionHandler(IPythonHandler):
                 "reason": "Incorrect username or password for {}".format(connection_name)
             })
             return
+        except Exception:
+            self.set_status(500)
+            self.write({
+                "reason": "General Network Error"
+            })
 
         self.write({
             'status'     : 200,
-            'connection': conn.get_info(),
-            'cwd'        : os.getcwd()
+            'connection' : conn.get_info(),
+            ''           : self._notebook_dir()
         })
 
     def get(self, connection_name):
@@ -159,9 +182,10 @@ class OpenBISConnectionHandler(IPythonHandler):
         conn.check_status()
 
         self.write({
-            'status'     : 200,
-            'connection': conn.get_info(),
-            'cwd'        : os.getcwd()
+            'status'        : 200,
+            'connection'    : conn.get_info(),
+            'noteboook_dir' : self._notebook_dir()
         })
         return
 
+
diff --git a/jupyter-openbis-extension/dataset.py b/jupyter-openbis-extension/dataset.py
index 91c6a89488dead78c42bef4fba4292b6122bfdf3..884c519c1a5159ab260f73208b55dae2dc3e0069 100644
--- a/jupyter-openbis-extension/dataset.py
+++ b/jupyter-openbis-extension/dataset.py
@@ -6,7 +6,6 @@ from .connection import openbis_connections
 class DataSetDownloadHandler(IPythonHandler):
     """Handle the requests for /openbis/dataset/connection/permId"""
 
-
     def download_data(self, conn, permId, downloadPath=None):
         if not conn.is_session_active():
             try:
@@ -46,6 +45,7 @@ class DataSetDownloadHandler(IPythonHandler):
             'dataStore' : dataset.dataStore,
             'location'  : dataset.physicalData.location,
             'size'      : dataset.physicalData.size,
+            'files'     : dataset.file_list,
             'statusText': 'Data for DataSet {} was successfully downloaded to: {}.'.format(dataset.permId, path)
         })
 
@@ -69,6 +69,15 @@ class DataSetDownloadHandler(IPythonHandler):
 class DataSetTypesHandler(IPythonHandler):
     def get(self, **params):
         """Handle a request to /openbis/datasetTypes/connection_name
+        This meta-metadata is used in the dataset upload dialog (uploadDialog.js)
+        to check data directly in the UI
+
+        Returns all datasetTypes of a given connection
+        - with all assigned properties
+        - with some details about the property types
+        - with the vocabulary, if exists
+
+        The result will be cached, as it is a costly operation with many fetches
         """
 
         try:
@@ -80,26 +89,44 @@ class DataSetTypesHandler(IPythonHandler):
             })
             return
 
+        if getattr(conn, 'dataset_types', False):
+            self.write({
+                "dataSetTypes": conn.dataset_types
+            })
+            return
+
         try:
             dataset_types = conn.openbis.get_dataset_types()
-            dts = dataset_types.df.to_dict(orient='records')
-
-            # get property assignments for every dataset-type
-            # and add it to the dataset collection
-            for dt in dts:
-                dataset_type = conn.openbis.get_dataset_type(dt['code'])
-                pa = dataset_type.get_propertyAssignments(including_vocabulary=True)
-                pa_dicts = pa.to_dict(orient='records')
-                for pa_dict in pa_dicts:
-                    if pa_dict['dataType'] == 'CONTROLLEDVOCABULARY':
-                        terms = conn.openbis.get_terms(pa_dict['vocabulary']['code'])
-                        pa_dict['terms'] = terms.df[['code','label','description','official','ordinal']].to_dict(orient='records')
 
-                dt['propertyAssignments'] = pa_dicts
+            # get all dataset types
+            ds_type_dicts = []
+            for dt in conn.openbis.get_dataset_types():
+                dt_dict = dt.attrs.all()
+                # get property assignments for every dataset-type
+                # and add them in the key «propertyAssignments»
+                pas = dt.get_property_assignments()
+                pa_dicts = pas.df[['propertyType','mandatory','ordinal','section']].to_dict(orient='records')
+                dt_dict['propertyAssignments'] = pa_dicts
+
+                for pa_dict in pa_dicts:
+                    # add a few more attributes to the property assignments
+                    pt = conn.openbis.get_property_type(pa_dict['propertyType'])
+                    pa_dict['code'] = pt.code
+                    pa_dict['label'] = pt.label
+                    pa_dict['description'] = pt.description
+                    pa_dict['dataType'] = pt.dataType
+                    # add vocabulary, if exists, as key «terms»
+                    if pt.dataType == 'CONTROLLEDVOCABULARY':
+                        terms = conn.openbis.get_terms(pt.vocabulary)
+                        terms_dict = terms.df[['code','label','description','official','ordinal']].to_dict(orient='records')
+                        pa_dict['terms'] = terms_dict
+
+                ds_type_dicts.append(dt_dict)
 
             self.write({
-                "dataSetTypes": dts
+                "dataSetTypes": ds_type_dicts
             })
+            conn.dataset_types = ds_type_dicts
             return
 
         except Exception as e:
@@ -114,6 +141,14 @@ class DataSetTypesHandler(IPythonHandler):
 class DataSetUploadHandler(IPythonHandler):
     """Handle the POST requests for /openbis/dataset/connection_name"""
 
+    def _notebook_dir(self):
+        notebook_dir = os.getcwd()
+        if 'SingleUserNotebookApp' in self.config and 'notebook_dir' in self.config.SingleUserNotebookApp:
+            notebook_dir = self.config.SingleUserNotebookApp.notebook_dir
+        elif 'notebook_dir' in self.config.NotebookApp:
+            notebook_dir = self.config.NotebookApp.notebook_dir
+        return notebook_dir
+
     def upload_data(self, conn, data):
         if not conn.is_session_active():
             try:
@@ -165,13 +200,15 @@ class DataSetUploadHandler(IPythonHandler):
                     })
 
         filenames = []
+        notebook_dir = self._notebook_dir()
         for filename in data.get('files'):
             filename = unquote(filename)
-            if os.path.isfile(filename):
-                filenames.append(filename)
+            full_filename_path = os.path.join(notebook_dir, filename)
+            if os.path.isfile(full_filename_path):
+                filenames.append(full_filename_path)
             else:
                 errors.append({
-                    "file": "File not found: {}".format(filename)
+                    "file": "File not found: {}".format(full_filename_path)
                 })
 
         try:
@@ -183,9 +220,9 @@ class DataSetUploadHandler(IPythonHandler):
                 files  = filenames,
             )
         except Exception as e:
-            print(e)
-            errors.append({
-                "create": 'Error while creating the dataset: {}'.format(e)
+            self.set_status(500)
+            self.write({
+                "reason": 'Error while creating the dataset: {}'.format(e)
             })
 
         # try to set the properties
@@ -249,34 +286,3 @@ class DataSetUploadHandler(IPythonHandler):
         self.upload_data(conn=conn,data=data)
 
 
-class FileListHandler(IPythonHandler):
-
-    def get(self, **params):
-        """
-        Returns the file list of the current working directory
-
-        :param params:
-        :return: dictionary of files, key is the fully qualified name,
-                 value is the relative name (for display)
-        """
-
-        cwd = os.getcwd()
-        files = {}
-        for (dirpath, dirnames, filenames) in os.walk(cwd):
-            if filenames:
-                for filename in filenames:
-                    # ignore hidden files
-                    if filename.startswith('.'):
-                        continue
-                    # ignore hidden folders
-                    if os.path.relpath(dirpath) != '.' \
-                            and os.path.relpath(dirpath).startswith('.'):
-                        continue
-                    fqn = os.path.join(dirpath, filename)
-                    files[fqn] = os.path.relpath(fqn, cwd)
-
-        self.set_status(200)
-        self.write({
-            "files": files
-        })
-
diff --git a/jupyter-openbis-extension/server.py b/jupyter-openbis-extension/server.py
index 97d4909c5b85e9b1b1b5358257a6e933b0599a0b..6d95bd59f0cf163c1bc92f74ede90df13e633634 100644
--- a/jupyter-openbis-extension/server.py
+++ b/jupyter-openbis-extension/server.py
@@ -3,7 +3,7 @@ import os
 import yaml
 
 from .connection import OpenBISConnections, OpenBISConnectionHandler, register_connection
-from .dataset import DataSetTypesHandler, DataSetDownloadHandler, DataSetUploadHandler, FileListHandler
+from .dataset import DataSetTypesHandler, DataSetDownloadHandler, DataSetUploadHandler
 from .sample import SampleHandler
 
 
@@ -48,6 +48,7 @@ def load_jupyter_server_extension(nb_server_app):
         filename = 'openbis-connections.yaml'
     )
 
+
     for connection_info in connections:
         conn = register_connection(connection_info)
         print("Registered: {}".format(conn.url))
@@ -66,14 +67,6 @@ def load_jupyter_server_extension(nb_server_app):
     host_pattern = '.*$'
     base_url = web_app.settings['base_url']
 
-    # get the file list
-    web_app.add_handlers(
-        host_pattern,
-        [(url_path_join( base_url, '/general/filelist'),
-            FileListHandler
-        )]
-    )
-
 
     # DataSet download
     web_app.add_handlers(
@@ -139,3 +132,4 @@ def load_jupyter_server_extension(nb_server_app):
     )
 
 
+
diff --git a/jupyter-openbis-extension/static/common.js b/jupyter-openbis-extension/static/common.js
index 15280a1e178c749e5e17292270e226bd061452ca..edcb4af10533d72158d37de5d428a2d27025c3a5 100644
--- a/jupyter-openbis-extension/static/common.js
+++ b/jupyter-openbis-extension/static/common.js
@@ -39,9 +39,18 @@ define([
             return "";
         }
 
+        function createErrorElement() {
+            var element = document.createElement("STRONG")
+            element.textContent = ""
+            element.style.marginLeft = "8px"
+            element.style.color = "red"
+            return element
+        }
+
         return {
             createFeedback: createFeedback,
-            getCookie: getCookie
+            getCookie: getCookie,
+            createErrorElement: createErrorElement
         }
     }
 )
\ No newline at end of file
diff --git a/jupyter-openbis-extension/static/connectionDialog.js b/jupyter-openbis-extension/static/connectionDialog.js
index 40c88225a504b0971efb6bb05afcbed4a8c652da..c8d01ab61e699f759c8569df0dea540df3242bf2 100644
--- a/jupyter-openbis-extension/static/connectionDialog.js
+++ b/jupyter-openbis-extension/static/connectionDialog.js
@@ -7,34 +7,35 @@ define(
     ],
     function (dialog, $, state, connections) {
 
-        var currentDownloadPath = null
+        let currentDownloadPath = null;
 
         function show_available_connections(env, data, conn_table) {
+
             if (!currentDownloadPath) {
                 currentDownloadPath = data.cwd
             }
 
-            var table = document.createElement("TABLE")
+            let table = document.createElement("TABLE");
             table.className = 'table-bordered table-striped table-condensed'
-            var thead = table.createTHead()
-            var thead_row = thead.insertRow(0)
-            var titles = ['', 'Name', 'URL', 'Status', 'Username / Password']
+            let thead = table.createTHead();
+            let thead_row = thead.insertRow(0)
+            let titles = ['', 'Name', 'URL', 'Status', 'Username / Password']
             for (title of titles) {
                 thead_row.insertCell().textContent = title
             }
 
             tbody = table.createTBody()
 
-            var getConnectionByName = function(name) {
-            	for (connection of data.connections) {
-            		if(connection.name === name) {
-            			return connection;
-            		}
-            	}
-            }
-            
+            let getConnectionByName = function (name) {
+                for (connection of data.connections) {
+                    if (connection.name === name) {
+                        return connection;
+                    }
+                }
+            };
+
             for (connection of data.connections) {
-                var conn = document.createElement("INPUT")
+                let conn = document.createElement("INPUT")
                 conn.type = "radio"
                 conn.name = "connection_name"
                 conn.value = connection.name
@@ -46,14 +47,28 @@ define(
                 	state.connection.candidateDTO = getConnectionByName(state.connection.candidateName);
                 }
 
-                var row = tbody.insertRow()
+                let row = tbody.insertRow()
                 row.insertCell().appendChild(conn)
-                row.insertCell().textContent = connection.name
-                row.insertCell().textContent = connection.url
+                let nameCell = row.insertCell()
+                nameCell.textContent = connection.name
+                nameCell.onclick = function () {
+                    let radio = this.parentElement.firstElementChild.firstElementChild
+                    radio.checked = 1
+                    state.connection.candidateName = radio.value
+                    state.connection.candidateDTO = getConnectionByName(state.connection.candidateName);
+                }
+                let urlCell = row.insertCell()
+                urlCell.textContent = connection.url
+                urlCell.onclick = function () {
+                    let radio = this.parentElement.firstElementChild.firstElementChild
+                    radio.checked = 1
+                    state.connection.candidateName = radio.value
+                    state.connection.candidateDTO = getConnectionByName(state.connection.candidateName);
+                }
 
-                var status_cell = row.insertCell()
+                let status_cell = row.insertCell()
 
-                var status_badge = document.createElement("SPAN")
+                let status_badge = document.createElement("SPAN")
                 status_badge.id = connection.name + "-badge"
                 status_badge.textContent = connection.status
                 if (connection.status === "connected") {
@@ -63,31 +78,33 @@ define(
                 }
                 status_cell.appendChild(status_badge)
 
-                var username = document.createElement("INPUT")
+                let username = document.createElement("INPUT")
                 username.type = "text"
                 username.name = "username"
                 username.autocomplete = "on"
                 username.value = connection.username
                 username.setAttribute("form", connection.name)
 
-                var password = document.createElement("INPUT")
+                let password = document.createElement("INPUT")
                 password.type = "password"
                 password.name = "password"
                 password.autocomplete = "current-password"
                 password.value = connection.password
                 password.setAttribute("form", connection.name)
 
+
                 // Username / Password form
-                var pwform = document.createElement("FORM")
+                let pwform = document.createElement("FORM")
                 pwform.id = connection.name
                 pwform.onsubmit = function (event) {
-                    var form_data = new FormData(this)
-                    var status_badge = document.getElementById(this.id + "-badge")
+                    let form_data = new FormData(this)
+                    let status_badge = document.getElementById(this.id + "-badge")
+                    status_badge.textContent = "connecting..."
+                    status_badge.className = "label label-warning"
                     connections.connect(env, this.id,
                             form_data.get("username"), form_data.get("password")
                         )
                         .then(function (response) {
-                            //console.log(response)
                             if (status_badge.nextElementSibling !== null) {
                                 status_badge.parentNode.removeChild(status_badge.nextElementSibling)
                             }
@@ -114,7 +131,7 @@ define(
                 }
 
 
-                var connect_button = document.createElement("BUTTON")
+                let connect_button = document.createElement("BUTTON")
                 connect_button.className = "btn btn-primary btn-xs"
                 connect_button.textContent = "connect"
 
@@ -122,17 +139,24 @@ define(
                 pwform.appendChild(password)
                 pwform.appendChild(connect_button)
 
-                var cell = row.insertCell()
-                cell.appendChild(pwform)
+                let pwCell = row.insertCell()
+                pwCell.appendChild(pwform)
+
+                pwCell.onclick = function () {
+                    let radio = this.parentElement.firstElementChild.firstElementChild
+                    radio.checked = 1
+                    state.connection.candidateName = radio.value
+                    state.connection.candidateDTO = getConnectionByName(state.connection.candidateName);
+                }
             }
 
             // add row for new connection
-            var row = tbody.insertRow()
+            let row = tbody.insertRow()
 
-            var conn_form = document.createElement("FORM")
+            let conn_form = document.createElement("FORM")
             conn_form.id = "new_connection"
             conn_form.onsubmit = function (event) {
-                var inputs = document.querySelectorAll("input[form=new_connection]")
+                let inputs = document.querySelectorAll("input[form=new_connection]")
 
                 data = {}
                 for (input of inputs) {
@@ -155,7 +179,7 @@ define(
                     })
                 return false
             }
-            var conn_name = document.createElement("INPUT")
+            let conn_name = document.createElement("INPUT")
             conn_name.type = "input"
             conn_name.name = "connection_name"
             conn_name.setAttribute("form", conn_form.id)
@@ -163,7 +187,7 @@ define(
             row.insertCell().appendChild(conn_form)
             row.insertCell().appendChild(conn_name)
 
-            var conn_url = document.createElement("INPUT")
+            let conn_url = document.createElement("INPUT")
             conn_url.type = "input"
             conn_url.name = "url"
             conn_url.setAttribute("form", conn_form.id)
@@ -171,30 +195,68 @@ define(
             row.insertCell().appendChild(conn_url)
             row.insertCell()
 
-            var username = document.createElement("INPUT")
+            let username = document.createElement("INPUT")
             username.autocomplete = "off"
             username.type = "text"
             username.name = "username"
             username.setAttribute("form", conn_form.id)
             username.placeholder = "username"
-            var password = document.createElement("INPUT")
+            let password = document.createElement("INPUT")
             password.type = "password"
             password.name = "password"
             password.autocomplete = "new-password"
             password.setAttribute("form", conn_form.id)
-            var create_btn = document.createElement("BUTTON")
+            let create_btn = document.createElement("BUTTON")
             create_btn.setAttribute("form", conn_form.id)
             create_btn.textContent = "create"
-            var uname_pw_cell = row.insertCell()
+            let uname_pw_cell = row.insertCell()
             uname_pw_cell.appendChild(username)
             uname_pw_cell.appendChild(password)
             uname_pw_cell.appendChild(create_btn)
 
             conn_table.innerHTML = ""
-            table_title = document.createElement("STRONG")
+            let table_title = document.createElement("STRONG")
             table_title.textContent = "Please choose a connection"
+
+            let working_dir_title = document.createElement("STRONG")
+            working_dir_title.textContent = "Your working directory "
+            let working_dir_in = document.createElement("INPUT")
+            working_dir_in.type = "text"
+            working_dir_in.name = "working_dir"
+            working_dir_in.autocomplete = "on"
+            working_dir_in.style.width = "100%"
+
+
+            // calculate the default working directory
+            // by combining the notebook_dir (from the jupyter configuration) and the relative notebook_path
+            let re = new RegExp(env.notebook.notebook_name+"$")
+            rel_path = env.notebook.notebook_path.replace(re, "")
+            let default_working_dir = ""
+            if (data.notebook_dir.endsWith('/')) {
+                default_working_dir = data.notebook_dir + rel_path
+            }
+            else {
+                default_working_dir = data.notebook_dir + "/" + rel_path
+            }
+
+            working_dir_in.value = state.working_dir ? state.working_dir : default_working_dir
+            state.working_dir_element = working_dir_in
+
+            let working_dir_reset = document.createElement("A")
+            working_dir_reset.className = "btn"
+            working_dir_reset.innerText = "reset to default"
+            working_dir_reset.onclick = function() {
+                working_dir_in.value = default_working_dir
+            }
+
             conn_table.appendChild(table_title)
             conn_table.appendChild(table)
+
+            conn_table.appendChild(working_dir_title)
+            conn_table.appendChild(working_dir_reset)
+            conn_table.appendChild(document.createElement("BR"))
+            conn_table.append(working_dir_in)
+
         }
 
         return {
@@ -203,13 +265,12 @@ define(
             help_index: '',
             handler: function (env) {
                 conn_table = document.createElement("DIV")
-                var dst_title = document.createElement("STRONG")
+                let dst_title = document.createElement("STRONG")
                 dst_title.textContent = "DataSet type"
-                var dataset_types = document.createElement("SELECT")
+                let dataset_types = document.createElement("SELECT")
                 dataset_types.id = "dataset_type"
                 dataset_types.className = "form-control select-xs"
 
-                var input_fields = document.createElement("DIV")
                 conn_table.id = "openbis_connections"
 
                 connections.list(env)
@@ -220,11 +281,12 @@ define(
                         alert(data.status)
                     })
 
-                var uploadDialogBox = $('<div/>').append(conn_table)
+                let uploadDialogBox = $('<div/>').append(conn_table)
 
                 function onOk() {
                     state.connection.name = state.connection.candidateName
                     state.connection.dto = state.connection.candidateDTO
+                    state.working_dir = state.working_dir_element.value
                 }
 
                 function onCancel() {
@@ -250,4 +312,4 @@ define(
             }
         }
     }
-)
\ No newline at end of file
+)
diff --git a/jupyter-openbis-extension/static/downloadDialog.js b/jupyter-openbis-extension/static/downloadDialog.js
index b948043a7f2c414249b059b0513df21177ad0239..bd251b818e18358f47e3837ded8fe8848461ffe4 100644
--- a/jupyter-openbis-extension/static/downloadDialog.js
+++ b/jupyter-openbis-extension/static/downloadDialog.js
@@ -3,15 +3,16 @@ define([
         "jquery",
         "./common",
         "./state",
-        "./entitySearcher"
+        //"./entitySearcher"
     ],
-    function (dialog, $, common, state, entitySearcher) {
+    function (dialog, $, common, state) {
 
         var spinner = document.createElement("IMG")
         spinner.className="openbis-feedback"
         spinner.src=""
         function showSpinner() {
-            spinner.src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.5.8/ajax-loader.gif"
+            var userName = window.location.pathname.split("/")[2];
+            spinner.src = '/user/' + userName+ '/nbextensions/jupyter-openbis-extension/spinner.gif'
         }
         function hideSpinner() {
             spinner.src=""
@@ -30,16 +31,13 @@ define([
                     "dataStore": data.dataStore,
                     "location": data.location,
                     "size": data.size,
+                    "files": data.files,
                     "status": data.statusText
                 }
             }
         }
 
         function show_datasets_table(env, data, datasets_table, pagingContainer, downloadPath, entityIdentifier) {
-            if (downloadPath.value === '') {
-                downloadPath.value = data.cwd
-            }
-
             var table = document.createElement("TABLE")
             table.className = "table-bordered table-striped table-condensed text-nowrap"
             table.style.width = "100%"
@@ -87,25 +85,45 @@ define([
             const previousCmd = () => getDatasets(env, startWith-5, 5, entityIdentifier, datasets_table, pagingContainer, downloadPath)
 
             var previous = document.createElement("A")
-            var linkText = document.createTextNode("<<< Previous")
-            previous.appendChild(linkText)
-            previous.href = "#"
-            previous.onclick = previousCmd
+            previous.className = "fas fa fa-caret-left fa-2x"
+            previous.style.verticalAlign="middle"
+            if (hasPrevious) {
+                previous.href = "#"
+                previous.onclick = previousCmd
+            }
 
             var next = document.createElement("A")
-            var linkText = document.createTextNode("Next >>>")
-            next.appendChild(linkText)
-            next.href = "#"
-            next.onclick = nextCmd
-            next.style.float="right"
+            next.className = "fas fa fa-caret-right fa-2x"
+            next.style.verticalAlign = "middle"
+            if (hasNext) {
+                next.href = "#"
+                next.onclick = nextCmd
+            }
+
+            var countStr = document.createElement("STRONG")
+            var until = startWith + count > totalCount ? totalCount : startWith + count
+            var startWithStr = startWith + 1
+            countStr.innerHTML = startWithStr + "&ndash;" + until + "/" + totalCount
+            countStr.style.paddingLeft = "10px"
+            countStr.style.paddingRight = "10px"
+            countStr.style.verticalAlign="middle"
 
             var paging = document.createElement("DIV")
             paging.style.width = "100%"
+            paging.appendChild(previous)
             if (hasPrevious) {
-                paging.appendChild(previous)
+                previous.style.color = "inherit"
+            }
+            else {
+                previous.style.color="transparent"
             }
+            paging.appendChild(countStr)
+            paging.appendChild(next)
             if (hasNext) {
-                paging.appendChild(next)
+                next.style.color="inherit"
+            }
+            else {
+                next.style.color="transparent"
             }
 
             while (pagingContainer.firstChild) {
@@ -121,7 +139,7 @@ define([
                 return false
             }
 
-            currentEntityIdentifier = entityIdentifier.firstChild.value
+            currentEntityIdentifier = entityIdentifier.value
             if (!currentEntityIdentifier) {
                 alert('Please specify an Entity identifier/permId')
                 return false
@@ -158,10 +176,11 @@ define([
 
 
         return {
-            help: 'Download openBIS datasets to your local harddrive',
+            help: 'Download openBIS datasets',
             icon: 'fa-download',
             help_index: '',
             handler: function (env) {
+                console.log(env);
                 state.selectedDatasets = new Set([])
 
                 conn_table = document.createElement("DIV")
@@ -173,7 +192,13 @@ define([
                 showDataSets.appendChild(title)
                 showDataSets.style.marginTop = '10px'
 
-                var entityIdentifier = entitySearcher.getEntitySearcherForDownload(state)
+                var entityIdentifier = document.createElement("INPUT")
+                entityIdentifier.type = "text"
+                entityIdentifier.name = "entityIdentifier"
+                entityIdentifier.size = 40
+                entityIdentifier.placeholder = "Sample or Experiment identifier/permId"
+                entityIdentifier.value = state.entityIdentifier ? state.entityIdentifier : ""
+
 
                 var datasets_table = document.createElement("DIV")
                 var pagingContainer = document.createElement("DIV")
@@ -185,8 +210,9 @@ define([
 
                 showDataSets.appendChild(entityIdentifier)
                 showDataSets.appendChild(show_datasets_btn)
-                showDataSets.appendChild(datasets_table)
                 showDataSets.appendChild(pagingContainer)
+                showDataSets.appendChild(document.createElement('BR'))
+                showDataSets.appendChild(datasets_table)
 
                 var dataset_direct = document.createElement("P")
                 dataset_direct.style.marginTop = '10px'
@@ -204,25 +230,39 @@ define([
                 downloadPath.type = "text"
                 downloadPath.name = "downloadPath"
                 downloadPath.size = "90"
-                downloadPath.value = state.workingDirectory
+                downloadPath.value = state.download_dir ? state.download_dir : state.working_dir
 
-                show_datasets_btn.onclick = 
+                show_datasets_btn.onclick =
                     () => getDatasets(env, 0, 5, entityIdentifier, datasets_table, pagingContainer, downloadPath)
-                
+
+
                 var path = document.createElement("DIV")
                 path.innerHTML = "<strong>download data to path: </strong>"
                 path.appendChild(downloadPath)
 
                 var download_dialog_box = document.createElement("DIV")
+
+                let mainError = common.createErrorElement()
+                if (!state.connection.name) {
+                    mainError.textContent = "Please choose a connection first."
+                    //mainError.textContent = "Network problem: please check your connection first."
+                }
+                download_dialog_box.appendChild(mainError)
                 download_dialog_box.appendChild(spinner)
                 download_dialog_box.appendChild(conn_table)
                 download_dialog_box.appendChild(showDataSets)
                 download_dialog_box.appendChild(dataset_direct)
                 download_dialog_box.appendChild(path)
 
-                function saveState() {
+                function onOk() {
+                    state.entityIdentifier = entityIdentifier.value
+                    state.directPermId = datasetPermId.value
+                    state.download_dir = downloadPath.value
+                }
+
+                function onCancel() {
+                    state.entityIdentifier = entityIdentifier.value
                     state.directPermId = datasetPermId.value
-                    state.workingDirectory = downloadPath.value
                 }
 
                 function downloadDataset(connection_name, selectedPermIds, downloadPath) {
@@ -252,7 +292,8 @@ define([
                                             // keep current download path for later use
                                             currentDownloadPath = downloadPath
                                         })
-                                } else {
+                                }
+                                else {
                                     response.json()
                                         .then(function (error) {
                                             console.log(error.reason)
@@ -292,7 +333,7 @@ define([
 
                     downloadDataset(selected_conn, selectedPermIds, downloadPath.value)
                     showSpinner()
-                    saveState()
+                    onOk()
                     return false
                 }
 
@@ -301,7 +342,7 @@ define([
                     title: 'Download openBIS DataSets',
                     buttons: {
                         'Cancel': {
-                            click: () => saveState()
+                            click: () => onCancel()
                         },
                         'Download': {
                             class: 'btn-primary btn-large',
diff --git a/jupyter-openbis-extension/static/entitySearcher.js b/jupyter-openbis-extension/static/entitySearcher.js
index 889db406d2be343c36739cf6107c6ed26a4c455a..70cf4c29922d9f1d07cc8f47e1b5dadd7bcc0124 100644
--- a/jupyter-openbis-extension/static/entitySearcher.js
+++ b/jupyter-openbis-extension/static/entitySearcher.js
@@ -64,24 +64,34 @@ define(["jquery", "./jquery-select2/js/select2.min"],
                 element.innerHTML = "<span style='color:orange;margin:5px'>loading...</span>"
                 if (!state.openbisService) {
                     require.config(this.getRequireJSV3Config(state.connection.dto.url))
-                    require(["openbis", "as/dto/experiment/search/ExperimentSearchCriteria", 
-                             "as/dto/experiment/fetchoptions/ExperimentFetchOptions",
-                             "as/dto/sample/search/SampleSearchCriteria",
-                             "as/dto/sample/fetchoptions/SampleFetchOptions"], function(openbis) {
+                    require(["openbis", "as/dto/experiment/search/ExperimentSearchCriteria",
+                        "as/dto/experiment/fetchoptions/ExperimentFetchOptions",
+                        "as/dto/sample/search/SampleSearchCriteria",
+                        "as/dto/sample/fetchoptions/SampleFetchOptions"],
+
+                        function (openbis) {
                         var apiUrl = state.connection.dto.url + "/openbis/openbis/rmi-application-server-v3.json"
                         var v3 = new openbis(apiUrl)
                         v3.login(state.connection.dto.username, state.connection.dto.password)
-                            .done(function(sessionToken) {
+                            .done(function (sessionToken) {
+                                console.log("sessionToken heisst:");
+                                console.log(sessionToken);
                                 state.openbisService = v3
-                                _this.loadResource("/nbextensions/openbis/jquery-select2/css/select2.min.css", 'css', function() {
-                                    _this.createDropdown(element, state, upload)
-                                })
-                            }).fail(function(result) {
-                                alert('openbis v3 service login failed for ' + apiUrl 
-                                        + " : property 'trusted-cross-origin-domains' is probably not set in service.properties.")
+                                var userName = window.location.pathname.split("/")[2];
+                                //_this.loadResource('/user/' + userName+ '/nbextensions/jupyter-openbis-extension/jquery-select2/css/select2.min.css', 'css', function() {
+                                _this.createDropdown(element, state, upload)
+                                //})
                             })
+                            .fail(function (result) {
+                                alert('openbis v3 service login failed for ' + apiUrl
+                                + " : property 'trusted-cross-origin-domains' is probably not set in service.properties.")
+                        })
+                    },
+                    function (err){
+                        alert('failed to load required libraries')
                     })
-                } else {
+                }
+                else {
                     _this.createDropdown(element, state, upload)
                 }
 
diff --git a/jupyter-openbis-extension/static/state.js b/jupyter-openbis-extension/static/state.js
index 71ea8e23d5a13982ed94c120171ef2e9674048d1..bcbe83fe121570577138ac2a503ac24d91bd5951 100644
--- a/jupyter-openbis-extension/static/state.js
+++ b/jupyter-openbis-extension/static/state.js
@@ -8,6 +8,9 @@ define([],
                 candidateName: null,
                 candidateDTO: null
             },
+            working_dir: null,
+            working_dir_element: null,
+            download_dir: null,
 
             // upload dialog
             uploadDataSetType: null,
@@ -21,7 +24,6 @@ define([],
             // download dialog
             selectedDatasets: new Set([]),
             entity: null,
-            workingDirectory: '',
 
             // openBIS v3 connection
             openbisService : null
diff --git a/jupyter-openbis-extension/static/uploadDialog.js b/jupyter-openbis-extension/static/uploadDialog.js
index 11cc7f651666265f1820a8f6b01bb53e82c09373..16e86669d0fbbee5cee2bafd112a66ea0b135591 100644
--- a/jupyter-openbis-extension/static/uploadDialog.js
+++ b/jupyter-openbis-extension/static/uploadDialog.js
@@ -24,23 +24,27 @@ define([
         spinner.className="openbis-feedback"
         spinner.src=""
         function showSpinner(env) {
-            spinner.src = env.notebook.base_url + "nbextensions/openbis/spinner.gif"
+            var userName = window.location.pathname.split("/")[2];
+            spinner.src = '/user/' + userName+ '/nbextensions/jupyter-openbis-extension/spinner.gif'
         }
         function hideSpinner(env) {
             spinner.src=""
         }
 
-        function get_file_list(env, container) {
-            var url = env.notebook.base_url + 'general/filelist'
-        
+        function get_file_list(env, container, path) {
+            // get the file list (relative to the notebook) using the existing jupyter api
+            var url = env.notebook.base_url + 'api/contents'
+            if (path !== "") {
+                url = url + '/' + path
+            }
+
             fetch(url)
                 .then( function(response) {
                     if (response.ok) {
                         response.json()
                             .then(function(data){
-                                var values = Object.keys(data.files)
-                                values.sort()
-                                state.fileCheckboxes = createSelectTable(values, container, false, state.selectedFiles)
+                                createFileTable(env, data, container, state)
+                                //state.fileCheckboxes = createFileTable(env, data, container, state.selectedFiles)
                             })
                     }
                     else {
@@ -173,7 +177,10 @@ define([
                                 console.error("Error while parsing dataset types", error)
                             })
 
-                    } else {
+                    }
+                    else {
+                        // ! response.ok
+                        errorElements.main.textContent = "Network problem: please check your connection first."
                         while (dataset_types.firstChild) {
                             dataset_types.removeChild(dataset_types.firstChild);
                         }
@@ -182,6 +189,7 @@ define([
                 .catch(function (error) {
                     console.error("Error while fetching dataset types:", error)
                 })
+
         }
 
         function createSelectTable(values, container, checked, overrides) {
@@ -210,6 +218,96 @@ define([
             return checkboxes
         }
 
+        function createFileTable(env, data, container, state) {
+            // list of files that will be uploaded as a dataSet.
+
+            var table = document.createElement("TABLE")
+            table.className = 'table-bordered table-striped table-condensed'
+            table.style.width = "100%"
+
+            var body = table.createTBody()
+            if (data.path !== "") {
+                var row = body.insertRow()
+                row.insertCell()
+                var iconCell = row.insertCell()
+                iconCell.className = "item_icon folder_icon icon-fixed-width"
+                var filenameCell = row.insertCell()
+                filenameCell.textContent = ".."
+                filenameCell.style.width = "80%"
+                filenameCell.style.cursor = "pointer"
+                filenameCell.onclick = function(){
+                    var elems = data.path.split('/')
+                    elems.pop()
+                    get_file_list(env, container, elems.join('/'))
+                }
+
+                var sizeCell = row.insertCell()
+                sizeCell.style.textAlign = "right"
+                sizeCell.style.width = "15%"
+            }
+
+            var registerFile = function () {
+                if (this.checked) {
+                    // add file to state
+                    state.selectedFiles.push(this.value)
+                }
+                else {
+                    // remove file from state
+                    state.selectedFiles.splice(state.selectedFiles.indexOf(this.value), 1)
+                }
+            }
+
+            var checkboxes = []
+            data.content.sort( (a, b) => a.name.localeCompare(b.name, undefined, {sensitivity: 'base'}) ).forEach( file => {
+
+                var row = body.insertRow()
+                var checkboxCell = row.insertCell()
+                checkboxCell.style.width="5%"
+                var iconCell = row.insertCell()
+                var filenameCell = row.insertCell()
+
+                filenameCell.textContent = file.name
+                filenameCell.style.width = "100%"
+                filenameCell.style.cursor = "pointer"
+
+                if (file.type === "directory") {
+                    iconCell.className = "item_icon folder_icon icon-fixed-width"
+                    filenameCell.onclick = function () {
+                        get_file_list(env, container, file.path)
+                    }
+                }
+                else {
+                    var checkbox = document.createElement("INPUT")
+                    checkbox.type = "checkbox"
+                    checkbox.value = file.path
+                    checkbox.checked = state.selectedFiles.includes(file.path) ? true: false
+                    checkbox.onclick = registerFile
+                    checkboxes.push(checkbox)
+                    checkboxCell.appendChild(checkbox)
+
+                    if (file.type === "notebook") {
+                        iconCell.className = "item_icon notebook_icon icon-fixed-width"
+                    }
+                    else {
+                        iconCell.className = "item_icon file_icon icon-fixed-width"
+                    }
+                    filenameCell.onclick = function () {
+                        checkbox.checked = !checkbox.checked
+                        registerFile.call(checkbox)
+                    }
+                }
+
+                var sizeCell = row.insertCell()
+                sizeCell.textContent = file.size
+                sizeCell.style.textAlign = "right"
+                sizeCell.style.width = "15%"
+
+            })
+            container.innerHTML = ""
+            container.appendChild(table)
+            return checkboxes
+        }
+
         return {
             help: 'upload Notebook and Data to openBIS',
             icon: 'fa-upload',
@@ -219,7 +317,7 @@ define([
                 var main_error = createErrorElement('main')
 
                 var dst_title = document.createElement("STRONG")
-                dst_title.textContent = "DataSet type"
+                dst_title.textContent = "choose a dataSet type"
                 var dataset_types = document.createElement("SELECT")
                 dataset_types.id = "dataset_type"
                 dataset_types.className = "form-control select-xs"
@@ -232,13 +330,20 @@ define([
                 getDatasetTypes(env, state.connection.name, dataset_types, input_fields)
 
                 var sample_title = document.createElement("STRONG")
-                sample_title.textContent = "Entity"
+                sample_title.textContent = "enter a sample/experiment identifier to attach this dataSet to:"
 
                 var sample_error = createErrorElement('entityIdentifier')
 
-                var entityIdentifier = entitySearcher.getEntitySearcherForUpload(state)
+                //var entityIdentifier = entitySearcher.getEntitySearcherForUpload(state)
+                var entityIdentifier = document.createElement("INPUT")
+                entityIdentifier.type = "text"
+                entityIdentifier.name = "entityIdentifier"
+                entityIdentifier.size = 40
+                entityIdentifier.placeholder = "Sample or Experiment identifier/permId"
+                entityIdentifier.value = state.entityIdentifier ? state.entityIdentifier : ""
 
                 var ds_title = document.createElement("STRONG")
+
                 var dataSetListContainer = document.createElement("DIV")
                 if (env.notebook.metadata.datasets) {
                     ds_title.textContent = "Parent DataSets"
@@ -248,11 +353,14 @@ define([
                 }
 
                 var files_title = document.createElement("STRONG")
-                files_title.textContent = "Files"
+                files_title.textContent = "Files to upload"
                 var fileListContainer = document.createElement("DIV")
-                fileListContainer.style.maxHeight="150px"
+                fileListContainer.style.height="200px"
                 fileListContainer.style.overflow="auto"
-                get_file_list(env, fileListContainer)
+                // get the relative path
+                let re = new RegExp(env.notebook.notebook_name+"$")
+                rel_path = env.notebook.notebook_path.replace(re, "")
+                get_file_list(env, fileListContainer, rel_path)
                 
                 var inputs = document.createElement("DIV")
                 inputs.style.marginTop = '10px'
@@ -263,9 +371,12 @@ define([
                 inputs.appendChild(dataset_types)
                 inputs.appendChild(input_fields)
                 inputs.appendChild(sample_title)
+                inputs.appendChild(document.createElement('BR'))
                 inputs.appendChild(sample_error)
                 inputs.appendChild(entityIdentifier)
+                inputs.appendChild(document.createElement('BR'))
                 inputs.appendChild(ds_title)
+                inputs.appendChild(document.createElement('BR'))
                 inputs.appendChild(dataSetListContainer)
                 inputs.appendChild(files_title)
                 inputs.appendChild(fileListContainer)
@@ -280,7 +391,7 @@ define([
                         }
                     }
                     state.unselectedDatasets = state.datasetCheckboxes.filter(cb => !cb.checked).map(cb => cb.value)
-                    state.selectedFiles = state.fileCheckboxes.filter(cb => cb.checked).map(cb => cb.value)
+                    //state.selectedFiles = state.fileCheckboxes.filter(cb => cb.checked).map(cb => cb.value)
                 }
 
                 function onOk() {
@@ -293,12 +404,13 @@ define([
 
                     var uploadUrl = env.notebook.base_url + 'openbis/dataset/' + connection_name
 
-                    var notebook = IPython.notebook
-                    var files = state.fileCheckboxes.filter(cb => cb.checked).map(cb => cb.value)
-                    var re = /\/notebooks\/(.*?)$/
-                    var filepath = window.location.pathname.match(re)[1]
-                    files.push(filepath)
-                    
+                    // add this notebook to the list of files
+                    var files = state.selectedFiles
+                    if (! files.includes(env.notebook.notebook_path)) {
+                        files.push(env.notebook.notebook_path)
+                    }
+                    console.log(files)
+
                     var props = {}
                     for (input of $('#upload-input-fields').find('input')) {
                         props[input.name] = input.value
@@ -308,9 +420,10 @@ define([
                         "type": dataset_types.value,
                         "files": files,
                         "parents": state.datasetCheckboxes.filter(cb => cb.checked).map(cb => cb.value),
-                        "entityIdentifier": entityIdentifier.firstChild.value,
+                        "entityIdentifier": entityIdentifier.value,
                         "props": props
                     }
+                    console.log(dataSetInfo);
 
                     var settings = {
                         url: uploadUrl,
@@ -326,14 +439,14 @@ define([
                             common.createFeedback('success', data.statusText)
 
                             // write statusText from returned data to notebooks metadata
-                            if (typeof notebook.metadata.openbis === 'undefined') {
-                                notebook.metadata.openbis = {}
+                            if (typeof env.notebook.metadata.openbis === 'undefined') {
+                                env.notebook.metadata.openbis = {}
                             }
-                            if (typeof notebook.metadata.openbis.permIds === 'undefined') {
-                                notebook.metadata.openbis.permIds = {}
+                            if (typeof env.notebook.metadata.openbis.permIds === 'undefined') {
+                                env.notebook.metadata.openbis.permIds = {}
                             }
                             if (data.permId) {
-                                notebook.metadata.openbis.permIds[data.permId] = data.statusText
+                                env.notebook.metadata.openbis.permIds[data.permId] = data.statusText
                             }
                         },
                         error: function (data) {
@@ -365,35 +478,43 @@ define([
                     saveState()
                     return true
                 }
-
-                if (IPython.notebook.dirty === true) {
-                    dialog.modal({
-                        body: 'Please save the notebook before uploading it to openBIS.',
-                        title: 'Save notebook first',
-                        buttons: {
-                            'Back': {}
-                        },
-                        notebook: env.notebook,
-                        keyboard_manager: env.notebook.keyboard_manager
-                    })
-                } else {
-                    dialog.modal({
-                        body: uploadDialogBox,
-                        title: 'Upload openBIS DataSet',
-                        buttons: {
-                            'Cancel': {
-                                click: onCancel
-                            },
-                            'Upload': {
-                                class: 'btn-primary btn-large',
-                                click: onOk
-                            }
+                dialog_params = {
+                    body: uploadDialogBox,
+                    title: 'Upload openBIS DataSet',
+                    buttons: {
+                        'Cancel': {
+                            click: onCancel
                         },
-                        notebook: env.notebook,
-                        keyboard_manager: env.notebook.keyboard_manager
-                    })
+                        'Upload': {
+                            class: 'btn-primary btn-large',
+                            click: onOk
+                        }
+                    },
+                    notebook: env.notebook,
+                    keyboard_manager: env.notebook.keyboard_manager
+                }
+
+                if (env.notebook.dirty === true) {
+                    env.notebook.save_notebook()
+                        .then(function () {
+                            dialog.modal(dialog_params)
+                        })
+                        .catch(function (error) {
+                            dialog.modal({
+                                body: error,
+                                title: 'Error saving the notebook',
+                                buttons: {
+                                    'Back': {}
+                                },
+                                notebook: env.notebook,
+                                keyboard_manager: env.notebook.keyboard_manager
+                            })
+                        })
+                }
+                else {
+                    dialog.modal(dialog_params)
                 }
             }
         }
     }
-)
\ No newline at end of file
+)
diff --git a/setup.py b/setup.py
index fb238db129b39ed313e0757152948972883c359e..dc56ee882d12e85791ccce9874f138aa3b2ee854 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
 
 setup(
     name='jupyter-openbis-extension',
-    version= '0.2.4',
+    version= '0.4.0',
     author='Swen Vermeul |  ID SIS | ETH Zürich',
     author_email='swen@ethz.ch',
     description='Extension for Jupyter notebooks to connect to openBIS and download/upload datasets, inluding the notebook itself',
@@ -23,7 +23,7 @@ setup(
     install_requires=[
         'jupyter-nbextensions-configurator',
         'jupyter',
-        'pybis>=1.8.4',
+        'pybis>=1.9.5',
         'numpy',
         'tornado==5.1.1',
     ],
@@ -43,18 +43,24 @@ setup(
             "jupyter-openbis-extension/static/connectionDialog.js",
             "jupyter-openbis-extension/static/uploadDialog.js",
             "jupyter-openbis-extension/static/spinner.gif",
-            "jupyter-openbis-extension/static/jquery-select2",
-            "jupyter-openbis-extension/static/jquery-select2/css",
+            "jupyter-openbis-extension/static/entitySearcher.js",
+            "jupyter-openbis-extension/static/main.js",
+            "jupyter-openbis-extension/static/state.js",
+            "jupyter-openbis-extension/static/common.js",
+        ]),
+        ("share/jupyter/nbextensions/jupyter-openbis-extension/jquery-select2/css", [
             "jupyter-openbis-extension/static/jquery-select2/css/select2.min.css",
             "jupyter-openbis-extension/static/jquery-select2/css/select2-bootstrap.css",
             "jupyter-openbis-extension/static/jquery-select2/css/select2-bootstrap.min.css",
             "jupyter-openbis-extension/static/jquery-select2/css/select2.css",
-            "jupyter-openbis-extension/static/jquery-select2/js",
+        ]),
+        ("share/jupyter/nbextensions/jupyter-openbis-extension/jquery-select2/js", [
             "jupyter-openbis-extension/static/jquery-select2/js/select2.min.js",
             "jupyter-openbis-extension/static/jquery-select2/js/select2.full.min.js",
             "jupyter-openbis-extension/static/jquery-select2/js/select2.js",
             "jupyter-openbis-extension/static/jquery-select2/js/select2.full.js",
-            "jupyter-openbis-extension/static/jquery-select2/js/i18n",
+        ]),
+        ("share/jupyter/nbextensions/jupyter-openbis-extension/jquery-select2/js/i18n", [
             "jupyter-openbis-extension/static/jquery-select2/js/i18n/pt.js",
             "jupyter-openbis-extension/static/jquery-select2/js/i18n/vi.js",
             "jupyter-openbis-extension/static/jquery-select2/js/i18n/lv.js",
@@ -102,12 +108,6 @@ setup(
             "jupyter-openbis-extension/static/jquery-select2/js/i18n/es.js",
             "jupyter-openbis-extension/static/jquery-select2/js/i18n/ro.js",
             "jupyter-openbis-extension/static/jquery-select2/js/i18n/tr.js",
-            "jupyter-openbis-extension/static/jquery-select2/VERSION.txt",
-            "jupyter-openbis-extension/static/jquery-select2/LICENSE.txt",
-            "jupyter-openbis-extension/static/entitySearcher.js",
-            "jupyter-openbis-extension/static/main.js",
-            "jupyter-openbis-extension/static/state.js",
-            "jupyter-openbis-extension/static/common.js",
         ]),
         # like `jupyter nbextension enable --sys-prefix`
         ("etc/jupyter/nbconfig/notebook.d", [