diff --git a/web/app/static/js/modules/nopaque.CorpusAnalysisClient.js b/web/app/static/js/modules/corpus_analysis/client/Client.js
similarity index 88%
rename from web/app/static/js/modules/nopaque.CorpusAnalysisClient.js
rename to web/app/static/js/modules/corpus_analysis/client/Client.js
index b64c24d8b0d48d62d5d522e8656e143b20462b6a..990c68517c61cc406d280f06d5cd5fc196539647 100644
--- a/web/app/static/js/modules/nopaque.CorpusAnalysisClient.js
+++ b/web/app/static/js/modules/corpus_analysis/client/Client.js
@@ -1,12 +1,12 @@
 /**
- * This class is used to create a CorpusAnalysisClient object.
+ * This class is used to create a Client object.
  * The client handels the client server communication.
  * It requests data (e.g. the analysis session or query results) from the
  * the server and recieves them, if it dynamicMode is true.
  * If dynamicMode is false, the client can also handle data that is already
  * loaded and not coming in in chunks.
  */
-class CorpusAnalysisClient {
+class Client {
   constructor({corpusId = null,
                socket = null,
                logging = true,
@@ -39,7 +39,7 @@ class CorpusAnalysisClient {
     }
   }
 
-  // Registers one or more SocketEventListeners to the CorpusAnalysisClient.
+  // Registers one or more SocketEventListeners to the Client.
   setSocketEventListeners(socketEventListeners) {
     for (let socketEventListener of socketEventListeners) {
       this.socketEventListeners[socketEventListener.type] = socketEventListener;
@@ -56,7 +56,15 @@ class CorpusAnalysisClient {
     }
   }
 
-  // Registers a CorpusAnalysisDisplay object to the CorpusAnalysisClient.
+
+  // TODO: get rid of this disply stuff and send commands to the viewer
+  // on what to do/show/hide etc
+
+  notifyView(SendWhatToDo) {
+
+  }
+
+  // Registers a CorpusAnalysisDisplay object to the Client.
   setDisplay(type, corpusAnalysisDisplay) {
     this.displays[type] = corpusAnalysisDisplay;
   }
@@ -87,27 +95,26 @@ class CorpusAnalysisClient {
   }
 
   /**
-   * Requests a corpus analysis session via socket.io.
-   * Opens a loading modal at the start of the request.
-   * Will be closed if session has been successfully recieved.
+   * Connects to the corpus analysis session for the specified corpus via
+   * socket.io.
    */
-  requestSession() {
-    console.info('corpus_analysis_init: Client requesting session via',
+  connect() {
+    console.info('corpus_analysis_init: Client connecting to session via',
                  'socket.emit');
-    if (this.displays.init != undefined) {
-      this.displays.init.element.M_Modal.open();
-      this.displays.init.setVisibilityByStatus('waiting');
-    }
+    // if (this.displays.init != undefined) {
+    //   this.displays.init.element.M_Modal.open();
+    //   this.displays.init.setVisibilityByStatus('waiting');
+    // }
     this.socket.emit('corpus_analysis_init', this.corpusId);
   }
 
   /**
-   * Request query data for the query string that has been sent to the server.
+   * Emits query to the server via socket.io. Server will send the results
+   * back.
    */
-  requestQueryData(queryStr) {
-    console.info('corpus_analysis_query: Client requesting query data via',
+  query(queryStr) {
+    console.info('corpus_analysis_query: Client sending query via',
                  'socket.emit for the query', queryStr);
-    // TODO: Display stuff ?
     this.socket.emit('corpus_analysis_query', queryStr);
   }
 }
@@ -236,8 +243,8 @@ class ListenerCallback {
 
 // export Classes from this module
 export {
-  CorpusAnalysisClient,
-  CorpusAnalysisDisplay,
+  Client,
   SocketEventListener,
+  CorpusAnalysisDisplay,
   ListenerCallback,
 };
\ No newline at end of file
diff --git a/web/app/static/js/modules/nopaque.listenerCallbacks.js b/web/app/static/js/modules/corpus_analysis/client/callbacks.js
similarity index 100%
rename from web/app/static/js/modules/nopaque.listenerCallbacks.js
rename to web/app/static/js/modules/corpus_analysis/client/callbacks.js
diff --git a/web/app/static/js/modules/nopaque.listenerFunctions.js b/web/app/static/js/modules/corpus_analysis/client/listeners.js
similarity index 100%
rename from web/app/static/js/modules/nopaque.listenerFunctions.js
rename to web/app/static/js/modules/corpus_analysis/client/listeners.js
diff --git a/web/app/static/js/modules/corpus_analysis/main.js b/web/app/static/js/modules/corpus_analysis/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/web/app/static/js/nopaque.Results.js b/web/app/static/js/modules/corpus_analysis/model/Results.js
similarity index 95%
rename from web/app/static/js/nopaque.Results.js
rename to web/app/static/js/modules/corpus_analysis/model/Results.js
index 2f7778f1d7a096d8002d2a0097a2749e92264cf4..3743553105a31bbfff11ff6d3438e13e185345f6 100644
--- a/web/app/static/js/nopaque.Results.js
+++ b/web/app/static/js/modules/corpus_analysis/model/Results.js
@@ -1,3 +1,9 @@
+/**
+ * These classes are implementing the data store of the corpus_analysis
+ * package. If we follow the idea of the Model View Controller Pattern these
+ * classes combined in the Results class define the Model.
+ */
+
 class Results {
   constructor(data, jsList , metaData) {
   this.data = data;
diff --git a/web/app/static/js/modules/nopaque.InteractionElement.js b/web/app/static/js/modules/corpus_analysis/view/InteractionElement.js
similarity index 100%
rename from web/app/static/js/modules/nopaque.InteractionElement.js
rename to web/app/static/js/modules/corpus_analysis/view/InteractionElement.js
diff --git a/web/app/static/js/modules/corpus_analysis/view/ResultsView.js b/web/app/static/js/modules/corpus_analysis/view/ResultsView.js
new file mode 100644
index 0000000000000000000000000000000000000000..fa0e8b36a8f8d68fd55dc6ac552040476b8b752a
--- /dev/null
+++ b/web/app/static/js/modules/corpus_analysis/view/ResultsView.js
@@ -0,0 +1,790 @@
+/**
+ * This class is implements a View which handles the reprensentation of the
+ * data that has been fetched by the Client of the corpus_analysis. This view
+ * only handles how the data is shown to the user. View extends the list.js
+ * List class.
+ */
+
+class ResultsList extends List {
+  /**
+   * If no options are given when a new instance of this class is created
+   * the options below are used.
+   */
+  static options = {
+    page: 10,
+    pagination: [{
+      name: "paginationTop",
+      paginationClass: "paginationTop",
+      innerWindow: 8,
+      outerWindow: 1
+    }, {
+      paginationClass: "paginationBottom",
+      innerWindow: 8,
+      outerWindow: 1
+    }],
+    valueNames: ["titles", "lc", "c", "rc", {data: ["index"]}],
+    item: `<span></span>`
+  };
+  constructor(idOrElement, options) {
+    super(idOrElement, options);
+    this.options = options;
+    /**
+     * All span tokens which are holding events if expert
+     * mode is on. Collected here to delete later on.
+     */
+    this.eventTokens = {};
+    /**
+    * all token elements which have added
+    * classes like chip and hoverable for expert view. Collected
+    * here to delete later on
+    */
+    this.currentExpertTokenElements = {};
+     // holds True/false for check buttons used to add matches tu sub-results. If checked, it is True. If unchecked, it is false. Buttons for this have the class add. Those little round check buttons.
+    this.addToSubResultsStatus = {};
+    this.addToSubResultsIdsToShow = new Set();  // If check button is pressed its corresponding data_index is saved in this set. The set is shown to the user.
+  }
+
+  helperCreateCpos(cpos_ranges, cpos_values) {
+    let lc;
+    let c;
+    let rc;
+    if (cpos_ranges) {
+      // python range like function from MDN
+      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Sequence_generator_(range)
+      const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
+      lc = range(cpos_values.lc[0], cpos_values.lc[1], 1)
+      c = range(cpos_values.c[0], cpos_values.c[1], 1)
+      rc = range(cpos_values.rc[0], cpos_values.rc[1], 1)
+    } else {
+      lc = cpos_values.lc;
+      c = cpos_values.c;
+      rc = cpos_values.rc;
+    }
+    return {lc: lc, c: c, rc: rc};
+  }
+
+  // handels interactionElements during a pagination navigation
+  // loops over interactionElements and executes callback functions accordingly
+  pageChangeEventInteractionHandler(interactionElements) {
+    // get elements to check thier status
+    for (let interaction of interactionElements.interactions) {
+      if (interaction.checkStatus) {
+        if (interaction.element.checked) {
+          let f_on = interaction.bindThisToCallback("on");
+          let args_on = interaction.callbacks.on.args;
+          f_on(...args_on);
+        } else {
+          let f_off = interaction.bindThisToCallback("off");
+          let args_off = interaction.callbacks.off.args;
+          f_off(...args_off);
+        }
+      } else {
+        let f = interaction.bindThisToCallback("noCheck");
+        let args = interaction.callbacks.noCheck.args;
+        f(...args);
+      }
+    }
+  }
+
+  // get display options from display options form element
+  static getDisplayOptions(htmlId) {
+    // gets display options parameters
+    let displayOptionsFormElement = document.getElementById(htmlId);
+    let displayOptionsFormData = new FormData(displayOptionsFormElement);
+    let displayOptionsData =
+      {
+        "resultsPerPage": displayOptionsFormData.get("display-options-form-results_per_page"),
+        "resultsContex": displayOptionsFormData.get("display-options-form-result_context"),
+        "expertMode": displayOptionsFormData.get("display-options-form-expert_mode")
+      };
+    return displayOptionsData
+  }
+
+  // ###### Functions to add one match to a sub-results ######
+  // activate the add buttons
+  activateAddToSubResults() {
+    subResultsIdListElement.classList.remove("hide");
+    if (subResultsExportElement.classList.contains("hide")) {
+      subResultsCreateElement.classList.remove("hide");
+    }
+    let addToSubResultsBtnElements = document.getElementsByClassName("add");
+    for (let addToSubResultsBtn of addToSubResultsBtnElements) {
+      addToSubResultsBtn.classList.remove("hide");
+    }
+  }
+  // deactivate the add buttons
+  deactivateAddToSubResults() {
+    subResultsIdListElement.classList.add("hide");
+    subResultsCreateElement.classList.add("hide");
+    let addToSubResultsBtnElements = document.getElementsByClassName("add");
+    for (let addToSubResultsBtn of addToSubResultsBtnElements) {
+      addToSubResultsBtn.classList.add("hide");
+    }
+  }
+
+  // Used in addToSubResults and inspect to toggle the design of the check
+  // buttons according to its checked unchecked status.
+  helperActivateBtn(btn) {
+    btn.classList.remove("grey");
+    btn.classList.add("green");
+    btn.textContent = "check";
+  }
+
+  // Used in addToSubResults and inspect to toggle the design of the check
+  // buttons according to its checked unchecked status.
+  helperDeactivateBtn(btn) {
+    btn.classList.remove("green");
+    btn.classList.add("grey");
+    btn.textContent = "add";
+  }
+
+  // Either adds or removes a match to the sub-results. For this it checks
+  // onclick if the current button has been checked or not. For this the
+  // function checks if its status in addToSubResultsStatus is either flase or
+  // true. Adds match to sub-results if status is false if status is true it
+  // removes it.
+  addToSubResults(dataIndex, tableCall=true) {
+    let textarea = subResultsIdListElement.getElementsByTagName("textarea")[0];
+    if (!this.addToSubResultsStatus[dataIndex]
+        || this.addToSubResultsStatus === undefined) {
+      // add button is activated because status is either false or undefined
+      this.helperActivateBtn(event.target);
+      this.addToSubResultsStatus[dataIndex] = true;  // sets status to true
+      this.addToSubResultsIdsToShow.add(dataIndex + 1);  // + 1 because user does not see zero indexd data indexes
+      textarea.textContent = [...this.addToSubResultsIdsToShow].sort(function(a, b){return a-b}).join(", ");  // automaticalle sorts ids into the textarea in ascending order
+      M.textareaAutoResize(textarea);  // after an insert textarea has to be resized manually
+      nrMarkedMatches.textContent = [...this.addToSubResultsIdsToShow].length;
+    } else if (this.addToSubResultsStatus[dataIndex]) {
+      // add button is deactivated because status is true
+      this.helperDeactivateBtn(event.target);
+      this.addToSubResultsStatus[dataIndex] = false;  // sets status to false
+      this.addToSubResultsIdsToShow.delete(dataIndex + 1);  // + 1 because user does not see zero indexd data indexes
+      textarea.textContent = [...this.addToSubResultsIdsToShow].sort(function(a, b){return a-b}).join(", ");  // automaticalle sorts ids into the textarea in ascending order
+      nrMarkedMatches.textContent = [...this.addToSubResultsIdsToShow].length;
+      M.textareaAutoResize(textarea); // after an insert textarea has to be resized manually
+    }
+    // Toggles the create button according to the number of ids in addToSubResultsIdsToShow
+    if ([...this.addToSubResultsIdsToShow].length > 0) {
+      subResultsCreateElement.classList.remove("disabled");
+    } else if ([...this.addToSubResultsIdsToShow].length === 0) {
+      subResultsCreateElement.classList.add("disabled");
+    }
+    if (resultCreationRunning) {
+      subResultsCreateElement.classList.add("disabled");
+    }
+    // After a match as been added or removed the export button will be
+    // hidden because the sub-results have been altered and have to be built
+    // again. Thus subResultsCreateElement has to be shown again.
+    subResultsExportElement.classList.add("hide");
+    subResultsCreateElement.classList.remove("hide");
+    // Also activate/deactivate buttons in the table/jsList results accordingly
+    //if button in inspect was activated/deactivated.
+    // This part only runs if tableCall is false.
+    if (!tableCall) {
+      let tableAddBtn = document.getElementById("query-results").querySelectorAll(`[data-index="${dataIndex}"]`)[0].getElementsByClassName('add')[0].firstElementChild; // gets the add button from the list view
+      if (this.addToSubResultsStatus[dataIndex]) {
+        this.helperActivateBtn(tableAddBtn);
+      } else {
+        this.helperDeactivateBtn(tableAddBtn);
+      }
+    }
+  }
+
+  // Triggers emit to get full match context from server for a number of
+  // matches identified by their data_index.
+  getMatchWithContext(dataIndexes, type) {
+    let tmp_first_cpos = [];
+    let tmp_last_cpos = [];
+    for (let dataIndex of dataIndexes) {
+      tmp_first_cpos.push(results.data.matches[dataIndex].c[0]);
+      tmp_last_cpos.push(results.data.matches[dataIndex].c[1]);
+    }
+    nopaque.socket.emit("corpus_analysis_inspect_match",
+                      {
+                        type: type,
+                        data_indexes: dataIndexes,
+                        first_cpos: tmp_first_cpos,
+                        last_cpos: tmp_last_cpos,
+                      }
+          );
+  }
+
+  // ###### Functions to inspect one match, to show more details ######
+  // activate inspect buttons if progress is 100
+  activateInspect() {
+    if (this.requestQueryProgress === 100) {
+      let inspectBtnElements;
+      inspectBtnElements = document.getElementsByClassName("inspect");
+      for (let inspectBtn of inspectBtnElements) {
+        inspectBtn.classList.remove("disabled");
+      }
+    } else {
+      return
+    }
+  }
+
+  // deactivate inspect buttons
+  deactivateInspect() {
+    let inspectBtnElements;
+    inspectBtnElements = document.getElementsByClassName("inspect");
+    for (let inspectBtn of inspectBtnElements) {
+      inspectBtn.classList.add("disabled");
+    }
+  }
+
+  // ### functions to inspect imported Matches
+  // This function creates an object that is similar to the object that is
+  // being recieved as an answere to the getMatchWithContext Method, which is
+  // triggering an socket.io event.
+  // It is used as an input for show match context in the context of imported
+  // results to be able to inspect matches.
+  createFakeResponse() {
+    contextModal.open();
+    // match nr for user to display derived from data_index
+    let contextMatchNrElement = document.getElementById("context-match-nr");
+    contextMatchNrElement.textContent = this.contextId + 1;
+    let cpos_lookup;
+    let fake_response = {};
+    let contextResultsElement;
+    // function to create one match object from entire imported results
+    // that is passed into the results.jsList.showMatchContext() function
+    fake_response["payload"] = {};
+    let dataIndex = event.target.closest("tr").dataset.index;
+    this.contextId = dataIndex;
+    fake_response.payload["matches"] = [results.data.matches[dataIndex]];
+    contextResultsElement = document.getElementById("context-results");
+    contextResultsElement.innerHTML = "";
+    let {lc, c, rc} = this.helperCreateCpos(results.data.cpos_ranges,
+                                            fake_response.payload.matches[0]);
+    cpos_lookup = {};
+    for (let cpos of lc) {
+      cpos_lookup[cpos] = results.data.cpos_lookup[cpos];
+    }
+    for (let cpos of c) {
+      cpos_lookup[cpos] = results.data.cpos_lookup[cpos];
+    }
+    for (let cpos of rc) {
+      cpos_lookup[cpos] = results.data.cpos_lookup[cpos];
+    }
+    fake_response.payload["cpos_lookup"] = cpos_lookup
+    fake_response.payload["cpos_ranges"] = results.data.cpos_ranges;
+    fake_response.payload["query"] = results.data.query;
+    fake_response.payload["context_id"] = dataIndex + 1;
+    fake_response.payload["match_count"] = fake_response.payload.matches.length
+    fake_response.payload["corpus_type"] = "inspect-result"
+    return fake_response
+  }
+
+  // gets result cpos infos for one dataIndex (list of length 1) to send back to
+  // the server
+  inspect(dataIndex, type) {
+    let contextResultsElement;
+    // get result infos from server and show them in context modal
+    this.contextId = dataIndex[0];
+    contextResultsElement = document.getElementById("context-results");
+    contextResultsElement.innerHTML = "";  // clear it from old inspects
+    this.getMatchWithContext(dataIndex, type);
+    // match nr for user to display derived from data_index
+    let contextMatchNrElement = document.getElementById("context-match-nr");
+    contextMatchNrElement.textContent = this.contextId + 1;
+    contextModal.open();
+    // add a button to add this match to sub results with onclick event
+    let classes = `btn-floating btn waves-effect` +
+                  `waves-light grey right`
+    let addToSubResultsIdsBtn = document.createElement("a");
+    addToSubResultsIdsBtn.setAttribute("class", classes + ` add`);
+    addToSubResultsIdsBtn.innerHTML = '<i class="material-icons">add</i>';
+    addToSubResultsIdsBtn.onclick= () => {this.addToSubResults(dataIndex[0], false)};
+    // checks if a button has already been added to the inspect modal and removes it
+    if (addToSubResultsFromInspectElement.children.length > 0) {
+      addToSubResultsFromInspectElement.firstElementChild.remove();
+    }
+    // Changes the design of the add button according to its checked status
+    // upon opening the inspect modal.
+    if (this.addToSubResultsStatus[dataIndex[0]]) {
+      this.helperActivateBtn(addToSubResultsIdsBtn.firstElementChild);
+    } else if (!this.addToSubResultsStatus[dataIndex[0]]) {
+      this.helperDeactivateBtn(addToSubResultsIdsBtn.firstElementChild);
+    }
+    addToSubResultsFromInspectElement.appendChild(addToSubResultsIdsBtn);
+  }
+
+  // create Element from HTML String helper function
+  HTMLTStrToElement(htmlStr) {
+    // https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
+    let template = document.createElement("template");
+    htmlStr = htmlStr.trim();
+    template.innerHTML = htmlStr;
+    return template.content.firstChild;
+    }
+
+  // Used as a callback to handle incoming match context results when inspect
+  // has been used.
+  showMatchContext(response) {
+    this.contextData;
+    let contextModalLoading;
+    let contextModalReady;
+    let contextResultsElement;
+    let highlightSentencesSwitchElement;
+    let htmlTokenStr;
+    let modalExpertModeSwitchElement;
+    let modalTokenElements;
+    let nrOfContextSentences;
+    let partElement;
+    let token;
+    let tokenHTMLArray;
+    let tokenHTMlElement;
+    let uniqueContextS;
+    let uniqueS;
+
+    this.contextData = response.payload;
+    console.log(this.contextData);
+    this.contextData["cpos_ranges"] = response.payload.cpos_ranges;
+    this.contextData["query"] = results.data.query;
+    this.contextData["context_id"] = this.contextId;
+    this.contextData["match_count"] = this.contextData.matches.length
+    this.contextData["corpus_type"] = "inspect-result"
+    Object.assign(this.contextData, results.metaData);
+    contextResultsElement = document.getElementById("context-results");
+    modalExpertModeSwitchElement = document.getElementById("inspect-display-options-form-expert_mode_inspect");
+    highlightSentencesSwitchElement = document.getElementById("inspect-display-options-form-highlight_sentences");
+    nrOfContextSentences = document.getElementById("context-sentences");
+    uniqueS = new Set();
+    uniqueContextS = new Set();
+    let {lc, c, rc} = this.helperCreateCpos(this.contextData.cpos_ranges,
+                                            this.contextData.matches[0])
+    // create sentence strings as tokens
+    tokenHTMLArray = [];
+    for (let cpos of lc) {
+      token = this.contextData.cpos_lookup[cpos];
+      uniqueS.add(token.s)
+      htmlTokenStr = `<span class="token"` +
+                           `data-sid="${token.s}"` +
+                           `data-cpos="${cpos}">` +
+                       `${token.word}` +
+                     `</span>`;
+      tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
+      tokenHTMLArray.push(tokenHTMlElement);
+    }
+    for (let cpos of c) {
+      token = this.contextData.cpos_lookup[cpos];
+      uniqueContextS.add(token.s);
+      uniqueS.add(token.s);
+      htmlTokenStr = `<span class="token bold light-green"` +
+                           `data-sid="${token.s}"` +
+                           `data-cpos="${cpos}"` +
+                           `style="text-decoration-line: underline;">` +
+                       `${token.word}` +
+                     `</span>`;
+      tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
+      tokenHTMLArray.push(tokenHTMlElement);
+    }
+    this.contextData["context_s_ids"] = Array.from(uniqueContextS);
+    for (let cpos of rc) {
+      token = this.contextData.cpos_lookup[cpos];
+      uniqueS.add(token.s)
+      htmlTokenStr = `<span class="token"` +
+                           `data-sid="${token.s}"` +
+                           `data-cpos="${cpos}">` +
+                       `${token.word}` +
+                     `</span>`;
+      tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
+      tokenHTMLArray.push(tokenHTMlElement);
+    }
+    for (let sId of uniqueS) {
+      let htmlSentence = `<span class="sentence" data-sid="${sId}"></span>`;
+      let sentenceElement = this.HTMLTStrToElement(htmlSentence);
+      for (let tokenElement of tokenHTMLArray) {
+        if (tokenElement.dataset.sid == sId) {
+          sentenceElement.appendChild(tokenElement);
+          sentenceElement.insertAdjacentHTML("beforeend", ` `);
+        } else {
+          continue;
+        }
+      }
+      contextResultsElement.appendChild(sentenceElement);
+    }
+
+
+    // add inspect display options events
+    modalExpertModeSwitchElement.onchange = (event) => {
+      if (event.target.checked) {
+        this.expertModeOn("context-results");
+      } else {
+        this.expertModeOff("context-results")
+      }
+    };
+
+    highlightSentencesSwitchElement.onchange = (event) => {
+      if (event.target.checked) {
+        this.higlightContextSentences();
+      } else {
+      this.unhighlightContextSentences();
+      }
+    };
+
+    nrOfContextSentences.onchange = (event) => {
+      // console.log(event.target.value);
+      this.changeSentenceContext(event.target.value);
+    }
+
+    // checks on new modal opening if switches are checked
+    // if switches are checked functions are executed
+    if (modalExpertModeSwitchElement.checked) {
+      this.expertModeOn("context-results");
+    }
+
+    if (highlightSentencesSwitchElement.checked) {
+      this.higlightContextSentences();
+    }
+
+    // checks the value of the number of sentences to show on modal opening
+    // sets context sentences accordingly
+    this.changeSentenceContext(nrOfContextSentences.value)
+  }
+
+  // splits context text into sentences based on spacy sentence split
+  higlightContextSentences() {
+    let sentences;
+    sentences = document.getElementById("context-results").getElementsByClassName("sentence");
+      for (let s of sentences) {
+        s.insertAdjacentHTML("beforeend", `<span><br><br></span>`)
+      }
+  }
+
+  unhighlightContextSentences() {
+    let sentences;
+    let br;
+    sentences = document.getElementById("context-results").getElementsByClassName("sentence");
+      for (let s of sentences) {
+        br = s.lastChild;
+        br.remove();
+      }
+  }
+
+  // changes how many context sentences in inspect view are shown
+  changeSentenceContext(sValue, maxSValue=10) {
+    let array;
+    let sentences;
+    let toHideArray;
+    let toShowArray;
+    sValue = maxSValue - sValue;
+    // console.log(sValue);
+    sentences = document.getElementById("context-results").getElementsByClassName("sentence");
+    array = Array.from(sentences);
+    if (sValue != 0) {
+      toHideArray = array.slice(0, sValue).concat(array.slice(-(sValue)));
+      toShowArray = array.slice(sValue, 9).concat(array.slice(9, -(sValue)))
+    } else {
+      toHideArray = [];
+      toShowArray = array;
+    }
+    // console.log(array);
+    // console.log("#######");
+    // console.log(toHideArray);
+    for (let s of toHideArray) {
+      s.classList.add("hide");
+    }
+    for (let s of toShowArray) {
+      s.classList.remove("hide");
+    }
+  }
+
+  // ###### Display options changing live how the matches are being displayed ######
+
+  // Event function that changes the shown hits per page.
+  // Just alters the resultsList.page property
+  changeHitsPerPage(event) {
+    try {
+      // console.log(this);
+      this.page = event.target.value;
+      this.update();
+      this.activateInspect();
+      this.pageChangeEventInteractionHandler(interactionElements);
+      if (expertModeSwitchElement.checked) {
+        this.expertModeOn("query-display");  // page holds new result rows, so add new tooltips
+      }
+      nopaque.flash("Updated matches per page.", "corpus")
+    } catch (e) {
+      // console.log(e);
+      // console.log("resultsList has no results right now.");
+    }
+  }
+
+  // Event function triggered on context select change
+  // also if pagination is clicked
+  changeContext(event) {
+    let array;
+    let lc;
+    let newContextValue;
+    let rc;
+    try {
+        if (event.type === "change") {
+            nopaque.flash("Updated context per match!", "corpus");
+        }
+    } catch (e) {
+    } finally {
+        newContextValue = document.getElementById("display-options-form-result_context").value;
+        lc = document.getElementsByClassName("left-context");
+        rc = document.getElementsByClassName("right-context");
+        for (let element of lc) {
+          array = Array.from(element.childNodes);
+          for (let element of array.reverse().slice(newContextValue)) {
+            element.classList.add("hide");
+          }
+          for (let element of array.slice(0, newContextValue)) {
+            element.classList.remove("hide");
+          }
+        }
+        for (let element of rc) {
+          array = Array.from(element.childNodes);
+          for (let element of array.slice(newContextValue)) {
+            element.classList.add("hide");
+          }
+          for (let element of array.slice(0, newContextValue)) {
+            element.classList.remove("hide");
+          }
+        }
+    }
+  }
+
+  // ###### Expert view event functions ######
+  // function to create a tooltip for the current hovered token
+  tooltipEventCreate(event, client) {
+    // console.log("Create Tooltip on mouseover.");
+    let token = client.results.data.cpos_lookup[event.target.dataset.cpos];
+    if (!token) {
+      token = this.contextData.cpos_lookup[event.target.dataset.cpos];
+    }
+    this.addToolTipToTokenElement(event.target, token, client);
+  }
+
+  // Function to destroy the current Tooltip for the current hovered tooltip
+  // on mouse leave
+  tooltipEventDestroy() {
+    // console.log("Tooltip destroy on leave.");
+    this.currentTooltipElement.destroy();
+  }
+
+  // turn the expert mode on for all tokens in the DOM element identified by its htmlID
+  expertModeOn(htmlId, client) {
+    if (!Array.isArray(this.currentExpertTokenElements[htmlId])) {
+      this.currentExpertTokenElements[htmlId] = [];
+    }
+    let container = document.getElementById(htmlId);
+    let tokens = container.querySelectorAll("span.token");
+    this.currentExpertTokenElements[htmlId].push(...tokens);
+    this.eventTokens[htmlId] = [];
+    for (let tokenElement of this.currentExpertTokenElements[htmlId]) {
+      tokenElement.classList.add("chip", "hoverable", "expert-view");
+      const eventCreate = (event, arg) => this.tooltipEventCreate(event, arg);
+      tokenElement.onmouseover = (event) => eventCreate(event, client);
+      tokenElement.onmouseout = () => this.tooltipEventDestroy();
+      this.eventTokens[htmlId].push(tokenElement);
+    }
+  }
+
+  // fuction that creates Tooltip for one token and extracts the corresponding
+  // infos from the result JSON
+  addToolTipToTokenElement(tokenElement, token, client) {
+    this.currentTooltipElement;
+    this.currentTooltipElement = M.Tooltip.init(tokenElement,
+     {"html": `<table>
+                 <tr>
+                   <th>Token information</th>
+                   <th>Source information</th>
+                 </tr>
+                 <tr>
+                   <td class="left-align">
+                     Word: ${token.word}<br>
+                     Lemma: ${token.lemma}<br>
+                     POS: ${token.pos}<br>
+                     Simple POS: ${token.simple_pos}<br>
+                     NER: ${token.ner}
+                   </td>
+                   <td class="left-align">
+                     Title: ${client.results.data.text_lookup[token.text].title}
+                     <br>
+                     Author: ${client.results.data.text_lookup[token.text].author}
+                     <br>
+                     Publishing year: ${client.results.data.text_lookup[token.text].publishing_year}
+                   </td>
+                 </tr>
+               </table>`}
+      );
+  }
+
+  // function to remove extra informations and animations from tokens
+  expertModeOff(htmlId) {
+    // console.log("Expert mode is off.");
+    if (!Array.isArray(this.currentExpertTokenElements[htmlId])) {
+      this.currentExpertTokenElements[htmlId] = [];
+    }
+    if (!Array.isArray(this.eventTokens[htmlId])) {
+      this.eventTokens[htmlId] = [];
+    }
+    for (let tokenElement of this.currentExpertTokenElements[htmlId]) {
+      tokenElement.classList.remove("chip", "hoverable", "expert-view");
+    }
+    this.currentExpertTokenElements[htmlId] = [];
+
+    for (let eventToken of this.eventTokens[htmlId]) {
+      eventToken.onmouseover = "";
+      eventToken.onmouseout = "";
+    }
+  this.eventTokens[htmlId] = [];
+  }
+
+  createResultRowElement(item, chunk, imported=false) {
+    let aCellElement;
+    let addToSubResultsBtn;
+    let cCellElement;
+    let cpos;
+    let fakeResponse;   // used if imported results are being created;
+    let inspectBtn
+    let lcCellElement;
+    let matchNrElement;
+    let matchRowElement;
+    let rcCellElement;
+    let textTitles;
+    let textTitlesCellElement;
+    let token;
+    let values;
+    // gather values from item
+    values = item.values();
+    let {lc, c, rc} = this.helperCreateCpos(chunk.cpos_ranges,
+                                            values)
+    // get infos for full match row
+    matchRowElement = document.createElement("tr");
+    matchRowElement.setAttribute("data-index", values.index)
+    lcCellElement = document.createElement("td");
+    lcCellElement.classList.add("left-context");
+    matchRowElement.appendChild(lcCellElement);
+    for (cpos of lc) {
+      token = chunk.cpos_lookup[cpos];
+      lcCellElement.insertAdjacentHTML("beforeend",
+        `<span class="token" data-cpos="${cpos}">${token.word} </span>`);
+    }
+
+    // get infos for hit of match and set actions
+    textTitles = new Set();
+    aCellElement = document.createElement("td");
+    aCellElement.classList.add("actions");
+    cCellElement = document.createElement("td");
+    cCellElement.classList.add("match-hit");
+    textTitlesCellElement = document.createElement("td");
+    textTitlesCellElement.classList.add("titles");
+    matchNrElement = document.createElement("td");
+    matchNrElement.classList.add("match-nr");
+    matchRowElement.appendChild(cCellElement);
+    matchRowElement.appendChild(aCellElement);
+    for (cpos of c) {
+      token = chunk.cpos_lookup[cpos];
+      cCellElement.insertAdjacentHTML("beforeend",
+        `<span class="token" data-cpos="${cpos}">${token.word} </span>`);
+      // get text titles of every hit cpos token
+      textTitles.add(chunk.text_lookup[token.text].title);
+    }
+    // add some interaction buttons
+    // # some btn css rules and classes
+    let css = `margin-right: 5px; margin-bottom: 5px;`
+    let classes = `btn-floating btn waves-effect` +
+                  `waves-light grey`
+    // # add button to trigger more context to every match td
+    inspectBtn = document.createElement("a");
+    inspectBtn.setAttribute("style", css);
+    inspectBtn.setAttribute("class", classes + ` disabled inspect`
+                            );
+    inspectBtn.innerHTML = '<i class="material-icons inspect-btn">search</i>';
+    // # add btn to add matches to sub-results. hidden per default
+    addToSubResultsBtn = document.createElement("a");
+    addToSubResultsBtn.setAttribute("style", css);
+    addToSubResultsBtn.setAttribute("class", classes + ` hide add`
+                                );
+    addToSubResultsBtn.innerHTML = '<i class="material-icons add-btn">add</i>';
+    aCellElement.appendChild(inspectBtn);
+    aCellElement.appendChild(addToSubResultsBtn);
+    // add text titles at front as first td of one row
+    textTitlesCellElement.textContent = [...textTitles].join(", ");
+    matchRowElement.insertAdjacentHTML("afterbegin", textTitlesCellElement.outerHTML);
+    matchNrElement.textContent = values.index + 1;
+    matchRowElement.insertAdjacentHTML("afterbegin", matchNrElement.outerHTML);
+
+    // get infos for right context of match
+    rcCellElement = document.createElement("td");
+    rcCellElement.classList.add("right-context");
+    matchRowElement.appendChild(rcCellElement);
+    for (cpos of rc) {
+      token = chunk.cpos_lookup[cpos];
+      rcCellElement.insertAdjacentHTML("beforeend",
+        `<span class="token" data-cpos="${cpos}">${token.word} </span>`);
+    }
+    return matchRowElement
+  }
+
+  // creates the HTML table code for the metadata vie in the corpus analysis interface
+  createMetaDataForModal(metaDataObject) {
+    let html = `<div class="col s12">
+                      <table class="highlight">
+                        <thead>
+                          <tr>
+                            <th>Metadata Description</th>
+                            <th>Value</th>
+                          </tr>
+                        </thead>
+                        <tbody>`
+    for (let [outerKey, outerValue] of Object.entries(metaDataObject)) {
+      html += `<tr>
+                  <td style="text-transform: uppercase;">${outerKey.replace(/_/g, " ")}</td>`
+      if (outerKey === "corpus_all_texts" || outerKey === "text_lookup") {
+        html += `<td>
+                  <ul class="collapsible">`
+        for (let [innerKey, innerValue] of Object.entries(outerValue)) {
+          html += `<li class="text-metadata"
+                        data-metadata-key="${outerKey}"
+                        data-text-key="${innerKey}">
+                      <div class="collapsible-header"
+                           data-metadata-key="${outerKey}"
+                           data-text-key="${innerKey}">
+                        <i class="material-icons"
+                           data-metadata-key="${outerKey}"
+                           data-text-key="${innerKey}">info_outline</i>
+                           ${innerValue['author']} - ${innerValue['publishing_year']} -
+                           ${innerValue['title']}
+                      </div>
+                      <div class="collapsible-body">
+                        <span>
+                          <ul id="bibliographic-data-${outerKey}-${innerKey}"
+                              style="column-count: 2;">
+                          </ul>
+                        </span>
+                      </div>
+                    </li>`
+        }
+        html += `</ul>
+                  </td>`
+      } else {
+        html += `<td>${outerValue}</td>`
+      }
+      html += `</tr>`
+    }
+    html += `</tbody>
+              </table>`
+    return html
+  }
+
+  // Creates the text details for the texts shown in the corpus analysis metadata modal.
+  createTextDetails(metaDataObject) {
+    let metadataKey = event.target.dataset.metadataKey;
+    let textKey = event.target.dataset.textKey;
+    let textData = metaDataObject[metadataKey][textKey];
+    let bibliographicData = document.getElementById(`bibliographic-data-${metadataKey}-${textKey}`);
+    bibliographicData.innerHTML = "";
+    for (let [key, value] of Object.entries(textData)) {
+      bibliographicData.insertAdjacentHTML("afterbegin",
+      `
+      <li><span style="text-transform: capitalize;">${key}:</span> ${value}</li>
+      `);
+    }
+  }
+};
diff --git a/web/app/static/js/modules/corpus_analysis/view/displays.js b/web/app/static/js/modules/corpus_analysis/view/displays.js
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/web/app/static/js/modules/nopaque.scrollToTop.js b/web/app/static/js/modules/corpus_analysis/view/scrollToTop.js
similarity index 83%
rename from web/app/static/js/modules/nopaque.scrollToTop.js
rename to web/app/static/js/modules/corpus_analysis/view/scrollToTop.js
index 82b6e77465ac05bde376ee3115a2a39e77f0abcc..d5aed247f42fed14d01893aa7e11cf2cf58dc776 100644
--- a/web/app/static/js/modules/nopaque.scrollToTop.js
+++ b/web/app/static/js/modules/corpus_analysis/view/scrollToTop.js
@@ -1,6 +1,6 @@
 /**
- * Function to show a scrol lto top button if the user has scrolled down
- * 250 pixels from teh headline element.
+ * Function to show a scroll to top button if the user has scrolled down
+ * 250 pixels from the headline element.
  */
 function scrollToTop() {
   let headline = document.querySelector(".headline");
diff --git a/web/app/static/js/nopaque.lists.js b/web/app/static/js/nopaque.lists.js
index f7b640ed97d4d03132849f9c2b5fe3e05143c8fc..306d706e257b50837a52b2891de3f2c77ef6a5c8 100644
--- a/web/app/static/js/nopaque.lists.js
+++ b/web/app/static/js/nopaque.lists.js
@@ -423,789 +423,4 @@ RessourceList.options = {
   },
 };
 
-
-class ResultsList extends List {
-  /**
-   * If no options are given when a new instance of this class is created
-   * the options below are used.
-   */
-  static options = {
-    page: 10,
-    pagination: [{
-      name: "paginationTop",
-      paginationClass: "paginationTop",
-      innerWindow: 8,
-      outerWindow: 1
-    }, {
-      paginationClass: "paginationBottom",
-      innerWindow: 8,
-      outerWindow: 1
-    }],
-    valueNames: ["titles", "lc", "c", "rc", {data: ["index"]}],
-    item: `<span></span>`
-  };
-  constructor(idOrElement, options) {
-    super(idOrElement, options);
-    this.options = options;
-    /**
-     * All span tokens which are holding events if expert
-     * mode is on. Collected here to delete later on.
-     */
-    this.eventTokens = {};
-    /**
-    * all token elements which have added
-    * classes like chip and hoverable for expert view. Collected
-    * here to delete later on
-    */
-    this.currentExpertTokenElements = {};
-     // holds True/false for check buttons used to add matches tu sub-results. If checked, it is True. If unchecked, it is false. Buttons for this have the class add. Those little round check buttons.
-    this.addToSubResultsStatus = {};
-    this.addToSubResultsIdsToShow = new Set();  // If check button is pressed its corresponding data_index is saved in this set. The set is shown to the user.
-  }
-
-  helperCreateCpos(cpos_ranges, cpos_values) {
-    let lc;
-    let c;
-    let rc;
-    if (cpos_ranges) {
-      // python range like function from MDN
-      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Sequence_generator_(range)
-      const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
-      lc = range(cpos_values.lc[0], cpos_values.lc[1], 1)
-      c = range(cpos_values.c[0], cpos_values.c[1], 1)
-      rc = range(cpos_values.rc[0], cpos_values.rc[1], 1)
-    } else {
-      lc = cpos_values.lc;
-      c = cpos_values.c;
-      rc = cpos_values.rc;
-    }
-    return {lc: lc, c: c, rc: rc};
-  }
-
-  // handels interactionElements during a pagination navigation
-  // loops over interactionElements and executes callback functions accordingly
-  pageChangeEventInteractionHandler(interactionElements) {
-    // get elements to check thier status
-    for (let interaction of interactionElements.interactions) {
-      if (interaction.checkStatus) {
-        if (interaction.element.checked) {
-          let f_on = interaction.bindThisToCallback("on");
-          let args_on = interaction.callbacks.on.args;
-          f_on(...args_on);
-        } else {
-          let f_off = interaction.bindThisToCallback("off");
-          let args_off = interaction.callbacks.off.args;
-          f_off(...args_off);
-        }
-      } else {
-        let f = interaction.bindThisToCallback("noCheck");
-        let args = interaction.callbacks.noCheck.args;
-        f(...args);
-      }
-    }
-  }
-
-  // get display options from display options form element
-  static getDisplayOptions(htmlId) {
-    // gets display options parameters
-    let displayOptionsFormElement = document.getElementById(htmlId);
-    let displayOptionsFormData = new FormData(displayOptionsFormElement);
-    let displayOptionsData =
-      {
-        "resultsPerPage": displayOptionsFormData.get("display-options-form-results_per_page"),
-        "resultsContex": displayOptionsFormData.get("display-options-form-result_context"),
-        "expertMode": displayOptionsFormData.get("display-options-form-expert_mode")
-      };
-    return displayOptionsData
-  }
-
-  // ###### Functions to add one match to a sub-results ######
-  // activate the add buttons
-  activateAddToSubResults() {
-    subResultsIdListElement.classList.remove("hide");
-    if (subResultsExportElement.classList.contains("hide")) {
-      subResultsCreateElement.classList.remove("hide");
-    }
-    let addToSubResultsBtnElements = document.getElementsByClassName("add");
-    for (let addToSubResultsBtn of addToSubResultsBtnElements) {
-      addToSubResultsBtn.classList.remove("hide");
-    }
-  }
-  // deactivate the add buttons
-  deactivateAddToSubResults() {
-    subResultsIdListElement.classList.add("hide");
-    subResultsCreateElement.classList.add("hide");
-    let addToSubResultsBtnElements = document.getElementsByClassName("add");
-    for (let addToSubResultsBtn of addToSubResultsBtnElements) {
-      addToSubResultsBtn.classList.add("hide");
-    }
-  }
-
-  // Used in addToSubResults and inspect to toggle the design of the check
-  // buttons according to its checked unchecked status.
-  helperActivateBtn(btn) {
-    btn.classList.remove("grey");
-    btn.classList.add("green");
-    btn.textContent = "check";
-  }
-
-  // Used in addToSubResults and inspect to toggle the design of the check
-  // buttons according to its checked unchecked status.
-  helperDeactivateBtn(btn) {
-    btn.classList.remove("green");
-    btn.classList.add("grey");
-    btn.textContent = "add";
-  }
-
-  // Either adds or removes a match to the sub-results. For this it checks
-  // onclick if the current button has been checked or not. For this the
-  // function checks if its status in addToSubResultsStatus is either flase or
-  // true. Adds match to sub-results if status is false if status is true it
-  // removes it.
-  addToSubResults(dataIndex, tableCall=true) {
-    let textarea = subResultsIdListElement.getElementsByTagName("textarea")[0];
-    if (!this.addToSubResultsStatus[dataIndex]
-        || this.addToSubResultsStatus === undefined) {
-      // add button is activated because status is either false or undefined
-      this.helperActivateBtn(event.target);
-      this.addToSubResultsStatus[dataIndex] = true;  // sets status to true
-      this.addToSubResultsIdsToShow.add(dataIndex + 1);  // + 1 because user does not see zero indexd data indexes
-      textarea.textContent = [...this.addToSubResultsIdsToShow].sort(function(a, b){return a-b}).join(", ");  // automaticalle sorts ids into the textarea in ascending order
-      M.textareaAutoResize(textarea);  // after an insert textarea has to be resized manually
-      nrMarkedMatches.textContent = [...this.addToSubResultsIdsToShow].length;
-    } else if (this.addToSubResultsStatus[dataIndex]) {
-      // add button is deactivated because status is true
-      this.helperDeactivateBtn(event.target);
-      this.addToSubResultsStatus[dataIndex] = false;  // sets status to false
-      this.addToSubResultsIdsToShow.delete(dataIndex + 1);  // + 1 because user does not see zero indexd data indexes
-      textarea.textContent = [...this.addToSubResultsIdsToShow].sort(function(a, b){return a-b}).join(", ");  // automaticalle sorts ids into the textarea in ascending order
-      nrMarkedMatches.textContent = [...this.addToSubResultsIdsToShow].length;
-      M.textareaAutoResize(textarea); // after an insert textarea has to be resized manually
-    }
-    // Toggles the create button according to the number of ids in addToSubResultsIdsToShow
-    if ([...this.addToSubResultsIdsToShow].length > 0) {
-      subResultsCreateElement.classList.remove("disabled");
-    } else if ([...this.addToSubResultsIdsToShow].length === 0) {
-      subResultsCreateElement.classList.add("disabled");
-    }
-    if (resultCreationRunning) {
-      subResultsCreateElement.classList.add("disabled");
-    }
-    // After a match as been added or removed the export button will be
-    // hidden because the sub-results have been altered and have to be built
-    // again. Thus subResultsCreateElement has to be shown again.
-    subResultsExportElement.classList.add("hide");
-    subResultsCreateElement.classList.remove("hide");
-    // Also activate/deactivate buttons in the table/jsList results accordingly
-    //if button in inspect was activated/deactivated.
-    // This part only runs if tableCall is false.
-    if (!tableCall) {
-      let tableAddBtn = document.getElementById("query-results").querySelectorAll(`[data-index="${dataIndex}"]`)[0].getElementsByClassName('add')[0].firstElementChild; // gets the add button from the list view
-      if (this.addToSubResultsStatus[dataIndex]) {
-        this.helperActivateBtn(tableAddBtn);
-      } else {
-        this.helperDeactivateBtn(tableAddBtn);
-      }
-    }
-  }
-
-  // Triggers emit to get full match context from server for a number of
-  // matches identified by their data_index.
-  getMatchWithContext(dataIndexes, type) {
-    let tmp_first_cpos = [];
-    let tmp_last_cpos = [];
-    for (let dataIndex of dataIndexes) {
-      tmp_first_cpos.push(results.data.matches[dataIndex].c[0]);
-      tmp_last_cpos.push(results.data.matches[dataIndex].c[1]);
-    }
-    nopaque.socket.emit("corpus_analysis_inspect_match",
-                      {
-                        type: type,
-                        data_indexes: dataIndexes,
-                        first_cpos: tmp_first_cpos,
-                        last_cpos: tmp_last_cpos,
-                      }
-          );
-  }
-
-  // ###### Functions to inspect one match, to show more details ######
-  // activate inspect buttons if progress is 100
-  activateInspect() {
-    if (this.requestQueryProgress === 100) {
-      let inspectBtnElements;
-      inspectBtnElements = document.getElementsByClassName("inspect");
-      for (let inspectBtn of inspectBtnElements) {
-        inspectBtn.classList.remove("disabled");
-      }
-    } else {
-      return
-    }
-  }
-
-  // deactivate inspect buttons
-  deactivateInspect() {
-    let inspectBtnElements;
-    inspectBtnElements = document.getElementsByClassName("inspect");
-    for (let inspectBtn of inspectBtnElements) {
-      inspectBtn.classList.add("disabled");
-    }
-  }
-
-  // ### functions to inspect imported Matches
-  // This function creates an object that is similar to the object that is
-  // being recieved as an answere to the getMatchWithContext Method, which is
-  // triggering an socket.io event.
-  // It is used as an input for show match context in the context of imported
-  // results to be able to inspect matches.
-  createFakeResponse() {
-    contextModal.open();
-    // match nr for user to display derived from data_index
-    let contextMatchNrElement = document.getElementById("context-match-nr");
-    contextMatchNrElement.textContent = this.contextId + 1;
-    let cpos_lookup;
-    let fake_response = {};
-    let contextResultsElement;
-    // function to create one match object from entire imported results
-    // that is passed into the results.jsList.showMatchContext() function
-    fake_response["payload"] = {};
-    let dataIndex = event.target.closest("tr").dataset.index;
-    this.contextId = dataIndex;
-    fake_response.payload["matches"] = [results.data.matches[dataIndex]];
-    contextResultsElement = document.getElementById("context-results");
-    contextResultsElement.innerHTML = "";
-    let {lc, c, rc} = this.helperCreateCpos(results.data.cpos_ranges,
-                                            fake_response.payload.matches[0]);
-    cpos_lookup = {};
-    for (let cpos of lc) {
-      cpos_lookup[cpos] = results.data.cpos_lookup[cpos];
-    }
-    for (let cpos of c) {
-      cpos_lookup[cpos] = results.data.cpos_lookup[cpos];
-    }
-    for (let cpos of rc) {
-      cpos_lookup[cpos] = results.data.cpos_lookup[cpos];
-    }
-    fake_response.payload["cpos_lookup"] = cpos_lookup
-    fake_response.payload["cpos_ranges"] = results.data.cpos_ranges;
-    fake_response.payload["query"] = results.data.query;
-    fake_response.payload["context_id"] = dataIndex + 1;
-    fake_response.payload["match_count"] = fake_response.payload.matches.length
-    fake_response.payload["corpus_type"] = "inspect-result"
-    return fake_response
-  }
-
-  // gets result cpos infos for one dataIndex (list of length 1) to send back to
-  // the server
-  inspect(dataIndex, type) {
-    let contextResultsElement;
-    // get result infos from server and show them in context modal
-    this.contextId = dataIndex[0];
-    contextResultsElement = document.getElementById("context-results");
-    contextResultsElement.innerHTML = "";  // clear it from old inspects
-    this.getMatchWithContext(dataIndex, type);
-    // match nr for user to display derived from data_index
-    let contextMatchNrElement = document.getElementById("context-match-nr");
-    contextMatchNrElement.textContent = this.contextId + 1;
-    contextModal.open();
-    // add a button to add this match to sub results with onclick event
-    let classes = `btn-floating btn waves-effect` +
-                  `waves-light grey right`
-    let addToSubResultsIdsBtn = document.createElement("a");
-    addToSubResultsIdsBtn.setAttribute("class", classes + ` add`);
-    addToSubResultsIdsBtn.innerHTML = '<i class="material-icons">add</i>';
-    addToSubResultsIdsBtn.onclick= () => {this.addToSubResults(dataIndex[0], false)};
-    // checks if a button has already been added to the inspect modal and removes it
-    if (addToSubResultsFromInspectElement.children.length > 0) {
-      addToSubResultsFromInspectElement.firstElementChild.remove();
-    }
-    // Changes the design of the add button according to its checked status
-    // upon opening the inspect modal.
-    if (this.addToSubResultsStatus[dataIndex[0]]) {
-      this.helperActivateBtn(addToSubResultsIdsBtn.firstElementChild);
-    } else if (!this.addToSubResultsStatus[dataIndex[0]]) {
-      this.helperDeactivateBtn(addToSubResultsIdsBtn.firstElementChild);
-    }
-    addToSubResultsFromInspectElement.appendChild(addToSubResultsIdsBtn);
-  }
-
-  // create Element from HTML String helper function
-  HTMLTStrToElement(htmlStr) {
-    // https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
-    let template = document.createElement("template");
-    htmlStr = htmlStr.trim();
-    template.innerHTML = htmlStr;
-    return template.content.firstChild;
-    }
-
-  // Used as a callback to handle incoming match context results when inspect
-  // has been used.
-  showMatchContext(response) {
-    this.contextData;
-    let contextModalLoading;
-    let contextModalReady;
-    let contextResultsElement;
-    let highlightSentencesSwitchElement;
-    let htmlTokenStr;
-    let modalExpertModeSwitchElement;
-    let modalTokenElements;
-    let nrOfContextSentences;
-    let partElement;
-    let token;
-    let tokenHTMLArray;
-    let tokenHTMlElement;
-    let uniqueContextS;
-    let uniqueS;
-
-    this.contextData = response.payload;
-    console.log(this.contextData);
-    this.contextData["cpos_ranges"] = response.payload.cpos_ranges;
-    this.contextData["query"] = results.data.query;
-    this.contextData["context_id"] = this.contextId;
-    this.contextData["match_count"] = this.contextData.matches.length
-    this.contextData["corpus_type"] = "inspect-result"
-    Object.assign(this.contextData, results.metaData);
-    contextResultsElement = document.getElementById("context-results");
-    modalExpertModeSwitchElement = document.getElementById("inspect-display-options-form-expert_mode_inspect");
-    highlightSentencesSwitchElement = document.getElementById("inspect-display-options-form-highlight_sentences");
-    nrOfContextSentences = document.getElementById("context-sentences");
-    uniqueS = new Set();
-    uniqueContextS = new Set();
-    let {lc, c, rc} = this.helperCreateCpos(this.contextData.cpos_ranges,
-                                            this.contextData.matches[0])
-    // create sentence strings as tokens
-    tokenHTMLArray = [];
-    for (let cpos of lc) {
-      token = this.contextData.cpos_lookup[cpos];
-      uniqueS.add(token.s)
-      htmlTokenStr = `<span class="token"` +
-                           `data-sid="${token.s}"` +
-                           `data-cpos="${cpos}">` +
-                       `${token.word}` +
-                     `</span>`;
-      tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
-      tokenHTMLArray.push(tokenHTMlElement);
-    }
-    for (let cpos of c) {
-      token = this.contextData.cpos_lookup[cpos];
-      uniqueContextS.add(token.s);
-      uniqueS.add(token.s);
-      htmlTokenStr = `<span class="token bold light-green"` +
-                           `data-sid="${token.s}"` +
-                           `data-cpos="${cpos}"` +
-                           `style="text-decoration-line: underline;">` +
-                       `${token.word}` +
-                     `</span>`;
-      tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
-      tokenHTMLArray.push(tokenHTMlElement);
-    }
-    this.contextData["context_s_ids"] = Array.from(uniqueContextS);
-    for (let cpos of rc) {
-      token = this.contextData.cpos_lookup[cpos];
-      uniqueS.add(token.s)
-      htmlTokenStr = `<span class="token"` +
-                           `data-sid="${token.s}"` +
-                           `data-cpos="${cpos}">` +
-                       `${token.word}` +
-                     `</span>`;
-      tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
-      tokenHTMLArray.push(tokenHTMlElement);
-    }
-    for (let sId of uniqueS) {
-      let htmlSentence = `<span class="sentence" data-sid="${sId}"></span>`;
-      let sentenceElement = this.HTMLTStrToElement(htmlSentence);
-      for (let tokenElement of tokenHTMLArray) {
-        if (tokenElement.dataset.sid == sId) {
-          sentenceElement.appendChild(tokenElement);
-          sentenceElement.insertAdjacentHTML("beforeend", ` `);
-        } else {
-          continue;
-        }
-      }
-      contextResultsElement.appendChild(sentenceElement);
-    }
-
-
-    // add inspect display options events
-    modalExpertModeSwitchElement.onchange = (event) => {
-      if (event.target.checked) {
-        this.expertModeOn("context-results");
-      } else {
-        this.expertModeOff("context-results")
-      }
-    };
-
-    highlightSentencesSwitchElement.onchange = (event) => {
-      if (event.target.checked) {
-        this.higlightContextSentences();
-      } else {
-      this.unhighlightContextSentences();
-      }
-    };
-
-    nrOfContextSentences.onchange = (event) => {
-      // console.log(event.target.value);
-      this.changeSentenceContext(event.target.value);
-    }
-
-    // checks on new modal opening if switches are checked
-    // if switches are checked functions are executed
-    if (modalExpertModeSwitchElement.checked) {
-      this.expertModeOn("context-results");
-    }
-
-    if (highlightSentencesSwitchElement.checked) {
-      this.higlightContextSentences();
-    }
-
-    // checks the value of the number of sentences to show on modal opening
-    // sets context sentences accordingly
-    this.changeSentenceContext(nrOfContextSentences.value)
-  }
-
-  // splits context text into sentences based on spacy sentence split
-  higlightContextSentences() {
-    let sentences;
-    sentences = document.getElementById("context-results").getElementsByClassName("sentence");
-      for (let s of sentences) {
-        s.insertAdjacentHTML("beforeend", `<span><br><br></span>`)
-      }
-  }
-
-  unhighlightContextSentences() {
-    let sentences;
-    let br;
-    sentences = document.getElementById("context-results").getElementsByClassName("sentence");
-      for (let s of sentences) {
-        br = s.lastChild;
-        br.remove();
-      }
-  }
-
-  // changes how many context sentences in inspect view are shown
-  changeSentenceContext(sValue, maxSValue=10) {
-    let array;
-    let sentences;
-    let toHideArray;
-    let toShowArray;
-    sValue = maxSValue - sValue;
-    // console.log(sValue);
-    sentences = document.getElementById("context-results").getElementsByClassName("sentence");
-    array = Array.from(sentences);
-    if (sValue != 0) {
-      toHideArray = array.slice(0, sValue).concat(array.slice(-(sValue)));
-      toShowArray = array.slice(sValue, 9).concat(array.slice(9, -(sValue)))
-    } else {
-      toHideArray = [];
-      toShowArray = array;
-    }
-    // console.log(array);
-    // console.log("#######");
-    // console.log(toHideArray);
-    for (let s of toHideArray) {
-      s.classList.add("hide");
-    }
-    for (let s of toShowArray) {
-      s.classList.remove("hide");
-    }
-  }
-
-  // ###### Display options changing live how the matches are being displayed ######
-
-  // Event function that changes the shown hits per page.
-  // Just alters the resultsList.page property
-  changeHitsPerPage(event) {
-    try {
-      // console.log(this);
-      this.page = event.target.value;
-      this.update();
-      this.activateInspect();
-      this.pageChangeEventInteractionHandler(interactionElements);
-      if (expertModeSwitchElement.checked) {
-        this.expertModeOn("query-display");  // page holds new result rows, so add new tooltips
-      }
-      nopaque.flash("Updated matches per page.", "corpus")
-    } catch (e) {
-      // console.log(e);
-      // console.log("resultsList has no results right now.");
-    }
-  }
-
-  // Event function triggered on context select change
-  // also if pagination is clicked
-  changeContext(event) {
-    let array;
-    let lc;
-    let newContextValue;
-    let rc;
-    try {
-        if (event.type === "change") {
-            nopaque.flash("Updated context per match!", "corpus");
-        }
-    } catch (e) {
-    } finally {
-        newContextValue = document.getElementById("display-options-form-result_context").value;
-        lc = document.getElementsByClassName("left-context");
-        rc = document.getElementsByClassName("right-context");
-        for (let element of lc) {
-          array = Array.from(element.childNodes);
-          for (let element of array.reverse().slice(newContextValue)) {
-            element.classList.add("hide");
-          }
-          for (let element of array.slice(0, newContextValue)) {
-            element.classList.remove("hide");
-          }
-        }
-        for (let element of rc) {
-          array = Array.from(element.childNodes);
-          for (let element of array.slice(newContextValue)) {
-            element.classList.add("hide");
-          }
-          for (let element of array.slice(0, newContextValue)) {
-            element.classList.remove("hide");
-          }
-        }
-    }
-  }
-
-  // ###### Expert view event functions ######
-  // function to create a tooltip for the current hovered token
-  tooltipEventCreate(event, client) {
-    // console.log("Create Tooltip on mouseover.");
-    let token = client.results.data.cpos_lookup[event.target.dataset.cpos];
-    if (!token) {
-      token = this.contextData.cpos_lookup[event.target.dataset.cpos];
-    }
-    this.addToolTipToTokenElement(event.target, token, client);
-  }
-
-  // Function to destroy the current Tooltip for the current hovered tooltip
-  // on mouse leave
-  tooltipEventDestroy() {
-    // console.log("Tooltip destroy on leave.");
-    this.currentTooltipElement.destroy();
-  }
-
-  // turn the expert mode on for all tokens in the DOM element identified by its htmlID
-  expertModeOn(htmlId, client) {
-    if (!Array.isArray(this.currentExpertTokenElements[htmlId])) {
-      this.currentExpertTokenElements[htmlId] = [];
-    }
-    let container = document.getElementById(htmlId);
-    let tokens = container.querySelectorAll("span.token");
-    this.currentExpertTokenElements[htmlId].push(...tokens);
-    this.eventTokens[htmlId] = [];
-    for (let tokenElement of this.currentExpertTokenElements[htmlId]) {
-      tokenElement.classList.add("chip", "hoverable", "expert-view");
-      const eventCreate = (event, arg) => this.tooltipEventCreate(event, arg);
-      tokenElement.onmouseover = (event) => eventCreate(event, client);
-      tokenElement.onmouseout = () => this.tooltipEventDestroy();
-      this.eventTokens[htmlId].push(tokenElement);
-    }
-  }
-
-  // fuction that creates Tooltip for one token and extracts the corresponding
-  // infos from the result JSON
-  addToolTipToTokenElement(tokenElement, token, client) {
-    this.currentTooltipElement;
-    this.currentTooltipElement = M.Tooltip.init(tokenElement,
-     {"html": `<table>
-                 <tr>
-                   <th>Token information</th>
-                   <th>Source information</th>
-                 </tr>
-                 <tr>
-                   <td class="left-align">
-                     Word: ${token.word}<br>
-                     Lemma: ${token.lemma}<br>
-                     POS: ${token.pos}<br>
-                     Simple POS: ${token.simple_pos}<br>
-                     NER: ${token.ner}
-                   </td>
-                   <td class="left-align">
-                     Title: ${client.results.data.text_lookup[token.text].title}
-                     <br>
-                     Author: ${client.results.data.text_lookup[token.text].author}
-                     <br>
-                     Publishing year: ${client.results.data.text_lookup[token.text].publishing_year}
-                   </td>
-                 </tr>
-               </table>`}
-      );
-  }
-
-  // function to remove extra informations and animations from tokens
-  expertModeOff(htmlId) {
-    // console.log("Expert mode is off.");
-    if (!Array.isArray(this.currentExpertTokenElements[htmlId])) {
-      this.currentExpertTokenElements[htmlId] = [];
-    }
-    if (!Array.isArray(this.eventTokens[htmlId])) {
-      this.eventTokens[htmlId] = [];
-    }
-    for (let tokenElement of this.currentExpertTokenElements[htmlId]) {
-      tokenElement.classList.remove("chip", "hoverable", "expert-view");
-    }
-    this.currentExpertTokenElements[htmlId] = [];
-
-    for (let eventToken of this.eventTokens[htmlId]) {
-      eventToken.onmouseover = "";
-      eventToken.onmouseout = "";
-    }
-  this.eventTokens[htmlId] = [];
-  }
-
-  createResultRowElement(item, chunk, imported=false) {
-    let aCellElement;
-    let addToSubResultsBtn;
-    let cCellElement;
-    let cpos;
-    let fakeResponse;   // used if imported results are being created;
-    let inspectBtn
-    let lcCellElement;
-    let matchNrElement;
-    let matchRowElement;
-    let rcCellElement;
-    let textTitles;
-    let textTitlesCellElement;
-    let token;
-    let values;
-    // gather values from item
-    values = item.values();
-    let {lc, c, rc} = this.helperCreateCpos(chunk.cpos_ranges,
-                                            values)
-    // get infos for full match row
-    matchRowElement = document.createElement("tr");
-    matchRowElement.setAttribute("data-index", values.index)
-    lcCellElement = document.createElement("td");
-    lcCellElement.classList.add("left-context");
-    matchRowElement.appendChild(lcCellElement);
-    for (cpos of lc) {
-      token = chunk.cpos_lookup[cpos];
-      lcCellElement.insertAdjacentHTML("beforeend",
-        `<span class="token" data-cpos="${cpos}">${token.word} </span>`);
-    }
-
-    // get infos for hit of match and set actions
-    textTitles = new Set();
-    aCellElement = document.createElement("td");
-    aCellElement.classList.add("actions");
-    cCellElement = document.createElement("td");
-    cCellElement.classList.add("match-hit");
-    textTitlesCellElement = document.createElement("td");
-    textTitlesCellElement.classList.add("titles");
-    matchNrElement = document.createElement("td");
-    matchNrElement.classList.add("match-nr");
-    matchRowElement.appendChild(cCellElement);
-    matchRowElement.appendChild(aCellElement);
-    for (cpos of c) {
-      token = chunk.cpos_lookup[cpos];
-      cCellElement.insertAdjacentHTML("beforeend",
-        `<span class="token" data-cpos="${cpos}">${token.word} </span>`);
-      // get text titles of every hit cpos token
-      textTitles.add(chunk.text_lookup[token.text].title);
-    }
-    // add some interaction buttons
-    // # some btn css rules and classes
-    let css = `margin-right: 5px; margin-bottom: 5px;`
-    let classes = `btn-floating btn waves-effect` +
-                  `waves-light grey`
-    // # add button to trigger more context to every match td
-    inspectBtn = document.createElement("a");
-    inspectBtn.setAttribute("style", css);
-    inspectBtn.setAttribute("class", classes + ` disabled inspect`
-                            );
-    inspectBtn.innerHTML = '<i class="material-icons inspect-btn">search</i>';
-    // # add btn to add matches to sub-results. hidden per default
-    addToSubResultsBtn = document.createElement("a");
-    addToSubResultsBtn.setAttribute("style", css);
-    addToSubResultsBtn.setAttribute("class", classes + ` hide add`
-                                );
-    addToSubResultsBtn.innerHTML = '<i class="material-icons add-btn">add</i>';
-    aCellElement.appendChild(inspectBtn);
-    aCellElement.appendChild(addToSubResultsBtn);
-    // add text titles at front as first td of one row
-    textTitlesCellElement.textContent = [...textTitles].join(", ");
-    matchRowElement.insertAdjacentHTML("afterbegin", textTitlesCellElement.outerHTML);
-    matchNrElement.textContent = values.index + 1;
-    matchRowElement.insertAdjacentHTML("afterbegin", matchNrElement.outerHTML);
-
-    // get infos for right context of match
-    rcCellElement = document.createElement("td");
-    rcCellElement.classList.add("right-context");
-    matchRowElement.appendChild(rcCellElement);
-    for (cpos of rc) {
-      token = chunk.cpos_lookup[cpos];
-      rcCellElement.insertAdjacentHTML("beforeend",
-        `<span class="token" data-cpos="${cpos}">${token.word} </span>`);
-    }
-    return matchRowElement
-  }
-
-  // creates the HTML table code for the metadata vie in the corpus analysis interface
-  createMetaDataForModal(metaDataObject) {
-    let html = `<div class="col s12">
-                      <table class="highlight">
-                        <thead>
-                          <tr>
-                            <th>Metadata Description</th>
-                            <th>Value</th>
-                          </tr>
-                        </thead>
-                        <tbody>`
-    for (let [outerKey, outerValue] of Object.entries(metaDataObject)) {
-      html += `<tr>
-                  <td style="text-transform: uppercase;">${outerKey.replace(/_/g, " ")}</td>`
-      if (outerKey === "corpus_all_texts" || outerKey === "text_lookup") {
-        html += `<td>
-                  <ul class="collapsible">`
-        for (let [innerKey, innerValue] of Object.entries(outerValue)) {
-          html += `<li class="text-metadata"
-                        data-metadata-key="${outerKey}"
-                        data-text-key="${innerKey}">
-                      <div class="collapsible-header"
-                           data-metadata-key="${outerKey}"
-                           data-text-key="${innerKey}">
-                        <i class="material-icons"
-                           data-metadata-key="${outerKey}"
-                           data-text-key="${innerKey}">info_outline</i>
-                           ${innerValue['author']} - ${innerValue['publishing_year']} -
-                           ${innerValue['title']}
-                      </div>
-                      <div class="collapsible-body">
-                        <span>
-                          <ul id="bibliographic-data-${outerKey}-${innerKey}"
-                              style="column-count: 2;">
-                          </ul>
-                        </span>
-                      </div>
-                    </li>`
-        }
-        html += `</ul>
-                  </td>`
-      } else {
-        html += `<td>${outerValue}</td>`
-      }
-      html += `</tr>`
-    }
-    html += `</tbody>
-              </table>`
-    return html
-  }
-
-  // Creates the text details for the texts shown in the corpus analysis metadata modal.
-  createTextDetails(metaDataObject) {
-    let metadataKey = event.target.dataset.metadataKey;
-    let textKey = event.target.dataset.textKey;
-    let textData = metaDataObject[metadataKey][textKey];
-    let bibliographicData = document.getElementById(`bibliographic-data-${metadataKey}-${textKey}`);
-    bibliographicData.innerHTML = "";
-    for (let [key, value] of Object.entries(textData)) {
-      bibliographicData.insertAdjacentHTML("afterbegin",
-      `
-      <li><span style="text-transform: capitalize;">${key}:</span> ${value}</li>
-      `);
-    }
-  }
-};
-
-export {RessourceList, ResultsList};
+export { RessourceList, };
diff --git a/web/app/templates/corpora/analyse_corpus.html.j2 b/web/app/templates/corpora/analyse_corpus.html.j2
index 674603cf7d34f6b02deec982a4accfcfb7c05ea3..e980d1c8950b9a79f8e9f5f5467eea42d59dcd49 100644
--- a/web/app/templates/corpora/analyse_corpus.html.j2
+++ b/web/app/templates/corpora/analyse_corpus.html.j2
@@ -65,173 +65,7 @@
 {% include 'modals/export_query_results.html.j2' %}
 {% include 'modals/context_modal.html.j2' %}
 
-<!-- import modules -->
-<script type="module">
-/**
- * First Phase:
- * Document content is loaded and scripts are being imported and executed.
- */
-import {
-  CorpusAnalysisClient,
-  CorpusAnalysisDisplay,
-  SocketEventListener,
-  ListenerCallback,
-} from '../../static/js/modules/nopaque.CorpusAnalysisClient.js';
-import {
-  recieveSession,
-  recieveQueryStatus,
-  recieveQueryData,
-} from '../../static/js/modules/nopaque.listenerFunctions.js';
-import {
-  querySetup,
-  queryRenderResults,
-} from '../../static/js/modules/nopaque.listenerCallbacks.js'
-import {
-  Results,
-  Data,
-  MetaData,
-} from '../../static/js/nopaque.Results.js';
-import {
-  ResultsList,
-} from '../../static/js/nopaque.lists.js';
-import {
-  scrollToTop,
-} from '../../static/js/modules/nopaque.scrollToTop.js';
-import {
-  InteractionElement,
-  InteractionElements,
-} from '../../static/js/modules/nopaque.InteractionElement.js';
-
-/**
- * Second Phase:
- * Asynchronus and event driven code
- */
-document.addEventListener("DOMContentLoaded", () => {
-  // Initialize the CorpusAnalysisClient dynamic mode
-  let corpusId = {{ corpus_id}}
-  const client = new CorpusAnalysisClient({'corpusId': corpusId,
-                                           'socket': nopaque.socket,
-                                           'logging': true,
-                                           'dynamicMode': true});
-  console.info("CorpusAnalysisClient created as client:", client);
-  // Initialize modals which are shown depending on events or client status
-  const initLoadingElement = document.getElementById("init-display");
-  const initLoadingModal = M.Modal.init(initLoadingElement,
-                                        {"dismissible": false});
-  // Set up display elements which are shown depending on the client status
-  const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal);
-  client.getHTMLElements(['#query-display']);
-  const queryDisplay = new CorpusAnalysisDisplay(client.queryDisplay);
-  // Register those display elements to client
-  client.setDisplay("init", initLoadingDisplay);
-  client.setDisplay("query", queryDisplay);
-  /**
-   * Initializing the results object holding all the data of a query.
-   * Also holds the metadata of one query.
-   * Lastly it contains the object ResultsList which is a list.js
-   * subclass which handles the visual representation of the query data.
-   */
-  let displayOptionsData = ResultsList.getDisplayOptions('display-options-form');
-  ResultsList.options.page = displayOptionsData["resultsPerPage"];
-  let data = new Data();
-  let resultsList = new ResultsList("result-list", ResultsList.options);
-  let resultsMetaData = new MetaData();
-  let results = new Results(data, resultsList, resultsMetaData);
-  // Make results part of the client
-  client.results = results;
-  console.info('Initialized the Results object.')
-  /**
-   * Initialization of interactionElemnts
-   * An interactionElement is an object identifing a switch or button via
-   * htmlID. Callbacks are set for these elements which will be triggered on
-   * a pagination interaction by the user or if the status of the element has
-   * been altered. (Like the switche has ben turned on or off).
-   */
-  let interactionElements = new InteractionElements();
-  const expertModeInteraction = new InteractionElement("display-options-form-expert_mode");
-  expertModeInteraction.setCallback('on',
-                                  results.jsList.expertModeOn,
-                                  results.jsList,
-                                  ['query-display', client]);
-  expertModeInteraction.setCallback('off',
-                                    results.jsList.expertModeOff,
-                                    results.jsList,
-                                    ['query-display', client]);
-  const subResultsInteraction = new InteractionElement("add-to-sub-results");
-  subResultsInteraction.setCallback('on',
-                                     results.jsList.activateAddToSubResults,
-                                     results.jsList);
-  subResultsInteraction.setCallback('off',
-                                     results.jsList.deactivateAddToSubResults,
-                                     results.jsList);
-
-  const activateInspectInteraction = new InteractionElement('inspect',
-                                                            false);
-  activateInspectInteraction.setCallback('noCheck',
-                                         results.jsList.activateInspect,
-                                         results.jsList);
-  const changeContextInteraction = new InteractionElement('display-options-form-results_per_page',
-                                                          false);
-  changeContextInteraction.setCallback('noCheck',
-                                       results.jsList.changeContext,
-                                       results.jsList)
-  interactionElements.addInteractions([expertModeInteraction,
-                                       subResultsInteraction,
-                                       activateInspectInteraction,
-                                       changeContextInteraction]);
-
-  /**
-  * Checks if a change for every interactionElement happens and executes
-  * the callbacks accordingly.
-  */
-  interactionElements.onChangeExecute();
-  /**
-   * Register listeners listening to socket.io events and their callbacks
-   * Afterwards load them.
-   */
-  const listenForSession = new SocketEventListener('corpus_analysis_init',
-                                                  recieveSession);
-  const listenForQueryStatus = new SocketEventListener('corpus_analysis_query',
-                                                       recieveQueryStatus);
-  const queryStatusCallback = new ListenerCallback('corpus_analysis_query',
-                                                   querySetup);
-  listenForQueryStatus.setCallbacks([queryStatusCallback]);
-  const listenForQueryData = new SocketEventListener('corpus_analysis_query_results',
-                                                  recieveQueryData);
-  const queryDataCallback = new ListenerCallback('corpus_analysis_query_results',
-                                                 queryRenderResults);
-  listenForQueryData.setCallbacks([queryDataCallback]);
-  client.setSocketEventListeners([listenForSession, listenForQueryStatus,
-                                  listenForQueryData]);
-  client.loadSocketEventListeners();
-  // Session initialization
-  client.requestSession();
-  // Send a query and recieve its answer data
-  let queryFormElement = document.getElementById("query-form");
-  queryFormElement.addEventListener("submit", (event) => {
-    try {
-      /**
-       * Selects first page of result list if pagination is already available
-       * from an query submitted before.
-       * This avoids confusion for the user e.g.: The user was on page 24
-       * reviewing the results and issues a new query. He would not see any
-       * results until the new results reach page 24 or he clicks on another
-       * valid result page element from the new pagination.
-       */
-      let firstPageElement = document.querySelector('a.page');
-      firstPageElement.click();
-    } catch (e) {
-      // No page element is present if first query is submitted.
-    }
-    // Prevent page from reloading on submit
-    event.preventDefault();
-    // Get query string and send query to server
-    results.data.getQueryStr(queryFormElement);
-    client.requestQueryData(results.data.query);
-
-    // Add scrollToTop functionality
-    scrollToTop();
-  });
-});
+<script type="text/javascript"
+        src="web/app/static/js/modules/corpus_analysis/main.js">
 </script>
 {% endblock %}
diff --git a/web/app/templates/corpora/analyse_corpus.html.j2.new.bak b/web/app/templates/corpora/analyse_corpus.html.j2.new.bak
new file mode 100644
index 0000000000000000000000000000000000000000..674603cf7d34f6b02deec982a4accfcfb7c05ea3
--- /dev/null
+++ b/web/app/templates/corpora/analyse_corpus.html.j2.new.bak
@@ -0,0 +1,237 @@
+{% extends "nopaque.html.j2" %}
+
+{% set headline = ' ' %}
+
+{% set full_width = True %}
+{% set imported = False %}
+
+{% block page_content %}
+<div class="col s12">
+  <div class="card">
+    <div class="card-content" style="padding-top: 5px;
+                             padding-bottom: 0px;">
+      <!-- Query form -->
+      <div class="row">
+      <form id="query-form">
+          <div class="col s12 m10">
+            <div class="input-field">
+              <i class="material-icons prefix">search</i>
+              {{ query_form.query() }}
+              {{ query_form.query.label }}
+              <span class="helper-text">
+                <a href="http://cwb.sourceforge.net/files/CQP_Tutorial/">
+                  <i class="material-icons" style="font-size: inherit;">help
+                  </i>
+                  CQP query language tutorial
+                </a>
+              </span>
+            </div>
+          </div>
+          <div class="col s12 m2 right-align">
+            <br class="hide-on-small-only">
+            {{ M.render_field(query_form.submit, material_icon='send') }}
+          </div>
+      </form>
+    </div>
+    </div>
+  </div>
+</div>
+
+<!-- entire results div/card -->
+<div class="col s12" id="query-display">
+  <div class="card">
+    <div class="card-content" id="result-list" style="overflow: hidden;">
+      <div class="error-container hide show-on-error"></div>
+      <div class=" row hide show-on-success">
+        {% include 'interactions/infos.html.j2' %}
+        {% include 'interactions/export.html.j2' %}
+        {% include 'interactions/create.html.j2' %}
+        {% include 'interactions/display.html.j2' %}
+        {% include 'interactions/analysis.html.j2' %}
+        {% include 'interactions/cite.html.j2' %}
+      </div>
+      {% include 'tables/query_results.html.j2' %}
+    </div>
+  </div>
+</div>
+
+<!-- Scroll to top element -->
+{% include 'interactions/scroll_to_top.html.j2' %}
+
+<!-- Modals -->
+{% include 'modals/show_metadata.html.j2' %}
+{% include 'modals/show_text_details.html.j2' %}
+{% include 'modals/analysis_init.html.j2' %}
+{% include 'modals/export_query_results.html.j2' %}
+{% include 'modals/context_modal.html.j2' %}
+
+<!-- import modules -->
+<script type="module">
+/**
+ * First Phase:
+ * Document content is loaded and scripts are being imported and executed.
+ */
+import {
+  CorpusAnalysisClient,
+  CorpusAnalysisDisplay,
+  SocketEventListener,
+  ListenerCallback,
+} from '../../static/js/modules/nopaque.CorpusAnalysisClient.js';
+import {
+  recieveSession,
+  recieveQueryStatus,
+  recieveQueryData,
+} from '../../static/js/modules/nopaque.listenerFunctions.js';
+import {
+  querySetup,
+  queryRenderResults,
+} from '../../static/js/modules/nopaque.listenerCallbacks.js'
+import {
+  Results,
+  Data,
+  MetaData,
+} from '../../static/js/nopaque.Results.js';
+import {
+  ResultsList,
+} from '../../static/js/nopaque.lists.js';
+import {
+  scrollToTop,
+} from '../../static/js/modules/nopaque.scrollToTop.js';
+import {
+  InteractionElement,
+  InteractionElements,
+} from '../../static/js/modules/nopaque.InteractionElement.js';
+
+/**
+ * Second Phase:
+ * Asynchronus and event driven code
+ */
+document.addEventListener("DOMContentLoaded", () => {
+  // Initialize the CorpusAnalysisClient dynamic mode
+  let corpusId = {{ corpus_id}}
+  const client = new CorpusAnalysisClient({'corpusId': corpusId,
+                                           'socket': nopaque.socket,
+                                           'logging': true,
+                                           'dynamicMode': true});
+  console.info("CorpusAnalysisClient created as client:", client);
+  // Initialize modals which are shown depending on events or client status
+  const initLoadingElement = document.getElementById("init-display");
+  const initLoadingModal = M.Modal.init(initLoadingElement,
+                                        {"dismissible": false});
+  // Set up display elements which are shown depending on the client status
+  const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal);
+  client.getHTMLElements(['#query-display']);
+  const queryDisplay = new CorpusAnalysisDisplay(client.queryDisplay);
+  // Register those display elements to client
+  client.setDisplay("init", initLoadingDisplay);
+  client.setDisplay("query", queryDisplay);
+  /**
+   * Initializing the results object holding all the data of a query.
+   * Also holds the metadata of one query.
+   * Lastly it contains the object ResultsList which is a list.js
+   * subclass which handles the visual representation of the query data.
+   */
+  let displayOptionsData = ResultsList.getDisplayOptions('display-options-form');
+  ResultsList.options.page = displayOptionsData["resultsPerPage"];
+  let data = new Data();
+  let resultsList = new ResultsList("result-list", ResultsList.options);
+  let resultsMetaData = new MetaData();
+  let results = new Results(data, resultsList, resultsMetaData);
+  // Make results part of the client
+  client.results = results;
+  console.info('Initialized the Results object.')
+  /**
+   * Initialization of interactionElemnts
+   * An interactionElement is an object identifing a switch or button via
+   * htmlID. Callbacks are set for these elements which will be triggered on
+   * a pagination interaction by the user or if the status of the element has
+   * been altered. (Like the switche has ben turned on or off).
+   */
+  let interactionElements = new InteractionElements();
+  const expertModeInteraction = new InteractionElement("display-options-form-expert_mode");
+  expertModeInteraction.setCallback('on',
+                                  results.jsList.expertModeOn,
+                                  results.jsList,
+                                  ['query-display', client]);
+  expertModeInteraction.setCallback('off',
+                                    results.jsList.expertModeOff,
+                                    results.jsList,
+                                    ['query-display', client]);
+  const subResultsInteraction = new InteractionElement("add-to-sub-results");
+  subResultsInteraction.setCallback('on',
+                                     results.jsList.activateAddToSubResults,
+                                     results.jsList);
+  subResultsInteraction.setCallback('off',
+                                     results.jsList.deactivateAddToSubResults,
+                                     results.jsList);
+
+  const activateInspectInteraction = new InteractionElement('inspect',
+                                                            false);
+  activateInspectInteraction.setCallback('noCheck',
+                                         results.jsList.activateInspect,
+                                         results.jsList);
+  const changeContextInteraction = new InteractionElement('display-options-form-results_per_page',
+                                                          false);
+  changeContextInteraction.setCallback('noCheck',
+                                       results.jsList.changeContext,
+                                       results.jsList)
+  interactionElements.addInteractions([expertModeInteraction,
+                                       subResultsInteraction,
+                                       activateInspectInteraction,
+                                       changeContextInteraction]);
+
+  /**
+  * Checks if a change for every interactionElement happens and executes
+  * the callbacks accordingly.
+  */
+  interactionElements.onChangeExecute();
+  /**
+   * Register listeners listening to socket.io events and their callbacks
+   * Afterwards load them.
+   */
+  const listenForSession = new SocketEventListener('corpus_analysis_init',
+                                                  recieveSession);
+  const listenForQueryStatus = new SocketEventListener('corpus_analysis_query',
+                                                       recieveQueryStatus);
+  const queryStatusCallback = new ListenerCallback('corpus_analysis_query',
+                                                   querySetup);
+  listenForQueryStatus.setCallbacks([queryStatusCallback]);
+  const listenForQueryData = new SocketEventListener('corpus_analysis_query_results',
+                                                  recieveQueryData);
+  const queryDataCallback = new ListenerCallback('corpus_analysis_query_results',
+                                                 queryRenderResults);
+  listenForQueryData.setCallbacks([queryDataCallback]);
+  client.setSocketEventListeners([listenForSession, listenForQueryStatus,
+                                  listenForQueryData]);
+  client.loadSocketEventListeners();
+  // Session initialization
+  client.requestSession();
+  // Send a query and recieve its answer data
+  let queryFormElement = document.getElementById("query-form");
+  queryFormElement.addEventListener("submit", (event) => {
+    try {
+      /**
+       * Selects first page of result list if pagination is already available
+       * from an query submitted before.
+       * This avoids confusion for the user e.g.: The user was on page 24
+       * reviewing the results and issues a new query. He would not see any
+       * results until the new results reach page 24 or he clicks on another
+       * valid result page element from the new pagination.
+       */
+      let firstPageElement = document.querySelector('a.page');
+      firstPageElement.click();
+    } catch (e) {
+      // No page element is present if first query is submitted.
+    }
+    // Prevent page from reloading on submit
+    event.preventDefault();
+    // Get query string and send query to server
+    results.data.getQueryStr(queryFormElement);
+    client.requestQueryData(results.data.query);
+
+    // Add scrollToTop functionality
+    scrollToTop();
+  });
+});
+</script>
+{% endblock %}