define([
        "base/js/namespace",
        "base/js/dialog",
        "base/js/utils",
        "jquery"
    ],
    function(IPython, dialog, utils, $) {
        var currentConnection = ''
        var currentSampleIdentifier = null
        var currentDownloadPath = null
        var ds_type = document.createElement("SELECT")
        ds_type.size = '40'
        ds_type.className = "select-xs"
        ds_type.id = "dataset_type"
        var conn_table = null

        function show_available_connections(env, data, conn_table, onclick_cbf) {
            if (!currentDownloadPath) {
                currentDownloadPath = data.cwd
            }

            var 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']
            for (title of titles) {
                thead_row.insertCell().textContent = title
            }

            tbody = table.createTBody()
            for (connection of data.connections) {
                var conn = document.createElement("INPUT")
                conn.type = "radio"
                conn.name = "connection_name"
                conn.value = connection.name
                conn.setAttribute("url", connection.url)

                conn.checked = connection.name === currentConnection;
                if (onclick_cbf === undefined) {
                    conn.onclick = function() {
                        currentConnection = this.value
                    }
                }
                else {
                    conn.onclick = onclick_cbf
                }

                var row = tbody.insertRow()
                row.insertCell().appendChild(conn)
                row.insertCell().textContent = connection.name
                row.insertCell().textContent = connection.url

                var status_cell = row.insertCell()

                var status_badge = document.createElement("SPAN")
                status_badge.id = connection.name + "-badge"
                status_badge.textContent = connection.status
                if (connection.status === "connected") {
                    status_badge.className = "label label-success"
                }
                else {
                        status_badge.className = "label label-danger"
                }
                status_cell.appendChild(status_badge)

                var 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")
                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")
                pwform.id = connection.name
                pwform.onsubmit = function(event) {
                    var form_data = new FormData(this)
                    var status_badge = document.getElementById(this.id + "-badge")
                    reconnect_connection(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)
                            }
                            if (response.ok) {
                                status_badge.textContent = "connected"
                                status_badge.className = "label label-success"
                            }
                            else {
                                status_badge.textContent = "not connected"
                                status_badge.className = "label label-danger"
                                message = document.createElement("p")
                                if (response.status === 401) {
                                    message.textContent = "username/password incorrect"
                                }
                                else if (response.status === 500) {
                                    message.textContent = "Connection error"
                                }
                                else {
                                    message.textContent = "General error"
                                }
                                status_badge.parentNode.insertBefore(message, status_badge.nextSibling)
                            }
                        })
                        .catch( error => console.error("Error while attempting to reconnect: ",error) )

                    return false
                }


                var connect_button = document.createElement("BUTTON")
                connect_button.className = "btn btn-primary btn-xs"
                connect_button.textContent  = "connect"

                pwform.appendChild(username)
                pwform.appendChild(password)
                pwform.appendChild(connect_button)

                var cell = row.insertCell()
                cell.appendChild(pwform)
            }

            // add row for new connection
            var row = tbody.insertRow()

            var conn_form = document.createElement("FORM")
            conn_form.id = "new_connection"
            conn_form.onsubmit = function(event) {
                var inputs = document.querySelectorAll("input[form=new_connection]")

                data = {}
                for (input of inputs) {
                    data[input.name] = input.value
                }
                for (missing of ['connection_name','url', 'username', 'password']) {
                    if (data[missing] === ""){
                        alert("Please provide: " + missing)
                        return false
                    }
                }
                new_connection(
                    env, data.connection_name, data.url, data.username, data.password
                )
                    .then( function(response){
                        if (response.ok) {
                            response.json()
                                .then( function(data){
                                    show_available_connections(env, data, conn_table)
                                })
                        }
                    })
                return false
            }
            var conn_name = document.createElement("INPUT")
            conn_name.type = "input"
            conn_name.name = "connection_name"
            conn_name.setAttribute("form", conn_form.id)
            conn_name.placeholder = "openBIS instance name"
            row.insertCell().appendChild(conn_form)
            row.insertCell().appendChild(conn_name)

            var conn_url = document.createElement("INPUT")
            conn_url.type = "input"
            conn_url.name = "url"
            conn_url.setAttribute("form", conn_form.id)
            conn_url.placeholder = "https://openbis.domain:port"
            row.insertCell().appendChild(conn_url)
            row.insertCell()

            var 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")
            password.type = "password"
            password.name = "password"
            password.autocomplete = "new-password"
            password.setAttribute("form", conn_form.id)
            var create_btn = document.createElement("BUTTON")
            create_btn.setAttribute("form", conn_form.id)
            create_btn.textContent = "create"
            var 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")
            table_title.textContent = "Please choose a connection"
            conn_table.appendChild(table_title)
            conn_table.appendChild(table)
        }

        function show_datasets_table( data, datasets_table) {
            var table = document.createElement("TABLE")
            table.className = "table-bordered table-striped table-condensed text-nowrap"
            var thead = table.createTHead()
            var t_row = thead.insertRow()
            var titles = ['', 'permId', 'Type', 'Experiment', 'Registration Date', 'Status', 'Size']
            titles.forEach( function(title) {
                t_row.insertCell().textContent = title
            })
            var tbody = table.createTBody()

            for (dataSet of data.dataSets) {

                var permId = document.createElement("INPUT")
                permId.type = "checkbox"
                permId.name = "permId"
                permId.value = dataSet.permId

                var row = tbody.insertRow()
                row.insertCell().appendChild(permId)
                row.insertCell().textContent = dataSet.permId
                row.insertCell().textContent = dataSet.type
                row.insertCell().textContent = dataSet.experiment
                row.insertCell().textContent = dataSet.registrationDate
                row.insertCell().textContent = dataSet.status
                row.insertCell().textContent = dataSet.size
            }

            while (datasets_table.firstChild) {
                datasets_table.removeChild(datasets_table.firstChild);
            }
            datasets_table.appendChild(table)
        }

        // gets the status of the avialable openBIS connections
        function getOpenBisConnections(env) {

             var connectionsUrl = env.notebook.base_url + 'openbis/conns'
             var settings = {
                 url: connectionsUrl,
                 processData: false,
                 type: 'GET',
                 dataType: 'json',
                 contentType: 'application/json'
             }
             return utils.ajax(settings)
        }

        function reconnect_connection(env, connection, username, password){
            var url = env.notebook.base_url + 'openbis/conn/' + connection
            body = {
                "username": username,
                "password": password
            }

            var cookie = decodeURIComponent(document.cookie)
            var xsrf_token = cookie.split("_xsrf=")[1]

            return fetch(url, {
                method: "PUT",
                headers: {
                    "Content-Type": "application/json",
                    "X-XSRFToken": xsrf_token,
                },
                body: JSON.stringify(body)
            })
        }

        function new_connection(env, connection_name, connection_url, username, password){
            var endpoint = env.notebook.base_url + 'openbis/conns'
            body = {
                "name"    : connection_name,
                "url"     : connection_url,
                "username": username,
                "password": password
            }

            var cookie = decodeURIComponent(document.cookie)
            var xsrf_token = cookie.split("_xsrf=")[1]

            return fetch(endpoint, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "X-XSRFToken": xsrf_token,
                },
                body: JSON.stringify(body)
            })
        }

        function getDatasetTypes(env, connection_name, dataset_types, input_fields) {
            // get all DatasetTypes of a given connection

            var url = env.notebook.base_url + 'openbis/datasetTypes/'+ connection_name
            fetch(url)
                .then( function(response) {
                    if (response.ok) {
                        response.json()
                            .then( function(data) {
                                //console.log(data.dataSetTypes)

                                var change_input_fields = function() {
                                    // remove existing input fields
                                    while (input_fields.firstChild) {
                                        input_fields.removeChild(input_fields.firstChild)
                                    }

                                    // for every property assignment, create an input field.
                                    for (pa of dts[dataset_type.selectedIndex].propertyAssignments) {
                                        //var input_title = document.createTextNode(pa.label + ": ")
                                        var input_field = document.createElement("INPUT")
                                        input_field.type = "text"
                                        input_field.name = pa.code
                                        input_field.placeholder = pa.description ? pa.label + ": " + pa.description : pa.label
                                        input_field.size = 90

                                        //input_fields.appendChild(input_title)
                                        input_fields.appendChild(input_field)
                                        input_fields.appendChild(document.createElement("BR"))
                                    }
                                }
                                dataset_types.onchange = change_input_fields

                                // remove the old and add the new dataset-types
                                dts = data.dataSetTypes
                                while (dataset_types.firstChild) {
                                    dataset_types.removeChild(dataset_types.firstChild);
                                }
                                for (dt of dts) {
                                    var option = document.createElement("OPTION")
                                    option.value = dt.code
                                    option.textContent = dt.description ? dt.code + ": " + dt.description : dt.code
                                    dataset_types.appendChild(option)
                                }
                                // change the input fields, since we just received new datasetTypes
                                change_input_fields()

                            })
                            .catch( function(error){
                                console.error("Error while parsing dataset types", error)
                            })

                    }
                    else {
                        while (dataset_types.firstChild) {
                            dataset_types.removeChild(dataset_types.firstChild);
                        }
                    }
                })
                .catch (function(error) {
                    console.error("Error while fetching dataset types:", error)
                })
        }

        function createFeedback(type, content) {
            var close = document.createElement("BUTTON")
            close.className = "close"
            close.setAttribute("data-dismiss", "alert")
            close.setAttribute("aria-label", "Close")
            var x = document.createElement("SPAN")
            x.setAttribute("aria-hidden", true)
            x.innerHTML = "×"
            close.appendChild(x)

            var feedbackBox = document.createElement( "DIV" )
            feedbackBox.className = "openbis-feedback alert alert-dismissible alert-" + type
            feedbackBox.setAttribute("role","alert")
            feedbackBox.innerHTML = content
            feedbackBox.prepend(close)

            var nb_container = document.getElementById('notebook-container')
            nb_container.prepend(feedbackBox)
        }

        function writeMetaData(data) {
            var notebook = IPython.notebook
            if (typeof notebook.metadata.openbis_connections === 'undefined') {
                notebook.metadata.openbis_connections = {}
            }
            if (typeof notebook.metadata.openbis_connections[data.url] === 'undefined') {
                notebook.metadata.openbis_connections[data.url] = {}
            }
            // store metadata about the downloaded files into the notebook-metadata
            if (data.permId) {
                notebook.metadata.openbis_connections[data.url][data.permId] = {
                    "permId": data.permId,
                    "path": data.path,
                    "dataStore": data.dataStore,
                    "location": data.location,
                    "size": data.size,
                    "status": data.statusText
                }
            }

        }

        var fetchDatasetFromOpenBis = {
            help: 'Download openBIS datasets to your local harddrive',
            icon: 'fa-download',
            help_index: '',
            handler: function (env) {
                conn_table = document.createElement("DIV")
                conn_table.id = "openbis_connections"
                getOpenBisConnections(env)
                    .done(function (data) {
                        show_available_connections(env, data, conn_table)
                    })
                    .fail(function (data) {
                        alert(data.status)
                    })
                    .always(function () {
                        showDownloadDialog()
                    })

                function showDownloadDialog() {
                    // This function gets called after loading the openBIS connections
                    // to make sure we can display the download path provided by the server.

                    // show DataSets for Sample identifier/permid
                    var showDataSets = document.createElement("DIV")
                    var title = document.createElement("STRONG")
                    title.textContent = "Sample identfier/permId: "
                    showDataSets.appendChild(title)
                    showDataSets.style.marginTop = '10px'

                    var sampleIdentifier = document.createElement("INPUT")
                    sampleIdentifier.type = "text"
                    sampleIdentifier.name = "sampleIdentifier"
                    sampleIdentifier.size = 40
                    sampleIdentifier.placeholder = "sample identifier or permId"
                    sampleIdentifier.value = currentSampleIdentifier

                    var datasets_table = document.createElement("DIV")
                    datasets_table.id = "dataset_table"
                    datasets_table.className = "output output_scroll"
                    datasets_table.style.maxHeight = "10em"

                    var show_datasets_btn = document.createElement("BUTTON")
                    show_datasets_btn.className = "btn-info btn-xs"
                    show_datasets_btn.textContent = "show datasets"

                    show_datasets_btn.onclick = function() {
                        var selected_conn = document.querySelector('input[name=connection_name]:checked')
                        if (!selected_conn) {
                            alert('Please choose a connection')
                            return false
                        }
                        connection_name = selected_conn.value

                        currentConnection = connection_name
                        currentSampleIdentifier = sampleIdentifier.value
                        if (!currentSampleIdentifier) {
                            alert('Please specify a sample identifier/permId')
                            return false
                        }
                        var url = env.notebook.base_url + 'openbis/sample/' + connection_name + '/' + encodeURIComponent(currentSampleIdentifier)

                        fetch(url)
                            .then( function(response) {
                                if (response.ok) {
                                    response.json()
                                        .then( function(data) {
                                            show_datasets_table(data, datasets_table)
                                        })
                                }
                                else {
                                    response.json()
                                        .then( function(error) {
                                            console.log(error.reason)
                                            alert("Error: " + error.reason)
                                        })
                                }
                            })
                            .catch( function(error) {
                                console.error('A serious network problem occured:', error)
                            })

                    }
                    showDataSets.appendChild(sampleIdentifier)
                    showDataSets.appendChild(show_datasets_btn)
                    showDataSets.appendChild(datasets_table)

                    // dataSetPermId only
                    var dataset_direct = document.createElement("P")
                    dataset_direct.style.marginTop='10px'
                    dataset_direct.innerHTML = '<strong>enter DataSet permId directly: </strong>'

                    //var dataset = $('<p>')
                    //    .css('margin-top', '10px')
                    //    .append($('<b>').text('... or enter DataSet permId directly: '))
                    var datasetPermId = document.createElement("INPUT")
                    datasetPermId.type = "text"
                    datasetPermId.name = "datasetPermId"
                    datasetPermId.size = "40"
                    datasetPermId.placeholder = "dataSet permId"

                    dataset_direct.appendChild(datasetPermId)

                    var downloadPath = document.createElement("INPUT")
                    downloadPath.type = "text"
                    downloadPath.name = "downloadPath"
                    downloadPath.size = "90"
                    downloadPath.value = currentDownloadPath

                    var path = document.createElement("DIV")
                    path.innerHTML = "<strong>download data to path: </strong>"
                    path.appendChild(downloadPath)

                    var download_dialog_box = document.createElement("DIV")
                    download_dialog_box.appendChild(conn_table)
                    download_dialog_box.appendChild(showDataSets)
                    download_dialog_box.appendChild(dataset_direct)
                    download_dialog_box.appendChild(path)

                    function downloadDataset(selected_conn, selectedPermIds, downloadPath) {
                        var connection_name = selected_conn.value

                        for (permId of selectedPermIds) {
                            var downloadUrl = env.notebook.base_url + 'openbis/dataset/'
                                + connection_name + '/' + permId + '/' + encodeURIComponent(downloadPath)

                            fetch(downloadUrl)
                                .then( function(response) {
                                    if (response.ok) {
                                        response.json()
                                            .then( function(data) {
                                                createFeedback('success', data.statusText)

                                                // successful download:
                                                // write statusText from returned data to notebooks metadata
                                                writeMetaData(data)

                                                // keep current download path for later use
                                                currentDownloadPath = downloadPath
                                            })
                                    }
                                    else {
                                        response.json()
                                            .then( function(error) {
                                                console.log(error.reason)
                                                alert("Error: " + error.reason)
                                            })
                                    }
                                })
                                .catch( function(error) {
                                    console.error('A serious network problem occured:', error)
                                })
                        }
                    }

                    function onDownloadClick() {
                        var selected_conn = document.querySelector('input[name=connection_name]:checked')
                        if (! selected_conn) {
                            alert('please choose a connection')
                            return false
                        }

                        var selectedPermIds = []
                        for (row of document.querySelectorAll('input[name=permId]:checked') ) {
                            selectedPermIds.push(row.value)
                        }
                        if (datasetPermId.value) {
                            selectedPermIds.push(datasetPermId.value)
                        }
                        if (!selectedPermIds) {
                            alert('please select a dataset or provide a permId')
                            return false
                        }

                        if (!downloadPath.value) {
                            alert('Please specify where you would like to download your files!')
                            return false
                        }
                        downloadDataset(selected_conn, selectedPermIds, downloadPath.value)
                    }

                    dialog.modal({
                        body: download_dialog_box,
                        title: 'Download openBIS DataSets',
                        buttons: {
                            'Cancel': {},
                            'Download': {
                                class: 'btn-primary btn-large',
                                click: onDownloadClick,
                            }
                        },
                        notebook: env.notebook,
                        keyboard_manager: env.notebook.keyboard_manager
                    })
                }
            }
        }

        var uploadDatasetsToOpenBis = {
            help: 'upload Notebook and Data to openBIS',
            icon: 'fa-upload',
            help_index: '',
            handler: function (env) {
                conn_table = document.createElement("DIV")
                var dst_title = document.createElement("STRONG")
                dst_title.textContent = "DataSet type"
                var 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"

                var onclick_cbf = function() {
                    currentConnection = this.value
                    getDatasetTypes(env, this.value, dataset_types, input_fields)
                }

                getOpenBisConnections(env)
                    .done(function (data) {
                        show_available_connections(env, data, conn_table, onclick_cbf)
                    })
                    .fail(function (data) {
                        alert(data.status)
                    })

                var sample_title = document.createElement("STRONG")
                sample_title.textContent = "Sample Identifier"
                var sampleIdentifier = document.createElement("INPUT")
                sampleIdentifier.type = "text"
                sampleIdentifier.name = 'sampleIdentifier'
                sampleIdentifier.placeholder = "Sample Identifier or permId"
                sampleIdentifier.value = currentSampleIdentifier
                sampleIdentifier.size  = "90"

                var ds_title = document.createElement("STRONG")
                ds_title.textContent = "DataSet files"
                var ds_files         = document.createElement("INPUT")
                ds_files.type        = "text"
                ds_files.placeholder = "filenames"
                ds_files.name        = "ds_files"
                ds_files.size        = "90"

                var inputs = document.createElement("DIV")
                inputs.style.marginTop = '10px'
                inputs.appendChild(dst_title)
                inputs.appendChild(dataset_types)
                inputs.appendChild(input_fields)
                inputs.appendChild(sample_title)
                inputs.appendChild(sampleIdentifier)
                inputs.appendChild(ds_title)
                inputs.appendChild(ds_files)

                var uploadDialogBox = $('<div/>').append(conn_table).append(inputs)


                // get the canvas for user feedback
                var container = $('#notebook-container')

                function onOk () {
                    //var connection_name = $('input[name="connection_name"]:checked').val()
                    var selected_connection = document.querySelector('input[name=connection_name]:checked')
                    if (!selected_connection) {
                        alert("No connection selected")
                        return false
                    }
                    var connection_name = selected_connection.value

                    var uploadUrl = env.notebook.base_url + 'openbis/dataset/' + connection_name

                    var notebook = IPython.notebook
                    var re = /\/notebooks\/(.*?)$/
                    var files = []
                    var filepath = window.location.pathname.match(re)[1]
                    files.push(filepath)
                    // FIXME
                    //if (ds_files.val()) {
                    //    files.push(ds_files.value)
                    //}

                    var dataSetInfo = {
                        "type"            : dataset_types.value,
                        "files"           : files,
                        "sampleIdentifier": sampleIdentifier.value
                    }

                    var settings = {
                        url: uploadUrl,
                        processData: false,
                        type: 'POST',
                        dataType: 'json',
                        data: JSON.stringify(dataSetInfo),
                        contentType: 'application/json',
                        success: function (data) {
                            // display feedback to user
                            createFeedback('success', data.statusText)

                            // write statusText from returned data to notebooks metadata
                            if ( typeof notebook.metadata.openbis === 'undefined') {
                                notebook.metadata.openbis = {}
                            }
                            if ( typeof notebook.metadata.openbis.permIds === 'undefined' ) {
                                notebook.metadata.openbis.permIds = {}
                            }
                            if ( data.permId ) {
                                notebook.metadata.openbis.permIds[data.permId] = data.statusText
                            }

                        },
                        error: function (data) {
                            // display feedback to user
                            var feedback = "<strong>Error: </strong>Dataset was not uploaded.<div>"
                                + data.statusText
                                + "</div>"
                            createFeedback('danger', feedback)
                        }
                    }

                    // display preloader during commit and push
                    var preloader = '<img class="openbis-feedback" src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.5.8/ajax-loader.gif">'

                    // commit and push
                    utils.ajax(settings)
                }

                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': {},
                            'Upload': {
                                class: 'btn-primary btn-large',
                                click: onOk
                            }
                        },
                        notebook: env.notebook,
                        keyboard_manager: env.notebook.keyboard_manager
                    })
                }
            }
        }

        var configureOpenBisConnections = {
            help: 'configure openBIS connections',
            icon: 'fa-sliders',
            help_index: '',
            handler: function (env) {
                conn_table = document.createElement("DIV")
                var dst_title = document.createElement("STRONG")
                dst_title.textContent = "DataSet type"
                var 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"

                var onclick_cbf = function() {
                    currentConnection = this.value
                    getDatasetTypes(env, this.value, dataset_types, input_fields)
                }

                getOpenBisConnections(env)
                    .done(function (data) {
                        show_available_connections(env, data, conn_table, onclick_cbf)
                    })
                    .fail(function (data) {
                        alert(data.status)
                    })

                var uploadDialogBox = $('<div/>').append(conn_table)

                // get the canvas for user feedback
                var container = $('#notebook-container')

                function onOk () {

                }

                dialog.modal({
                    body: uploadDialogBox,
                    title: 'Choose openBIS connection',
                    buttons: {
                        'Cancel': {},
                        'Choose connection': {
                            class: 'btn-primary btn-large',
                            click: onOk
                        }
                    },
                    notebook: env.notebook,
                    keyboard_manager: env.notebook.keyboard_manager
                })
            }
        }

        function _onLoad () {
            // show connections
            var configure_openbis_connections = IPython.keyboard_manager.actions.register(
                configureOpenBisConnections, 'openbis-connections', 'jupyter-openBIS')

            // dnownload
            var download_datasets = IPython.keyboard_manager.actions.register(
                fetchDatasetFromOpenBis, 'openbis-dataset-download', 'jupyter-openBIS')

            // upload
            var upload_datasets = IPython.keyboard_manager.actions.register(
                uploadDatasetsToOpenBis, 'openbis-dataset-upload', 'jupyter-openBIS')

            // add button for new action
            IPython.toolbar.add_buttons_group([configure_openbis_connections, download_datasets, upload_datasets])
        }

        return {load_ipython_extension: _onLoad}
    })