diff --git a/src/core/js/ext_applicable.js b/src/core/js/ext_applicable.js
index 20f3a593c5b8d7329017b8a46b4c964b28907648..8ff06bc0f162062ca512ba0f144e559a187ccaf6 100644
--- a/src/core/js/ext_applicable.js
+++ b/src/core/js/ext_applicable.js
@@ -60,18 +60,26 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
   const version = "0.1";
 
   /**
+   * Run through all creators and call the "create" function of the first
+   * creator which returns true from is_applicable(entity).
+   *
    * @param {HTMLElement} entity
-   * @param {Creator[]} creators - 
+   * @param {Creator[]} creators - list of creators
+   * @return {HTMLElemen|String} content - the result of the first matching
+   *     creator.
    */
   const root_creator = async function (entity, creators) {
     for (let c of creators) {
+      var is_applicable = false;
       try {
-        if (await c.is_applicable(entity)) {
-          const content = await c.create(entity);
-          return content;
-        }
+        is_applicable = await c.is_applicable(entity);
       } catch (err) {
-          logger.error(err);
+        logger.error(`error in is_applicable function of creator`, c, err);
+        continue;
+      }
+      if (is_applicable) {
+        const content = await c.create(entity);
+        return content;
       }
     }
     return undefined;
@@ -80,23 +88,16 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
   var _set_content = function (container, content) {
     const _container = $(container);
     _container.empty();
-    // TODO show/hide buttons for expanding the content
-    var buttons = _container.siblings(`.${_css_class_preview_container_button}`);
 
-    // toggle the buttons which expand the container
     if (content) {
-        buttons.css({
-            "visibility": "initial"
-        });
         _container.append(content);
-    } else {
-        buttons.css({
-            "visibility": "hidden"
-        });
     }
   }
 
-  const set_content = async function (container, content, contentReadyEvent) {
+  /**
+   * TODO
+   */
+  const set_content = async function (container, content, contentReadyEvent, noContentEvent) {
     try {
       const wait = "Please wait...";
       _set_content(container, wait);
@@ -104,7 +105,10 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
       _set_content(container, result);
       if (result && contentReadyEvent) {
         container.dispatchEvent(contentReadyEvent);
+      } else if (!result && noContentEvent) {
+        container.dispatchEvent(noContentEvent);
       }
+
     } catch (err) {
       logger.error(err);
       const err_msg = "An error occured while loading this content.";
@@ -117,12 +121,14 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
    * @param {HTMLElement} entity
    * @param {get_container_cb} get_container_cb
    * @param {Creator[]} creators
+   * @param {Event} [contentReadyEvent]
+   * @param {Event} [noContentEvent]
    */
-  const _root_handler = function (entity, get_container_cb, creators, contentReadyEvent) {
+  const _root_handler = function (entity, get_container_cb, creators, contentReadyEvent, noContentEvent) {
     const _container = get_container_cb(entity);
     if (_container) {
       const content = root_creator(entity, creators);
-      set_content(container, content, contentReadyEvent);
+      set_content(_container, content, contentReadyEvent, noContentEvent);
     }
   }
 
@@ -133,17 +139,17 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
    * @param {CreatorConfig[]} - config for the creators.
    * @returns {Creator[]} - array of creators.
    */
-  var make_creators = function (creators) {
-    const result = [];
-    for (let c of creators) {
-      result.push({
-          id: c.id,
-          is_applicable: typeof c.is_applicable === "function" ? c.is_applicable : eval(c.is_applicable),
-          create: typeof c.create === "function" ? c.create : eval(c.create)
-        });
-    }
-    return result;
-  }
+  //var make_creators = function (creators) {
+    //const result = [];
+    //for (let c of creators) {
+      //result.push({
+          //id: c.id,
+          //is_applicable: typeof c.is_applicable === "function" ? c.is_applicable : eval(c.is_applicable),
+          //create: typeof c.create === "function" ? c.create : eval(c.create)
+        //});
+    //}
+    //return result;
+  //}
 
 
   /**
@@ -163,6 +169,7 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
     }
   }
 
+
   /**
    * Initialize the scroll watcher which listens on the scroll event of the
    * window and triggers the root handler with a delay after the last
@@ -175,7 +182,7 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
   var init_watcher = function(delay, trigger) {
     var scroll_timeout = undefined;
     $(window).scroll(() => {
-        if (!scroll_timeout) {
+        if (scroll_timeout) {
             clearTimeout(scroll_timeout);
         }
         scroll_timeout = setTimeout(trigger, delay);
@@ -187,11 +194,10 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
     window.addEventListener(
       preview.previewReadyEvent.type,
       () => {
-        if (!preview_timeout) {
-          clearTimeout(scroll_timeout);
+        if (preview_timeout) {
+          clearTimeout(preview_timeout);
         }
-        scroll_timeout = setTimeout(trigger, 100);
-        return true;
+        preview_timeout = setTimeout(trigger, delay);
       },
       true);
 
@@ -234,6 +240,15 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
     };
   }
 
+  const _make_creator = function (c) {
+    return {
+      id: c.id,
+      is_applicable: typeof c.is_applicable === "function" ?
+                         c.is_applicable : eval(c.is_applicable),
+      create: typeof c.create === "function" ? c.create : eval(c.create)
+    };
+  }
+
 
   /**
    * @param {IsApplicableConfig}
@@ -241,12 +256,12 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
    */
   const _make_creators = function(config) {
     const creators = [];
-    // for ... in ...
-    // TODO
-    // creators.push(creator)
-    const fallback_creator = _make_fallback_creator(config["fallback"]);
+    for (let c of config.creators) {
+      creators.push(_make_creator(c));
+    }
+    const fallback_creator = _make_fallback_creator(config.fallback);
     if (fallback_creator) {
-      creator.push(fallback_creator);
+      creators.push(fallback_creator);
     }
     return creators;
   }
@@ -289,33 +304,42 @@ var ext_applicable = function($, logger, is_in_view_port, load_config, getEntity
    * @param {string} that_version - a version string.
    * @throws {Error} if that_version doesn't match this modules version.
    */
-  const check_version = function(that_version) {
-    if(that_version !== _version) {
-      throw new Error("Wrong version in config.");
+  const _check_version = function(that_version) {
+    if(that_version != version) {
+      throw new Error(`Wrong version in config. Was '${that_version}', should be '${version}'.`);
     }
   }
 
   /**
-   * @param {get_container_cb|string} get_container
+   * @param {string} app_name
    * @param {IsApplicableConfig} config
+   * @param {get_container_cb} get_container
+   * @param {Event} [contentReadyEvent]
+   * @param {Event} [noContentEvent]
    * returns {IsApplicableApp}
    */
-  const create_is_applicable_app = function(app_name, config, get_container, contentReadyEvent) {
+  const create_is_applicable_app = function(app_name, config, get_container, contentReadyEvent, noContentEvent) {
     logger.debug("create_is_applicable_app", config, get_container);
-    check_version(config["version"])
-    creators = _make_creators(config)
-    get_container_wrapper = _make_get_container_wrapper(get_container, app_name);
+    _check_version(config["version"])
+    const creators = _make_creators(config)
+    const get_container_wrapper = _make_get_container_wrapper(get_container, app_name);
+
+    const root_handler = (entity) => _root_handler(entity, get_container_wrapper, creators, contentReadyEvent, noContentEvent);
 
-    root_handler = (entity) => _root_handler(entity, get_container_wrapper, creators, contentReadyEvent);
+    if (config.init_watcher) {
+      init_watcher(config.delay || 500, () => {root_handler_trigger(root_handler);});
+    }
+    return {
+      config: config,
+      creators: creators,
+      root_handler: root_handler,
+    }
   }
 
   return {
-    init_watcher: init_watcher,
-    root_creator: root_creator,
-    root_handler: _root_handler,
-    root_handler_trigger: root_handler_trigger,
-    make_creators: make_creators,
     create_is_applicable_app: create_is_applicable_app,
+    root_handler_trigger: root_handler_trigger,
+    init_watcher: init_watcher,
     helpers: helpers,
   };
 
diff --git a/src/core/js/ext_bottom_line.js b/src/core/js/ext_bottom_line.js
index d598fcbd9f52e5be8eccd69703224fbe0d58cf28..8c657698cfb9d076b1252f99cab8d57e01239f50 100644
--- a/src/core/js/ext_bottom_line.js
+++ b/src/core/js/ext_bottom_line.js
@@ -45,7 +45,9 @@
  */
 var ext_bottom_line = function($, logger, is_in_view_port, load_config, getEntityPath, connection, ext_applicable) {
 
+    const contentShownEvent = new Event("ext_bottom_line.content.shown");
     const contentReadyEvent = new Event("ext_bottom_line.content.ready");
+    const noContentEvent = new Event("ext_bottom_line.content.none");
     const _css_class_preview_container = "caosdb-f-ext_bottom_line-container";
     const _css_class_preview_container_button = "caosdb-f-ext_bottom_line-container-button";
 
@@ -118,25 +120,11 @@ var ext_bottom_line = function($, logger, is_in_view_port, load_config, getEntit
             is_applicable: (entity) => ext_applicable.helpers.path_has_file_extension(
                 entity, ["mp4", "mov", "webm"]),
             create: _create_video_preview,
-        }, { // fallback
-            id: "_default_creators.fallback",
-            is_applicable: (entity) => true,
-            create: (entity) => fallback_preview,
         },
 
     ];
 
 
-    const contentShownEvent = new Event("ext_bottom_line.content.shown");
-
-
-    /**
-     * Store the list of creators.
-     *
-     * @member {Creator[]}
-     */
-    const _creators = [];
-
     /**
      * Return the preview container of the entity.
      *
@@ -145,7 +133,7 @@ var ext_bottom_line = function($, logger, is_in_view_port, load_config, getEntit
      *     doesn't have any.
      */
     const get_preview_container = function(entity) {
-        return $(entity).children(`.${ext_applicable.
+        return $(entity).children(`.${ext_bottom_line.
             _css_class_preview_container}`)[0];
     }
 
@@ -200,10 +188,16 @@ var ext_bottom_line = function($, logger, is_in_view_port, load_config, getEntit
         container.on("shown.bs.collapse", () => {
             container[0].dispatchEvent(contentShownEvent);
         });
+        container.on(noContentEvent.type, () => {
+            button_hide.css({
+                "visibility": "hidden"
+            });
+            button_show.css({
+                "visibility": "hidden"
+            });
+        });
+
 
-        container.on(ext_applicable.contentReadyEvent.type, () => {
-          container[0].dispatchEvent(contentReadyEvent);
-        }
         $(entity).append(container);
         $(entity).append(button_show);
         $(entity).append(button_hide);
@@ -211,6 +205,11 @@ var ext_bottom_line = function($, logger, is_in_view_port, load_config, getEntit
         return container[0];
     }
 
+    var get_container = function (entity) {
+      const container = get_preview_container(entity) || add_preview_container(entity);
+      return container;
+    }
+
     /**
      * Create a preview for the entity and append it to the entity.
      *
@@ -221,85 +220,59 @@ var ext_bottom_line = function($, logger, is_in_view_port, load_config, getEntit
      * @param {HTMLElement} entity - the entity for which the preview is to
      *     created.
      */
-    var root_preview_handler = async function(entity) {
-        const container = get_preview_container(entity) || add_preview_container(entity);
-        if (container) {
-            await ext_applicable.root_handler(entity, container, _creators);
-        } else {
-            logger.error(new Error("Could not create the preview container."));
-        }
-    }
-
-    /**
-     * Trigger the root_preview_handler for all entities within the view port
-     * when the view port.
-     */
-    var root_preview_handler_trigger = function() {
-      ext_applicable.root_handler_trigger(root_preview_handler);
-    }
-
-
+    //var root_preview_handler = async function(entity) {
+        //const container = get_preview_container(entity) || add_preview_container(entity);
+        //if (container) {
+            //await ext_applicable.root_handler(entity, container, _creators);
+        //} else {
+            //logger.error(new Error("Could not create the preview container."));
+        //}
+    //}
 
     /**
-     * Configure the creators.
+     * Initialize this module as an is_applicable_app.
      *
-     * @param {BottomLineConfig} config
-     */
-    var configure = async function(config) {
-        logger.debug("configure", config);
-        if (config.version != "0.1") {
-            throw new Error("Wrong version in config.");
-        }
-
-        // append/load custom creators
-        _creators.splice(0, _creators.length);
-        for (let c of ext_applicable.make_creators(config.creators)) {
-            _creators.push(c);
-        }
-
-        // append default creators
-        for (let c of _default_creators) {
-            _creators.push(c);
-        }
-        fallback_preview = config.fallback || fallback_preview;
-    };
-
-
-    /**
-     * Initialize this module.
-     *
-     * I.e. configure the list of creators and setup the scroll listener which
-     * triggers the root_preview_handler.
-     *
-     * @property {BottomLineConfig} [config] - an optional config. Per default, the
-     *     configuration is fetched from the server.
+     * @property {IsApplicableConfig} [config] - an optional config.
+     *     Per default, the configuration is fetched from the server.
      */
     const init = async function(config) {
         logger.info("ext_bottom_line initialized");
-
         try {
             let _config = config || await load_config("json/ext_bottom_line.json");
-            await configure(_config);
-
-            ext_applicable.init_watcher(_config.delay || 500,
-              root_preview_handler_trigger);
-
+            // apply defaults if options are not set
+            _config.fallback = _config.fallback || fallback_preview;
+            _config.init_watcher = _config.init_watcher || true;
+            _config.delay = _config.delay || 500;
+            _config.creators = _config.creators || [];
+            if (typeof _config.use_default_creators == "undefined") {
+              _config.use_default_creators = true;
+            }
+
+            // append default creators
+            if (_config.use_default_creators == true) {
+              _config.creators = _config.creators.concat(_default_creators);
+            }
+
+            // create is_applicable_app
+            const app = ext_applicable.create_is_applicable_app("bottom_line",
+              _config, get_container, contentReadyEvent, noContentEvent);
+
+            ext_bottom_line.app = app;
+            logger.trace("created bottom line app", app);
 
         } catch (err) {
             logger.error(err);
         }
-
     }
 
     return {
         contentReadyEvent: contentReadyEvent,
         contentShownEvent: contentShownEvent,
+        noContentEvent: noContentEvent,
         init: init,
-        init_watcher: ext_applicable.init_watcher,
-        configure: configure,
-        add_preview_container: add_preview_container,
-        root_preview_handler: root_preview_handler,
-        _creators: _creators,
+        app: undefined,
+        get_container: get_container,
+        _css_class_preview_container: _css_class_preview_container,
     }
 }($, log.getLogger("ext_bottom_line"), resolve_references.is_in_viewport_vertically, load_config, getEntityPath, connection, ext_applicable);
 
diff --git a/test/core/js/modules/ext_bottom_line.js.js b/test/core/js/modules/ext_bottom_line.js.js
index b7e825f7b469c12a58b73ecdb1ecd126390f9c98..067aade473ba9918f9c1d44eee2b9bb60e8cc863 100644
--- a/test/core/js/modules/ext_bottom_line.js.js
+++ b/test/core/js/modules/ext_bottom_line.js.js
@@ -32,19 +32,19 @@ var ext_bottom_line_test_suite = function ($, ext_bottom_line, QUnit) {
       "fallback": "blablabla",
       "creators": [
         { "id": "test.success",
-          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) === 'TestPreviewRecord-success'",
+          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) == 'TestPreviewRecord-success'",
           "create": "(entity) => 'SUCCESS'"
         },
         { "id": "test.error",
-          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) === 'TestPreviewRecord-error'",
+          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) == 'TestPreviewRecord-error'",
           "create": "(entity) => new Promise((res,rej) => {rej('Test Error');})"
         },
         { "id": "test.load-forever",
-          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) === 'TestPreviewRecord-load-forever'",
+          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) == 'TestPreviewRecord-load-forever'",
           "create": "(entity) => new Promise((res,rej) => {})"
         },
         { "id": "test.success-2",
-          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) !== 'TestPreviewRecord-fall-back'",
+          "is_applicable": "(entity) => getParents(entity).map(par => par.name).includes('TestPreviewRecordType') && getEntityName(entity) != 'TestPreviewRecord-fall-back'",
           "create": "(entity) => { return plotly_preview.create_plot([{x: [1,2,3,4,5], y: [1,2,4,8,16]}], { 'xaxis': {'title': 'time [samples]'}}); }"
         }
       ]
@@ -53,7 +53,7 @@ var ext_bottom_line_test_suite = function ($, ext_bottom_line, QUnit) {
     QUnit.module("ext_bottom_line.js", {
         before: async function (assert) {
             // setup before module
-            await ext_bottom_line.configure(test_config);
+            await ext_bottom_line.init(test_config);
         },
         beforeEach: function (assert) {
             // setup before each test
@@ -66,52 +66,51 @@ var ext_bottom_line_test_suite = function ($, ext_bottom_line, QUnit) {
         }
     });
 
-    QUnit.test("_creators", function (assert) {
-        assert.equal(ext_bottom_line._creators.length, 7, "seven creators");
+    QUnit.test("app.creators", function (assert) {
+        assert.equal(ext_bottom_line.app.creators.length, 7, "seven creators");
     });
 
-    QUnit.test("add_preview_container", function(assert) {
+    QUnit.test("get_container - creation", function(assert) {
         var entity = $("<div/>");
-        var container = $(ext_bottom_line.add_preview_container(entity[0]));
-        assert.ok(container.hasClass(ext_applicable._css_class_preview_container), `has class ${ext_applicable._css_class_preview_container}`);
-        assert.ok(container.hasClass(ext_applicable._css_class_preview_container_resolvable), `has class ${ext_applicable._css_class_preview_container_resolvable}`);
+        var container = $(ext_bottom_line.get_container(entity[0]));
+        assert.ok(container.hasClass(ext_bottom_line._css_class_preview_container), `new container has class ${ext_bottom_line._css_class_preview_container}`);
     });
 
-    QUnit.test("root_preview_handler", async function(assert) {
-        for (let name_suffix of ["fall-back", "error", "load-forever", "success"]) {
+    QUnit.test("get_container - pre-existing", function(assert) {
+        var entity = $("<div/>");
+        var _pre_existing = $(`<div id="preexisting" class="${ext_bottom_line._css_class_preview_container}"/>`)[0];
+        entity.append(_pre_existing);
+        var container = ext_bottom_line.get_container(entity[0]);
+
+        assert.equal(container.id, _pre_existing.id, "correct container found");
+    });
+
+    QUnit.test("run with test config", async function(assert) {
+        for (let name_suffix of ["error", "fall-back", "load-forever", "success"]) {
             let name = "TestPreviewRecord-" + name_suffix;
             let entity_xml = `<Response><Record name="${name}"><Parent name='TestPreviewRecordType'/></Record></Response>`;
             let entity = (await transformation.transformEntities(str2xml(entity_xml)))[0];
             assert.equal(getEntityName(entity), name, "correct name");
-            var container = $(ext_bottom_line.add_preview_container(entity));
-
-            assert.ok(container.hasClass(ext_applicable._css_class_preview_container), `before has class ${ext_applicable._css_class_preview_container}`);
-            assert.ok(container.hasClass(ext_applicable._css_class_preview_container_resolvable), `before has class ${ext_applicable._css_class_preview_container_resolvable}`);
+            var container = $(ext_bottom_line.get_container(entity));
 
-            if (name_suffix === "load-forever"){
-                ext_bottom_line.root_preview_handler(entity);
-                await sleep(1000);
-            } else {
-                await ext_bottom_line.root_preview_handler(entity);
-            }
+            assert.ok(container.hasClass(ext_bottom_line._css_class_preview_container), `before has class ${ext_bottom_line._css_class_preview_container}`);
 
-            // ..._resolvable class removed
-            assert.ok(container.hasClass(ext_applicable._css_class_preview_container), `after has class ${ext_applicable._css_class_preview_container}`);
-            assert.notOk(container.hasClass(ext_applicable._css_class_preview_container_resolvable), `after missing class ${ext_applicable._css_class_preview_container_resolvable}`);
+            ext_bottom_line.app.root_handler(entity);
+            await sleep(1000);
 
 
             switch(name_suffix) {
-                case "fall-back":
-                    assert.equal(container.text(), "blablabla");
-                    break;
                 case "error":
-                    assert.equal(container.text(), "An error occured while loading this content.");
+                    assert.equal(container.text(), "An error occured while loading this content.", `${name_suffix} has correct content`);
                     break;
                 case "load-forever":
-                    assert.equal(container.text(), "Please wait...");
+                    assert.equal(container.text(), "Please wait...", `${name_suffix} has correct content`);
                     break;
                 case "success":
-                    assert.equal(container.text(), "SUCCESS");
+                    assert.equal(container.text(), "SUCCESS", `${name_suffix} has correct content`);
+                    break;
+                case "fall-back":
+                    assert.equal(container.text(), "blablabla", `${name_suffix} has correct content`);
                     break;
                 default:
                     assert.ok(false);