diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 29c00da07d96112143452285f633be78ccdecdde..b8e8bd933e7059c5805291074e78b633e0095cd2 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -53,6 +53,8 @@ import { SummaryNodeComponent } from './pages/explorer-page/summary-node/summary
 import { NetworkOverviewComponent } from './pages/explorer-page/network-overview/network-overview/network-overview.component';
 import { InfoTileEdgeComponent } from './components/info-tile-edge/info-tile-edge/info-tile-edge.component';
 import { NetworkEmptyWarningComponent } from './components/network-empty-warning/network-empty-warning.component';
+import { BugReportComponent } from './components/bug-report/bug-report.component';
+import { ViewListComponent } from './components/analysis-panel/view-list/view-list.component';
 
 
 @NgModule({
@@ -95,6 +97,8 @@ import { NetworkEmptyWarningComponent } from './components/network-empty-warning
     NetworkOverviewComponent,
     InfoTileEdgeComponent,
     NetworkEmptyWarningComponent,
+    BugReportComponent,
+    ViewListComponent,
   ],
   imports: [
     BrowserModule,
diff --git a/src/app/components/analysis-panel/analysis-panel.component.html b/src/app/components/analysis-panel/analysis-panel.component.html
index a0caa087593b838021ae67e2f91a498cb1ce680a..bcc633e735f3905ef7eb3505208419a331d7f66f 100644
--- a/src/app/components/analysis-panel/analysis-panel.component.html
+++ b/src/app/components/analysis-panel/analysis-panel.component.html
@@ -13,7 +13,7 @@
         <div class="field has-addons">
           <p class="control" *ngIf="!fullscreen">
             <button
-              (click)="analysis.removeTask(token); close()"
+              (click)="analysis.removeAnalysis(token, tokenType); close()"
               class="button is-rounded is-small is-outlined highlight-danger has-text-danger"
               aria-label="delete"
               pTooltip="Delete analysis"
@@ -70,6 +70,11 @@
                        [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }"
                        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'"
                        (click)="showEULA()">Show EULA</a>
+                  <a class="dropdown-item" pTooltip="Open window to submit a bug report"
+                     tooltipPosition="left"
+                     [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }"
+                     [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'"
+                     (click)="openBugreport()">Report bug</a>
                     <a class="dropdown-item" pTooltip="Opens Drugst.One website"
                        [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" tooltipPosition="left"
                        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'" target="_blank"
@@ -104,20 +109,20 @@
     >
       <div class="tabs is-centered tabs-header">
         <ul>
-          <li [class.is-active]="tab === 'table'">
+          <li [class.is-active]="tab === 'table'" *ngIf="tokenType!=='view'">
             <a (click)="tab = 'table'">Table</a>
           </li>
           <li [class.is-active]="tab === 'network'">
             <a (click)="tab = 'network'">Network</a>
           </li>
-          <li [class.is-active]="tab === 'meta'">
+          <li [class.is-active]="tab === 'meta'" *ngIf="tokenType!=='view'">
             <a (click)="tab = 'meta'">Parameters</a>
           </li>
         </ul>
       </div>
       <div
         class="tab-content meta parameter-tab"
-        *ngIf="task && task.info.done"
+        *ngIf="task && task.info &&  task.info.done"
         [class.is-visible]="tab === 'meta'"
       >
         <div class="columns m-1">
@@ -140,7 +145,8 @@
         </div>
         <div class="columns m-1">
           <div class="column">
-            <table class="table parameter-table" *ngIf="['quick', 'super', 'connect', 'connectSelected'].includes(task.info.algorithm)">
+            <table class="table parameter-table"
+                   *ngIf="['quick', 'super', 'connect', 'connectSelected'].includes(task.info.algorithm)">
               <tbody>
               <tr
                 *ngIf="result && result.geneInteractionDataset !== undefined"
@@ -164,7 +170,8 @@
               </tr>
               </tbody>
             </table>
-            <table class="table parameter-table" *ngIf="!['quick', 'super', 'connect', 'connectSelected'].includes(task.info.algorithm)">
+            <table class="table parameter-table"
+                   *ngIf="!['quick', 'super', 'connect', 'connectSelected'].includes(task.info.algorithm)">
               <tbody>
               <tr
                 *ngIf="result && result.geneInteractionDataset !== undefined"
@@ -186,95 +193,95 @@
                   {{ result.drugInteractionDataset.version }}]
                 </td>
               </tr>
-                <tr *ngIf="task.info.parameters.resultSize !== undefined">
-                  <td>Result Size</td>
-                  <td>{{ task.info.parameters.resultSize }}</td>
-                </tr>
-                <tr *ngIf="task.info.parameters.k !== undefined">
-                  <td>K</td>
-                  <td>{{ task.info.parameters.k }}</td>
-                </tr>
-                <tr *ngIf="task.info.parameters.numTrees !== undefined">
-                  <td>Number of trees</td>
-                  <td>{{ task.info.parameters.numTrees }}</td>
-                </tr>
-                <tr *ngIf="task.info.parameters.tolerance !== undefined">
-                  <td>Tolerance</td>
-                  <td>{{ task.info.parameters.tolerance }}</td>
-                </tr>
-                <tr *ngIf="task.info.parameters.dampingFactor !== undefined">
-                  <td>Damping Factor</td>
-                  <td>{{ task.info.parameters.dampingFactor }}</td>
-                </tr>
-                <tr *ngIf="task.info.parameters.maxDeg !== undefined">
-                  <td>Maximum Degree</td>
-                  <td>{{ task.info.parameters.maxDeg }}</td>
-                </tr>
-                <tr *ngIf="task.info.parameters.hubPenalty !== undefined">
-                  <td>Hub Penality</td>
-                  <td>{{ task.info.parameters.hubPenalty }}</td>
-                </tr>
-                <tr
-                  *ngIf="
+              <tr *ngIf="task.info.parameters.resultSize !== undefined">
+                <td>Result Size</td>
+                <td>{{ task.info.parameters.resultSize }}</td>
+              </tr>
+              <tr *ngIf="task.info.parameters.k !== undefined">
+                <td>K</td>
+                <td>{{ task.info.parameters.k }}</td>
+              </tr>
+              <tr *ngIf="task.info.parameters.numTrees !== undefined">
+                <td>Number of trees</td>
+                <td>{{ task.info.parameters.numTrees }}</td>
+              </tr>
+              <tr *ngIf="task.info.parameters.tolerance !== undefined">
+                <td>Tolerance</td>
+                <td>{{ task.info.parameters.tolerance }}</td>
+              </tr>
+              <tr *ngIf="task.info.parameters.dampingFactor !== undefined">
+                <td>Damping Factor</td>
+                <td>{{ task.info.parameters.dampingFactor }}</td>
+              </tr>
+              <tr *ngIf="task.info.parameters.maxDeg !== undefined">
+                <td>Maximum Degree</td>
+                <td>{{ task.info.parameters.maxDeg }}</td>
+              </tr>
+              <tr *ngIf="task.info.parameters.hubPenalty !== undefined">
+                <td>Hub Penality</td>
+                <td>{{ task.info.parameters.hubPenalty }}</td>
+              </tr>
+              <tr
+                *ngIf="
                     task.info.parameters.includeIndirectDrugs !== undefined &&
                     task.info.target === 'drug'
                   "
-                >
-                  <td>Include indirect drugs</td>
-                  <td>
-                    <app-fa-solid-icon
-                      *ngIf="task.info.parameters.includeIndirectDrugs"
-                      icon="check"
-                      title="indirect drugs included"
-                      classString="has-text-success"
-                    ></app-fa-solid-icon>
-                    <app-fa-solid-icon
-                      *ngIf="!task.info.parameters.includeIndirectDrugs"
-                      icon="times"
-                      classString="has-text-danger"
-                      title="indirect drugs excluded"
-                    ></app-fa-solid-icon>
-                  </td>
-                </tr>
-                <tr
-                  *ngIf="
+              >
+                <td>Include indirect drugs</td>
+                <td>
+                  <app-fa-solid-icon
+                    *ngIf="task.info.parameters.includeIndirectDrugs"
+                    icon="check"
+                    title="indirect drugs included"
+                    classString="has-text-success"
+                  ></app-fa-solid-icon>
+                  <app-fa-solid-icon
+                    *ngIf="!task.info.parameters.includeIndirectDrugs"
+                    icon="times"
+                    classString="has-text-danger"
+                    title="indirect drugs excluded"
+                  ></app-fa-solid-icon>
+                </td>
+              </tr>
+              <tr
+                *ngIf="
                     task.info.parameters.includeNonApprovedDrugs !==
                       undefined && task.info.target === 'drug'
                   "
-                >
-                  <td>Include non-approved drugs</td>
-                  <td>
-                    <app-fa-solid-icon
-                      *ngIf="task.info.parameters.includeNonApprovedDrugs"
-                      icon="check"
-                      title="non-approved drugs included"
-                      classString="has-text-success"
-                    ></app-fa-solid-icon>
-                    <app-fa-solid-icon
-                      *ngIf="!task.info.parameters.includeNonApprovedDrugs"
-                      icon="times"
-                      classString="has-text-danger"
-                      title="non-approved drugs excluded"
-                    ></app-fa-solid-icon>
-                  </td>
-                </tr>
-                <tr *ngIf="task.info.parameters.customEdges !== undefined">
-                  <td>Include all displayed edges</td>
-                  <td>
-                    <app-fa-solid-icon
-                      *ngIf="task.info.parameters.customEdges"
-                      icon="check"
-                      title="custom edges drugs included"
-                      classString="has-text-success"
-                    ></app-fa-solid-icon>
-                    <app-fa-solid-icon
-                      *ngIf="!task.info.parameters.customEdges"
-                      icon="times"
-                      classString="has-text-danger"
-                      title="custom edges drugs excluded"
-                    ></app-fa-solid-icon>
-                  </td>
-                </tr>
+              >
+                <td>Include non-approved drugs</td>
+                <td>
+                  <app-fa-solid-icon
+                    *ngIf="task.info.parameters.includeNonApprovedDrugs"
+                    icon="check"
+                    title="non-approved drugs included"
+                    classString="has-text-success"
+                  ></app-fa-solid-icon>
+                  <app-fa-solid-icon
+                    *ngIf="!task.info.parameters.includeNonApprovedDrugs"
+                    icon="times"
+                    classString="has-text-danger"
+                    title="non-approved drugs excluded"
+                  ></app-fa-solid-icon>
+                </td>
+              </tr>
+              <tr *ngIf="task.info.parameters.customEdges !== undefined">
+                <td>Include all displayed edges</td>
+                <td>
+                  <app-fa-solid-icon
+                    *ngIf="task.info.parameters.customEdges"
+                    icon="check"
+                    title="custom edges drugs included"
+                    classString="has-text-success"
+                  ></app-fa-solid-icon>
+                  <app-fa-solid-icon
+                    *ngIf="!task.info.parameters.customEdges"
+                    icon="times"
+                    classString="has-text-danger"
+                    title="custom edges drugs excluded"
+                  ></app-fa-solid-icon>
+                </td>
+              </tr>
               </tbody>
             </table>
           </div>
@@ -380,7 +387,7 @@
       </div>
       <div
         class="content tab-content scrollable table-tab"
-        *ngIf="task && task.info.done"
+        *ngIf="task && task.info && task.info.done"
         [class.is-visible]="tab === 'table'"
       >
         <div *ngIf="task.info.target === 'drug'">
diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts
index df8243113127278989591fb221774f0371bf7ac2..899f07b8940815cc8a7f1d7bd07746ce3ef0a6e5 100644
--- a/src/app/components/analysis-panel/analysis-panel.component.ts
+++ b/src/app/components/analysis-panel/analysis-panel.component.ts
@@ -26,7 +26,7 @@ import {
 } from '../../interfaces';
 import {NetworkSettings} from '../../network-settings';
 import {NetexControllerService} from 'src/app/services/netex-controller/netex-controller.service';
-import {mapCustomEdge} from 'src/app/main-network';
+import {mapCustomEdge, mapNetexEdge, ProteinNetwork} from 'src/app/main-network';
 import {DrugstoneConfigService} from 'src/app/services/drugstone-config/drugstone-config.service';
 import {NetworkHandlerService} from 'src/app/services/network-handler/network-handler.service';
 import {LegendService} from 'src/app/services/legend-service/legend-service.service';
@@ -56,6 +56,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
   @ViewChild('networkWithLegend', {static: false}) networkWithLegendEl: ElementRef;
   @Input() token: string | null = null;
+  @Input() tokenType: string | null = null;
 
 
   @Output() tokenChange = new EventEmitter<string | null>();
@@ -73,7 +74,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
   public nodeData: { nodes: any, edges: any } = {nodes: null, edges: null};
   // private drugNodes: any[] = [];
   // private drugEdges: any[] = [];
-  public tab: 'meta' | 'network' | 'table' = 'table';
+  public tab: 'meta' | 'network' | 'table' = 'network';
 
   // public adjacentDrugs = false;
   // public adjacentDrugList: Node[] = [];
@@ -116,7 +117,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
   constructor(public legendService: LegendService, public networkHandler: NetworkHandlerService, public drugstoneConfig: DrugstoneConfigService, private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService, public loadingScreen: LoadingScreenService) {
     try {
       this.versionString = version;
-    }catch (e){
+    } catch (e) {
     }
   }
 
@@ -145,255 +146,474 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     }
   }
 
-  private async refresh() {
-    if (this.token) {
-      this.loadingScreen.stateUpdate(true);
-      this.task = await this.getTask(this.token);
+  private async refreshView() {
+    this.loading = true;
+    this.loadingScreen.stateUpdate(true);
+    this.getView(this.token).then(async view => {
+      this.task = view;
+      this.result = view;
+      this.drugstoneConfig.set_analysisConfig(view.config);
       this.analysis.switchSelection(this.token);
+      this.loadingScreen.stateUpdate(false);
+
+
+      // Reset
+      this.nodeData = {nodes: null, edges: null};
+      // this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = '';
+      // this.networkHandler.activeNetwork.networkInternal = null;
+      // Create+
+      return new Promise<any>(async (resolve, reject) => {
+        const nodes = view.network.nodes;
+        let edges = view.network.edges;
+
+        if (this.drugstoneConfig.config.autofillEdges && nodes.length) {
+          const node_map = {};
+          nodes.filter(n => n.drugstoneType === 'protein').forEach(node => {
+            if (typeof node.drugstoneId === 'string') {
+              if (node_map[node.drugstoneId]) {
+                node_map[node.drugstoneId].push(node.id);
+              } else {
+                node_map[node.drugstoneId] = [node.id];
+              }
+            } else {
+              node.drugstoneId.forEach(n => {
+                if (node_map[n]) {
+                  node_map[n].push(node.id);
+                } else {
+                  node_map[n] = [node.id];
+                }
+              });
+            }
+          });
+          const netexEdges = await this.netex.fetchEdges(nodes, this.drugstoneConfig.config.interactionProteinProtein, this.drugstoneConfig.config.licensedDatasets);
+          edges.push(...netexEdges.map(netexEdge => mapNetexEdge(netexEdge, this.drugstoneConfig.currentConfig(), node_map)).flatMap(e => e));
+        }
 
-      if (this.task.info.algorithm === 'degree') {
-        this.tableDrugScoreTooltip =
-          'Normalized number of direct interactions of the drug with the seeds. ' +
-          'The higher the score, the more relevant the drug.';
-        this.tableProteinScoreTooltip =
-          'Normalized number of direct interactions of the protein with the seeds. ' +
-          'The higher the score, the more relevant the protein.';
-      } else if (this.task.info.algorithm === 'closeness' || this.task.info.algorithm === 'quick' || this.task.info.algorithm === 'super') {
-        this.tableDrugScoreTooltip =
-          'Normalized inverse mean distance of the drug to the seeds. ' +
-          'The higher the score, the more relevant the drug.';
-        this.tableProteinScoreTooltip =
-          'Normalized inverse mean distance of the protein to the seeds. ' +
-          'The higher the score, the more relevant the protein.';
-      } else if (this.task.info.algorithm === 'trustrank') {
-        this.tableDrugScoreTooltip =
-          'Amount of ‘trust’ on the drug at termination of the algorithm. ' +
-          'The higher the score, the more relevant the drug.';
-        this.tableProteinScoreTooltip =
-          'Amount of ‘trust’ on the protein at termination of the algorithm. ' +
-          'The higher the score, the more relevant the protein.';
-      } else if (this.task.info.algorithm === 'proximity') {
-        this.tableDrugScoreTooltip =
-          'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' +
-          'The lower the score, the more relevant the drug.';
-        this.tableProteinScoreTooltip =
-          'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' +
-          'The lower the score, the more relevant the drug.';
-      }
+        const edge_map = {};
+
+        edges = edges.filter(edge => {
+          if (edge_map[edge.to] && edge_map[edge.to].indexOf(edge.from) !== -1) {
+            return false;
+          }
+          if (edge_map[edge.from] && edge_map[edge.from].indexOf(edge.to) !== -1) {
+            return false;
+          }
+          if (!edge_map[edge.from]) {
+            edge_map[edge.from] = [edge.to];
+          } else {
+            edge_map[edge.from].push(edge.to);
+          }
+          return true;
+        });
+
+        // @ts-ignore
+        if (!this.drugstoneConfig.selfReferences) {
+          edges = edges.filter(el => el.from !== el.to);
+        }
+
+        this.networkHandler.activeNetwork.inputNetwork = {nodes: nodes, edges: edges};
+        this.nodeData.nodes = new vis.DataSet(nodes);
+        this.nodeData.edges = new vis.DataSet(edges);
+        const container = this.networkHandler.activeNetwork.networkEl.nativeElement;
+        const isBig = nodes.length > 100 || edges.length > 100;
+        const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig());
+        // @ts-ignore
+        options.groups = this.drugstoneConfig.currentConfig().nodeGroups;
+        // @ts-ignore
+        for (const g of Object.values(options.groups)) {
+          // @ts-ignore
+          delete g.renderer;
+        }
+        if (this.drugstoneConfig.config.physicsOn) {
+          this.drugstoneConfig.config.physicsOn = !isBig;
+        }
+        this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options);
+
+        if (isBig) {
+          resolve(nodes);
+        }
+        this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', async () => {
+          if (!this.drugstoneConfig.config.physicsOn || this.networkHandler.activeNetwork.isBig()) {
+            this.networkHandler.activeNetwork.updatePhysicsEnabled(false);
+          }
+          this.networkHandler.updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()).then(() => {
+            resolve(nodes);
+          });
+        });
+      }).then(() => {
+        this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => {
+          this.showDetailsChange.emit(null);
+        });
 
-      if (this.task && this.task.info.done) {
+        this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => {
+          const nodeIds: Array<string> = properties.nodes;
+          if (nodeIds.length > 0) {
+            const nodeId = nodeIds[0];
+            const node = this.nodeData.nodes.get(nodeId);
+            if (node.drugstoneId === undefined || node.nodeType === 'drug' || node.drugstoneType !== 'protein') {
+              this.analysis.unmappedNodeToast();
+              return;
+            }
+            const wrapper = getWrapperFromNode(node);
+            if (this.analysis.inSelection(wrapper)) {
+              this.analysis.removeItems([wrapper]);
+              this.analysis.getCount();
+            } else {
+              this.analysis.addItems([wrapper]);
+              this.analysis.getCount();
+            }
+          }
+        });
 
-        this.loading = true;
-        this.netex.getTaskResult(this.token).then(async result => {
-          this.drugstoneConfig.set_analysisConfig(result.parameters.config);
-          this.result = result;
-          if (this.result.parameters.target === 'drug') {
-            this.legendService.add_to_context('drug');
+        this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => {
+          if (properties.nodes.length === 0 && properties.edges.length === 1) {
+            // clicked on one edge
+            const edgeId = properties.edges[0];
+            this.networkHandler.activeNetwork.openEdgeSummary(edgeId);
           } else {
-            this.legendService.add_to_context('drugTarget');
+            this.networkHandler.activeNetwork.activeEdge = null;
+            const selectedNodes = this.nodeData.nodes.get(properties.nodes);
+            if (selectedNodes.length > 0) {
+              this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0]));
+            } else {
+              this.showDetailsChange.emit(null);
+            }
           }
-          const nodeAttributes = this.result.nodeAttributes || {};
-
-          this.networkHandler.activeNetwork.seedMap = nodeAttributes.isSeed || {};
-
-          // Reset
-          this.nodeData = {nodes: null, edges: null};
-          this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = '';
-          this.networkHandler.activeNetwork.networkInternal = null;
-          // Create
-          await this.createNetwork(this.result).then(nw => {
-            return new Promise<any>((resolve, reject) => {
-
-              const nodes = nw.nodes;
-              const edges = nw.edges;
-              this.networkHandler.activeNetwork.inputNetwork = {nodes: nodes, edges: edges};
-              this.nodeData.nodes = new vis.DataSet(nodes);
-              this.nodeData.edges = new vis.DataSet(edges);
-              const container = this.networkHandler.activeNetwork.networkEl.nativeElement;
-              const isBig = nodes.length > 100 || edges.length > 100;
-              const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig());
-              // @ts-ignore
-              options.groups = this.drugstoneConfig.currentConfig().nodeGroups;
-              // @ts-ignore
-              for (const g of Object.values(options.groups)) {
-                // @ts-ignore
-                delete g.renderer;
+        });
+        this.analysis.subscribeList((items, selected) => {
+          // return if analysis panel is closed or no nodes are loaded
+          if (!this.token) {
+            return;
+          }
+
+          if (selected !== null) {
+            const updatedNodes: Node[] = [];
+            for (const item of items) {
+              const node = this.nodeData.nodes.get(item.id);
+              if (!node) {
+                continue;
               }
-              if (this.drugstoneConfig.config.physicsOn) {
-                this.drugstoneConfig.config.physicsOn = !isBig;
+              const pos = this.networkHandler.activeNetwork.networkInternal.getPositions([item.id]);
+              node.x = pos[item.id].x;
+              node.y = pos[item.id].y;
+              const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
+              const nodeStyled = NetworkSettings.getNodeStyle(
+                node,
+                this.drugstoneConfig.currentConfig(),
+                isSeed,
+                selected,
+                this.networkHandler.activeNetwork.getGradient(item.id),
+                this.networkHandler.activeNetwork.nodeRenderer
+              );
+              updatedNodes.push(nodeStyled);
+            }
+            this.nodeData.nodes.update(updatedNodes);
+
+            const proteinSelection = this.tableSelectedProteins;
+            for (const item of items) {
+              // TODO: Refactor!
+              const found = proteinSelection.findIndex((i) => getProteinNodeId(i) === item.id);
+              const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
+              if (selected && found === -1 && tableItem) {
+                proteinSelection.push(tableItem);
               }
-              this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options);
-              if (isBig) {
-                resolve(nodes);
+              if (!selected && found !== -1 && tableItem) {
+                proteinSelection.splice(found, 1);
               }
-              this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', async () => {
-                if (!this.drugstoneConfig.config.physicsOn || this.networkHandler.activeNetwork.isBig()) {
-                  this.networkHandler.activeNetwork.updatePhysicsEnabled(false);
-                }
-                this.networkHandler.updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()).then(() => {
-                  resolve(nodes);
-                });
-              });
-            }).then(nodes => {
+            }
+            this.tableSelectedProteins = [...proteinSelection];
+          } else {
+            // else: selected is null
+            const updatedNodes = [];
+            this.nodeData.nodes.forEach((node) => {
+              const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
+              if (!isSeed) {
+                return;
+              }
+              const nodeStyled = NetworkSettings.getNodeStyle(
+                node,
+                this.drugstoneConfig.currentConfig(),
+                isSeed,
+                selected,
+                this.networkHandler.activeNetwork.getGradient(node.id),
+                this.networkHandler.activeNetwork.nodeRenderer
+              );
+              updatedNodes.push(nodeStyled);
+            });
+            this.nodeData.nodes.update(updatedNodes);
+
+            const proteinSelection = [];
+            for (const item of items) {
+              const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
+              if (tableItem) {
+                proteinSelection.push(tableItem);
+              }
+            }
+            this.tableSelectedProteins = [...proteinSelection];
+          }
+        });
+        this.emitVisibleItems(true);
+      });
+    });
+  }
 
-              this.tableDrugs = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'drug');
-              this.tableDrugs.forEach((r) => {
-                r.rawScore = r.score;
-              });
+
+  private async refreshTask() {
+    this.loadingScreen.stateUpdate(true);
+    this.task = await this.getTask(this.token);
+    this.analysis.switchSelection(this.token);
+
+    if (this.task.info.algorithm === 'degree') {
+      this.tableDrugScoreTooltip =
+        'Normalized number of direct interactions of the drug with the seeds. ' +
+        'The higher the score, the more relevant the drug.';
+      this.tableProteinScoreTooltip =
+        'Normalized number of direct interactions of the protein with the seeds. ' +
+        'The higher the score, the more relevant the protein.';
+    } else if (this.task.info.algorithm === 'closeness' || this.task.info.algorithm === 'quick' || this.task.info.algorithm === 'super') {
+      this.tableDrugScoreTooltip =
+        'Normalized inverse mean distance of the drug to the seeds. ' +
+        'The higher the score, the more relevant the drug.';
+      this.tableProteinScoreTooltip =
+        'Normalized inverse mean distance of the protein to the seeds. ' +
+        'The higher the score, the more relevant the protein.';
+    } else if (this.task.info.algorithm === 'trustrank') {
+      this.tableDrugScoreTooltip =
+        'Amount of ‘trust’ on the drug at termination of the algorithm. ' +
+        'The higher the score, the more relevant the drug.';
+      this.tableProteinScoreTooltip =
+        'Amount of ‘trust’ on the protein at termination of the algorithm. ' +
+        'The higher the score, the more relevant the protein.';
+    } else if (this.task.info.algorithm === 'proximity') {
+      this.tableDrugScoreTooltip =
+        'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' +
+        'The lower the score, the more relevant the drug.';
+      this.tableProteinScoreTooltip =
+        'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' +
+        'The lower the score, the more relevant the drug.';
+    }
+
+    if (this.task && this.task.info && this.task.info.done) {
+
+      this.loading = true;
+      this.netex.getTaskResult(this.token).then(async result => {
+        this.drugstoneConfig.set_analysisConfig(result.parameters.config);
+        this.result = result;
+        if (this.result.parameters.target === 'drug') {
+          this.legendService.add_to_context('drug');
+        } else {
+          this.legendService.add_to_context('drugTarget');
+        }
+        const nodeAttributes = this.result.nodeAttributes || {};
+
+        this.networkHandler.activeNetwork.seedMap = nodeAttributes.isSeed || {};
+
+        // Reset
+        this.nodeData = {nodes: null, edges: null};
+        this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = '';
+        this.networkHandler.activeNetwork.networkInternal = null;
+        // Create
+        await this.createNetwork(this.result).then(nw => {
+          return new Promise<any>((resolve, reject) => {
+
+            const nodes = nw.nodes;
+            const edges = nw.edges;
+            this.networkHandler.activeNetwork.inputNetwork = {nodes: nodes, edges: edges};
+            this.nodeData.nodes = new vis.DataSet(nodes);
+            this.nodeData.edges = new vis.DataSet(edges);
+            const container = this.networkHandler.activeNetwork.networkEl.nativeElement;
+            const isBig = nodes.length > 100 || edges.length > 100;
+            const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig());
+            // @ts-ignore
+            options.groups = this.drugstoneConfig.currentConfig().nodeGroups;
+            // @ts-ignore
+            for (const g of Object.values(options.groups)) {
               // @ts-ignore
-              this.tableDrugs.sort((a, b) => b.score - a.score);
-              this.rankTable(this.tableDrugs);
-              this.tableProteins = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'protein');
-              this.tableSelectedProteins = [];
-              this.tableProteins.forEach((r) => {
-                r.rawScore = r.score;
-                r.isSeed = this.networkHandler.activeNetwork.seedMap[r.id];
-                const wrapper = getWrapperFromNode(r);
+              delete g.renderer;
+            }
+            if (this.drugstoneConfig.config.physicsOn) {
+              this.drugstoneConfig.config.physicsOn = !isBig;
+            }
+            this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options);
+
+            if (isBig) {
+              resolve(nodes);
+            }
+            this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', async () => {
+              if (!this.drugstoneConfig.config.physicsOn || this.networkHandler.activeNetwork.isBig()) {
+                this.networkHandler.activeNetwork.updatePhysicsEnabled(false);
+              }
+              this.networkHandler.updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()).then(() => {
+                resolve(nodes);
+              });
+            });
+          }).then(nodes => {
+
+            this.tableDrugs = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'drug');
+            this.tableDrugs.forEach((r) => {
+              r.rawScore = r.score;
+            });
+            // @ts-ignore
+            this.tableDrugs.sort((a, b) => b.score - a.score);
+            this.rankTable(this.tableDrugs);
+            this.tableProteins = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'protein');
+            this.tableSelectedProteins = [];
+            this.tableProteins.forEach((r) => {
+              r.rawScore = r.score;
+              r.isSeed = this.networkHandler.activeNetwork.seedMap[r.id];
+              const wrapper = getWrapperFromNode(r);
+              if (this.analysis.inSelection(wrapper)) {
+                this.tableSelectedProteins.push(r);
+              }
+            });
+            this.tableProteins.sort((a, b) => b.score - a.score);
+            this.rankTable(this.tableProteins);
+
+            this.tableHasScores = ['trustrank', 'closeness', 'degree', 'betweenness', 'quick', 'super']
+              .indexOf(this.task.info.algorithm) !== -1;
+            if (this.tableHasScores) {
+              this.toggleNormalization(true);
+            }
+            this.networkHandler.activeNetwork.networkInternal.setData({nodes: undefined, edge: undefined});
+            setTimeout(() => {
+              this.networkHandler.activeNetwork.networkInternal.setData(this.nodeData);
+            }, 1000);
+
+            this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => {
+              this.showDetailsChange.emit(null);
+            });
+
+            this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => {
+              const nodeIds: Array<string> = properties.nodes;
+              if (nodeIds.length > 0) {
+                const nodeId = nodeIds[0];
+                const node = this.nodeData.nodes.get(nodeId);
+                if (node.drugstoneId === undefined || node.nodeType === 'drug' || node.drugstoneType !== 'protein') {
+                  this.analysis.unmappedNodeToast();
+                  return;
+                }
+                const wrapper = getWrapperFromNode(node);
                 if (this.analysis.inSelection(wrapper)) {
-                  this.tableSelectedProteins.push(r);
+                  this.analysis.removeItems([wrapper]);
+                  this.analysis.getCount();
+                } else {
+                  this.analysis.addItems([wrapper]);
+                  this.analysis.getCount();
                 }
-              });
-              this.tableProteins.sort((a, b) => b.score - a.score);
-              this.rankTable(this.tableProteins);
-
-              this.tableHasScores = ['trustrank', 'closeness', 'degree', 'betweenness', 'quick', 'super']
-                .indexOf(this.task.info.algorithm) !== -1;
-              if (this.tableHasScores) {
-                this.toggleNormalization(true);
               }
-              this.networkHandler.activeNetwork.networkInternal.setData({nodes: undefined, edge: undefined});
-              setTimeout(() => {
-                this.networkHandler.activeNetwork.networkInternal.setData(this.nodeData);
-              }, 1000);
+            });
+
+            this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => {
+              if (properties.nodes.length === 0 && properties.edges.length === 1) {
+                // clicked on one edge
+                const edgeId = properties.edges[0];
+                this.networkHandler.activeNetwork.openEdgeSummary(edgeId);
+              } else {
+                this.networkHandler.activeNetwork.activeEdge = null;
+                const selectedNodes = this.nodeData.nodes.get(properties.nodes);
+                if (selectedNodes.length > 0) {
+                  this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0]));
+                } else {
+                  this.showDetailsChange.emit(null);
+                }
+              }
+            });
 
-              this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => {
-                this.showDetailsChange.emit(null);
-              });
+            this.analysis.subscribeList((items, selected) => {
+              // return if analysis panel is closed or no nodes are loaded
+              if (!this.token) {
+                return;
+              }
 
-              this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => {
-                const nodeIds: Array<string> = properties.nodes;
-                if (nodeIds.length > 0) {
-                  const nodeId = nodeIds[0];
-                  const node = this.nodeData.nodes.get(nodeId);
-                  if (node.drugstoneId === undefined || node.nodeType === 'drug' || node.drugstoneType !== 'protein') {
-                    this.analysis.unmappedNodeToast();
-                    return;
-                  }
-                  const wrapper = getWrapperFromNode(node);
-                  if (this.analysis.inSelection(wrapper)) {
-                    this.analysis.removeItems([wrapper]);
-                    this.analysis.getCount();
-                  } else {
-                    this.analysis.addItems([wrapper]);
-                    this.analysis.getCount();
+              if (selected !== null) {
+                const updatedNodes: Node[] = [];
+                for (const item of items) {
+                  const node = this.nodeData.nodes.get(item.id);
+                  if (!node) {
+                    continue;
                   }
+                  const pos = this.networkHandler.activeNetwork.networkInternal.getPositions([item.id]);
+                  node.x = pos[item.id].x;
+                  node.y = pos[item.id].y;
+                  const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
+                  const nodeStyled = NetworkSettings.getNodeStyle(
+                    node,
+                    this.drugstoneConfig.currentConfig(),
+                    isSeed,
+                    selected,
+                    this.networkHandler.activeNetwork.getGradient(item.id),
+                    this.networkHandler.activeNetwork.nodeRenderer
+                  );
+                  updatedNodes.push(nodeStyled);
                 }
-              });
-
-              this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => {
-                if (properties.nodes.length === 0 && properties.edges.length === 1) {
-                  // clicked on one edge
-                  const edgeId = properties.edges[0];
-                  this.networkHandler.activeNetwork.openEdgeSummary(edgeId);
-                } else {
-                  this.networkHandler.activeNetwork.activeEdge = null;
-                  const selectedNodes = this.nodeData.nodes.get(properties.nodes);
-                  if (selectedNodes.length > 0) {
-                    this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0]));
-                  } else {
-                    this.showDetailsChange.emit(null);
+                this.nodeData.nodes.update(updatedNodes);
+
+                const proteinSelection = this.tableSelectedProteins;
+                for (const item of items) {
+                  // TODO: Refactor!
+                  const found = proteinSelection.findIndex((i) => getProteinNodeId(i) === item.id);
+                  const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
+                  if (selected && found === -1 && tableItem) {
+                    proteinSelection.push(tableItem);
                   }
-                }
-              });
-
-              this.analysis.subscribeList((items, selected) => {
-                // return if analysis panel is closed or no nodes are loaded
-                if (!this.token) {
-                  return;
-                }
-
-                if (selected !== null) {
-                  const updatedNodes: Node[] = [];
-                  for (const item of items) {
-                    const node = this.nodeData.nodes.get(item.id);
-                    if (!node) {
-                      continue;
-                    }
-
-                    const pos = this.networkHandler.activeNetwork.networkInternal.getPositions([item.id]);
-                    node.x = pos[item.id].x;
-                    node.y = pos[item.id].y;
-                    const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
-                    const nodeStyled = NetworkSettings.getNodeStyle(
-                      node,
-                      this.drugstoneConfig.currentConfig(),
-                      isSeed,
-                      selected,
-                      this.networkHandler.activeNetwork.getGradient(item.id),
-                      this.networkHandler.activeNetwork.nodeRenderer
-                    );
-                    updatedNodes.push(nodeStyled);
+                  if (!selected && found !== -1 && tableItem) {
+                    proteinSelection.splice(found, 1);
                   }
-                  this.nodeData.nodes.update(updatedNodes);
-
-                  const proteinSelection = this.tableSelectedProteins;
-                  for (const item of items) {
-                    // TODO: Refactor!
-                    const found = proteinSelection.findIndex((i) => getProteinNodeId(i) === item.id);
-                    const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
-                    if (selected && found === -1 && tableItem) {
-                      proteinSelection.push(tableItem);
-                    }
-                    if (!selected && found !== -1 && tableItem) {
-                      proteinSelection.splice(found, 1);
-                    }
+                }
+                this.tableSelectedProteins = [...proteinSelection];
+              } else {
+                // else: selected is null
+                const updatedNodes = [];
+                this.nodeData.nodes.forEach((node) => {
+                  const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
+                  if (!isSeed) {
+                    return;
                   }
-                  this.tableSelectedProteins = [...proteinSelection];
-                } else {
-                  // else: selected is null
-                  const updatedNodes = [];
-                  this.nodeData.nodes.forEach((node) => {
-                    const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
-                    if (!isSeed) {
-                      return;
-                    }
-                    const nodeStyled = NetworkSettings.getNodeStyle(
-                      node,
-                      this.drugstoneConfig.currentConfig(),
-                      isSeed,
-                      selected,
-                      this.networkHandler.activeNetwork.getGradient(node.id),
-                      this.networkHandler.activeNetwork.nodeRenderer
-                    );
-                    updatedNodes.push(nodeStyled);
-                  });
-                  this.nodeData.nodes.update(updatedNodes);
-
-                  const proteinSelection = [];
-                  for (const item of items) {
-                    const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
-                    if (tableItem) {
-                      proteinSelection.push(tableItem);
-                    }
+                  const nodeStyled = NetworkSettings.getNodeStyle(
+                    node,
+                    this.drugstoneConfig.currentConfig(),
+                    isSeed,
+                    selected,
+                    this.networkHandler.activeNetwork.getGradient(node.id),
+                    this.networkHandler.activeNetwork.nodeRenderer
+                  );
+                  updatedNodes.push(nodeStyled);
+                });
+                this.nodeData.nodes.update(updatedNodes);
+
+                const proteinSelection = [];
+                for (const item of items) {
+                  const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
+                  if (tableItem) {
+                    proteinSelection.push(tableItem);
                   }
-                  this.tableSelectedProteins = [...proteinSelection];
                 }
-              });
-              this.emitVisibleItems(true);
-            }).then(() => {
-              if (!['quick', 'super', 'connect', 'connectSelected'].includes(this.task.info.algorithm)) {
-                return;
+                this.tableSelectedProteins = [...proteinSelection];
               }
-              this.netex.getAlgorithmDefaults(this.task.info.algorithm).then(response => {
-                this.algorithmDefault = response
-              });
-            }).catch(console.error);
-          });
-          this.loadingScreen.stateUpdate(false);
+            });
+            this.emitVisibleItems(true);
+          }).then(() => {
+            if (!['quick', 'super', 'connect', 'connectSelected'].includes(this.task.info.algorithm)) {
+              return;
+            }
+            this.netex.getAlgorithmDefaults(this.task.info.algorithm).then(response => {
+              this.algorithmDefault = response;
+            });
+          }).catch(console.error);
         });
-      }
+        this.loadingScreen.stateUpdate(false);
+      });
     }
+  }
 
+  private async refresh() {
+    if (this.token) {
+      if (this.tokenType === 'view') {
+        await this.refreshView();
+      } else {
+        await this.refreshTask();
+      }
+    }
 
   }
 
@@ -405,6 +625,10 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     }
   }
 
+  private async getView(token: string): Promise<any> {
+    return await this.http.get(`${this.netex.getBackend()}view/?token=${token}`).toPromise();
+  }
+
   private async getTask(token: string): Promise<any> {
     return await this.http.get(`${this.netex.getBackend()}task/?token=${token}`).toPromise();
   }
@@ -597,4 +821,8 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     this.drugstoneConfig.showLicense = true;
   }
 
+  public openBugreport() {
+    this.drugstoneConfig.showBugreport = true;
+  }
+
 }
diff --git a/src/app/components/analysis-panel/view-list/view-list.component.html b/src/app/components/analysis-panel/view-list/view-list.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..ad817043487bd6f5352be7cc2805f4b362d985c2
--- /dev/null
+++ b/src/app/components/analysis-panel/view-list/view-list.component.html
@@ -0,0 +1,46 @@
+<div class="content">
+  <div
+    class="list is-hoverable"
+    [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"
+  >
+    <a
+      *ngFor="let task of analysis.viewInfos"
+      class="list-item box small-box"
+      [class.is-active]="task.token === token"
+    >
+      <div
+        *ngIf="task"
+        (click)="open(task.token)"
+        pTooltip="Show selection view"
+        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-top'"
+        tooltipPosition="top"
+      >
+        <div class="columns mb-0">
+          <div class="column is-8">
+            <span class="is-capitalized"
+            ><app-fa-solid-icon
+              icon="crosshairs"
+            ></app-fa-solid-icon>
+              Manual selection</span
+            >
+          </div>
+          <div class="column">
+          </div>
+        </div>
+        <div class="columns mb-0">
+          <div class="column is-8 pt-0 pb-0">
+            <small>Created {{ task.createdAt | date: "short" }}</small>
+          </div>
+          <div class="column pt-0 pb-0">
+            <a
+              (click)="analysis.removeTask(task)"
+              class="has-text-danger is-pulled-right"
+            >
+              <app-fa-solid-icon icon="trash"></app-fa-solid-icon>
+            </a>
+          </div>
+        </div>
+      </div>
+    </a>
+  </div>
+</div>
diff --git a/src/app/components/analysis-panel/view-list/view-list.component.scss b/src/app/components/analysis-panel/view-list/view-list.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/components/analysis-panel/view-list/view-list.component.spec.ts b/src/app/components/analysis-panel/view-list/view-list.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2b65a6b4ad6c9d43bca8c1d6d290c00739016a7f
--- /dev/null
+++ b/src/app/components/analysis-panel/view-list/view-list.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ViewListComponent } from './view-list.component';
+
+describe('ViewListComponent', () => {
+  let component: ViewListComponent;
+  let fixture: ComponentFixture<ViewListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ ViewListComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ViewListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/components/analysis-panel/view-list/view-list.component.ts b/src/app/components/analysis-panel/view-list/view-list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9759c73bd67aa99d3482df8deddecc6893a29843
--- /dev/null
+++ b/src/app/components/analysis-panel/view-list/view-list.component.ts
@@ -0,0 +1,24 @@
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {DrugstoneConfigService} from '../../../services/drugstone-config/drugstone-config.service';
+import {algorithmNames, AnalysisService} from '../../../services/analysis/analysis.service';
+
+@Component({
+  selector: 'app-view-list',
+  templateUrl: './view-list.component.html',
+  styleUrls: ['./view-list.component.scss']
+})
+export class ViewListComponent implements OnInit {
+  @Input() token: string;
+  @Output() tokenChange: EventEmitter<string> = new EventEmitter();
+  constructor(public drugstoneConfig: DrugstoneConfigService, public analysis: AnalysisService) { }
+
+  ngOnInit(): void {
+  }
+
+  open(token) {
+    this.token = token;
+    this.tokenChange.emit(token);
+  }
+
+  protected readonly algorithmNames = algorithmNames;
+}
diff --git a/src/app/components/bug-report/bug-report.component.html b/src/app/components/bug-report/bug-report.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..1605c042f4668d3016aaca7eaeb4fc4aaaea0c83
--- /dev/null
+++ b/src/app/components/bug-report/bug-report.component.html
@@ -0,0 +1,49 @@
+<div
+  class="modal absolute"
+  [class.is-active]="drugstoneConfig.showBugreport"
+>
+  <div class="modal-background"></div>
+  <div class="modal-card">
+    <header class="modal-card-head">
+      <p class="modal-card-title">
+        <app-fa-solid-icon icon="bug"></app-fa-solid-icon>
+        Submit Bug report
+      </p>
+    </header>
+    <section class="modal-card-body">
+      <div class="is-text-align-justify" style="margin-bottom: 16px">
+        <i
+        >If you experienced some unexpected behaviour and error or another clear sign for a bug we are happy to receive
+          your report to improve the Drugst.One application:</i
+        >
+      </div>
+      <div class="bugreport-input">
+        <input #title class="input" type="text" placeholder="Title">
+        <textarea #body class="textarea" placeholder="Report details about the bug" rows="10"></textarea>
+        <input #email class="input" type="text" placeholder="Optional: Email">
+      </div>
+    </section>
+    <footer class="modal-card-foot">
+      <button
+        (click)="send(title.value, body.value, email.value)"
+        class="button is-rounded has-tooltip is-success"
+        pTooltip="Send bug report to contact@drugst.one"
+        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-top'"
+        tooltipPosition="top"
+      >
+        <app-fa-solid-icon icon="bug"></app-fa-solid-icon>
+        Send
+      </button>
+      <button
+        (click)="close()"
+        class="button is-rounded has-tooltip is-danger"
+        pTooltip="Close without sending bug report"
+        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-top'"
+        tooltipPosition="top"
+      >
+        <app-fa-solid-icon icon="times"></app-fa-solid-icon>
+        Close
+      </button>
+    </footer>
+  </div>
+</div>
diff --git a/src/app/components/bug-report/bug-report.component.scss b/src/app/components/bug-report/bug-report.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..4f996bad2c755aaa6110643b07d375f287dda5e7
--- /dev/null
+++ b/src/app/components/bug-report/bug-report.component.scss
@@ -0,0 +1,7 @@
+.bugreport-input{
+  width: 95%
+}
+
+.textarea{
+  margin-top:8px !important;
+}
diff --git a/src/app/components/bug-report/bug-report.component.spec.ts b/src/app/components/bug-report/bug-report.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc8c3b52c5a68258d21c75e8d8a769b43fa312a0
--- /dev/null
+++ b/src/app/components/bug-report/bug-report.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BugReportComponent } from './bug-report.component';
+
+describe('BugReportComponent', () => {
+  let component: BugReportComponent;
+  let fixture: ComponentFixture<BugReportComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ BugReportComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(BugReportComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/components/bug-report/bug-report.component.ts b/src/app/components/bug-report/bug-report.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8e39e2589a0f7acfb6037a797a9af80a4dac6c7c
--- /dev/null
+++ b/src/app/components/bug-report/bug-report.component.ts
@@ -0,0 +1,34 @@
+import {Component, OnInit} from '@angular/core';
+import {DrugstoneConfigService} from '../../services/drugstone-config/drugstone-config.service';
+import {NetexControllerService} from '../../services/netex-controller/netex-controller.service';
+
+@Component({
+  selector: 'app-bug-report',
+  templateUrl: './bug-report.component.html',
+  styleUrls: ['./bug-report.component.scss']
+})
+export class BugReportComponent implements OnInit {
+
+  constructor(public drugstoneConfig: DrugstoneConfigService, public http: NetexControllerService) {
+  }
+
+  public close() {
+    this.drugstoneConfig.showBugreport = false;
+  }
+
+  public send(title, body, email) {
+    this.http.sendBugreport({title, body, email}).then(response => {
+      if (response.status === 200) {
+        this.close();
+      } else {
+        console.log('Error sending bugreport');
+      }
+    }).finally(() => {
+      this.close();
+    }).catch(console.error);
+  }
+
+  ngOnInit(): void {
+  }
+
+}
diff --git a/src/app/components/license-agreement/license-agreement.component.html b/src/app/components/license-agreement/license-agreement.component.html
index b862986584e1cd29bc2678805a83a9592086d7d0..da930ddbad9d818ec6ec8064233248cbb84acd8f 100644
--- a/src/app/components/license-agreement/license-agreement.component.html
+++ b/src/app/components/license-agreement/license-agreement.component.html
@@ -13,7 +13,7 @@
     <section class="modal-card-body">
       <div class="is-text-align-justify" style="margin-bottom: 16px">
         <i
-          >For the use of licenced data of sources like DrugBank and OMIM,
+          >For the use of licensed data of sources like DrugBank and OMIM,
           partially provided by the NeDRex database, the terms of use for data
           of the NeDRex platform have to be accepted:</i
         >
diff --git a/src/app/components/network/network.component.html b/src/app/components/network/network.component.html
index 247e8450f504eaa385e68a8ee1cc24173f13dbf1..e198d47e4758977df119c7234562809c45985684 100644
--- a/src/app/components/network/network.component.html
+++ b/src/app/components/network/network.component.html
@@ -48,6 +48,11 @@
                        [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }"
                        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'"
                        (click)="showEULA()">Show EULA</a>
+                  <a class="dropdown-item" pTooltip="Open window to submit a bug report"
+                       tooltipPosition="left"
+                       [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }"
+                       [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'"
+                       (click)="openBugreport()">Report bug</a>
                     <a class="dropdown-item" pTooltip="Opens Drugst.One website" [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" tooltipPosition="left"
                        [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'" target="_blank"
                        href="https://drugst.one/home">About Drugst.One</a>
diff --git a/src/app/components/network/network.component.ts b/src/app/components/network/network.component.ts
index 6e02d409943fd62588b135c2f1e16f66d16799cd..372f0dcaef973540ff5217d4ff03261186130039 100644
--- a/src/app/components/network/network.component.ts
+++ b/src/app/components/network/network.component.ts
@@ -23,6 +23,7 @@ import {NetworkHandlerService} from 'src/app/services/network-handler/network-ha
 import {LegendService} from 'src/app/services/legend-service/legend-service.service';
 import {LoadingScreenService} from 'src/app/services/loading-screen/loading-screen.service';
 import {version} from '../../../version';
+
 @Component({
   selector: 'app-network',
   templateUrl: './network.component.html',
@@ -30,6 +31,20 @@ import {version} from '../../../version';
 })
 export class NetworkComponent implements OnInit {
 
+  constructor(
+    public legendService: LegendService,
+    public networkHandler: NetworkHandlerService,
+    public analysis: AnalysisService,
+    public drugstoneConfig: DrugstoneConfigService,
+    public netex: NetexControllerService,
+    public omnipath: OmnipathControllerService,
+    public loadingScreen: LoadingScreenService) {
+    try {
+      this.versionString = version;
+    } catch (e) {
+    }
+  }
+
   @Input() public networkType: NetworkType;
   @Input() public nodeData: NodeData;
 
@@ -88,20 +103,7 @@ export class NetworkComponent implements OnInit {
 
   public nodeGroupsWithExpression: Set<string> = new Set();
 
-  constructor(
-    public legendService: LegendService,
-    public networkHandler: NetworkHandlerService,
-    public analysis: AnalysisService,
-    public drugstoneConfig: DrugstoneConfigService,
-
-    public netex: NetexControllerService,
-    public omnipath: OmnipathControllerService,
-    public loadingScreen: LoadingScreenService) {
-    try {
-      this.versionString = version;
-    }catch (e){
-    }
-  }
+  private selectMode = false;
 
   ngOnInit(): void {
     this.networkHandler.networks[this.networkType] = this;
@@ -111,6 +113,142 @@ export class NetworkComponent implements OnInit {
     return this.nodeData.nodes.length > 100 || this.nodeData.edges.length > 100;
   }
 
+  rectangleSelect(select: boolean) {
+
+    this.selectMode = select;
+    const options = this.getOptions();
+    if (!options.interaction) {
+      options.interaction = {};
+    }
+    if (select) {
+      options.interaction.zoomView = false;
+      options.interaction.dragView = false;
+      this.initDragSelect();
+    } else {
+      options.interaction.zoomView = true;
+      options.interaction.dragView = true;
+      this.removeDragSelect();
+    }
+    this.updateOptions(options);
+  }
+
+  public rect = undefined;
+
+
+  selectNodesFromHighlight() {
+    // const fromX;
+    // const toX;
+    // const fromY;
+    // const toY;
+    const nodesIdInDrawing = [];
+    const xRange = this.getStartToEnd(this.rect.startX, this.rect.w);
+    const yRange = this.getStartToEnd(this.rect.startY, this.rect.h);
+
+    // @ts-ignore
+    const allNodes = this.nodeData.nodes.get();
+    const selection = [];
+    for (let i = 0; i < allNodes.length; i++) {
+      const curNode = allNodes[i];
+      const nodePosition = this.net.getPositions([curNode.id]);
+      const nodeXY = this.net.canvasToDOM({x: nodePosition[curNode.id].x, y: nodePosition[curNode.id].y});
+      if (xRange.start <= nodeXY.x && nodeXY.x <= xRange.end && yRange.start <= nodeXY.y && nodeXY.y <= yRange.end) {
+        nodesIdInDrawing.push(curNode.id);
+        selection.push({id: curNode.id, label: curNode.label});
+      }
+    }
+    this.net.selectNodes(nodesIdInDrawing);
+    console.log(selection);
+  }
+
+  getStartToEnd(start, theLen) {
+    return theLen > 0 ? {start: start, end: start + theLen} : {start: start + theLen, end: start};
+  }
+
+  private ctx: CanvasRenderingContext2D;
+  private canvas: HTMLCanvasElement;
+  private net: any;
+
+  initDragSelect() {
+    if (this.net === undefined) {
+      this.net = this.networkInternal;
+      this.canvas = this.net.canvas.frame.canvas;
+      this.canvas.oncontextmenu = () => false;
+      this.ctx = this.canvas.getContext('2d');
+      console.log(this.ctx)
+      this.canvas.addEventListener('mousemove', this.dragMouseMove.bind(this));
+      this.canvas.addEventListener('mousedown', this.dragMouseDown.bind(this));
+      this.canvas.addEventListener('mouseup', this.dragMouseUp.bind(this));
+    }
+  }
+
+
+  removeDragSelect() {
+    this.net = undefined;
+    if (this.canvas) {
+      this.canvas.removeEventListener('mousemove', this.dragMouseMove.bind(this));
+      this.canvas.removeEventListener('mousedown', this.dragMouseDown.bind(this));
+      this.canvas.removeEventListener('mouseup', this.dragMouseUp.bind(this));
+    }
+  }
+
+  private drag = false;
+  public offsetLeft = 0;
+  public offsetTop = 0;
+
+  dragMouseMove(e) {
+    if (this.drag) {
+      this.restoreDrawingSurface();
+      this.rect.w = (e.pageX - this.offsetLeft) - this.rect.startX;
+      this.rect.h = (e.pageY - this.offsetTop) - this.rect.startY;
+
+      this.ctx.setLineDash([5]);
+      this.ctx.strokeStyle = 'rgb(0, 102, 0)';
+      this.ctx.strokeRect(this.rect.startX, this.rect.startY, this.rect.w, this.rect.h);
+      this.ctx.setLineDash([]);
+      this.ctx.fillStyle = 'rgba(0, 255, 0, 0.2)';
+      this.ctx.fillRect(this.rect.startX, this.rect.startY, this.rect.w, this.rect.h);
+
+    }
+  }
+
+  private canvasCursor = 'default';
+
+  dragMouseDown(e) {
+    if (e.button === 0) {
+      this.offsetLeft = e.target.getBoundingClientRect().left;
+      this.offsetTop = e.target.getBoundingClientRect().top;
+      this.saveDrawingSurface();
+      this.rect = {};
+      this.rect.startX = e.pageX - this.offsetLeft;
+      this.rect.startY = e.pageY - this.offsetTop;
+      this.drag = true;
+      this.canvasCursor = 'crosshair';
+    }
+  }
+
+
+  dragMouseUp(e) {
+    if (e.button === 0) {
+      this.restoreDrawingSurface();
+      this.drag = false;
+
+      this.canvasCursor = 'default';
+      this.selectNodesFromHighlight();
+    }
+  }
+
+  private drawingSurfaceImageData: ImageData;
+
+  saveDrawingSurface() {
+    this.drawingSurfaceImageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
+  }
+
+
+  restoreDrawingSurface() {
+    this.ctx.putImageData(this.drawingSurfaceImageData, 0, 0);
+  }
+
+
   getResetInputNetwork(): NetworkData {
     const nodes = [...this.inputNetwork.nodes];
     nodes.forEach(n => {
@@ -442,6 +580,14 @@ export class NetworkComponent implements OnInit {
     });
   }
 
+  public getOptions() {
+    return this.networkInternal.options;
+  }
+
+  public updateOptions(options: any) {
+    this.networkInternal.setOptions(options);
+  }
+
   public openEdgeSummary(edgeId: string) {
     this.selectedWrapper = undefined;
     const edgeMap = this.nodeData.edges.get({returnType: 'Object'});
@@ -671,4 +817,8 @@ export class NetworkComponent implements OnInit {
   public showEULA() {
     this.drugstoneConfig.showLicense = true;
   }
+
+  public openBugreport() {
+    this.drugstoneConfig.showBugreport = true;
+  }
 }
diff --git a/src/app/config.ts b/src/app/config.ts
index e6f0839260ea76887b5ae205a615c976b5c56bb2..73dff93a9241edde216114605868812cd6a395ec 100644
--- a/src/app/config.ts
+++ b/src/app/config.ts
@@ -54,6 +54,7 @@ export interface IConfig {
   showAdvAnalysis: boolean;
   showAdvAnalysisContent: Array<AdvAnalysisContentTypes>;
   showTasks: boolean;
+  showViews: boolean;
   showSelection: boolean;
   showNetworkMenu: false | 'left' | 'right';
   expandNetworkMenu: boolean;
@@ -153,6 +154,7 @@ export const defaultConfig: IConfig = {
   showAdvAnalysisContent: ['drug-search', 'drug-target-search', 'enrichment-gprofiler', 'enrichment-digest', 'search-ndex'],
   showSelection: true,
   showTasks: true,
+  showViews: true,
   showNetworkMenu: 'right',
   showLegend: true,
   expandNetworkMenu: true,
diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html
index 6b2d7ded9f9987dfd96d3c87a759ee0f6745833e..d6f7b11e19424a81bb226b3ed49cd58ab090cd91 100644
--- a/src/app/pages/explorer-page/explorer-page.component.html
+++ b/src/app/pages/explorer-page/explorer-page.component.html
@@ -9,6 +9,7 @@
     <app-parser-warning></app-parser-warning>
     <app-privacy-banner></app-privacy-banner>
     <app-license-agreement></app-license-agreement>
+    <app-bug-report></app-bug-report>
 
     <app-launch-analysis
       [(show)]="showAnalysisDialog"
@@ -318,55 +319,6 @@
           </div>
         </div>
 
-        <div *ngIf="drugstoneConfig.config.showTasks" class="card bar-large">
-          <header
-            class="card-header"
-            [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }"
-          >
-            <p class="card-header-title">
-              <app-fa-solid-icon icon="tasks"></app-fa-solid-icon>
-              Tasks ({{ analysis.tasks != null ? analysis.tasks.length : 0 }})
-            </p>
-            <a
-              (click)="collapseTask = !collapseTask"
-              data-action="collapse"
-              class="card-header-icon is-hidden-fullscreen"
-              aria-label="more options"
-            >
-              <app-fa-solid-icon
-                *ngIf="collapseTask"
-                icon="angle-down"
-              ></app-fa-solid-icon>
-              <app-fa-solid-icon
-                *ngIf="!collapseTask"
-                icon="angle-left"
-              ></app-fa-solid-icon>
-            </a>
-          </header>
-          <div *ngIf="collapseTask">
-            <div
-              class="card-content overflow task-list-container"
-              *ngIf="analysis.tasks && analysis.tasks.length > 0"
-            >
-              <app-task-list [(token)]="selectedAnalysisToken"></app-task-list>
-            </div>
-            <footer class="card-footer">
-              <a
-                *ngIf="analysis.tasks && analysis.tasks.length > 0"
-                (click)="
-                  analysis.removeAllTasks(); selectedAnalysisToken = null
-                "
-                class="card-footer-item has-text-danger"
-                pTooltip="Delete all tasks."
-                [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-top'"
-                tooltipPosition="top"
-              >
-                <app-fa-solid-icon icon="trash"></app-fa-solid-icon>
-                <span> Delete all </span>
-              </a>
-            </footer>
-          </div>
-        </div>
 
         <div
           *ngIf="drugstoneConfig.config.showSelection"
@@ -470,8 +422,37 @@
                 pTooltip="Add all proteins to the selection."
               >
                 <app-fa-solid-icon icon="plus"></app-fa-solid-icon>
-                <span> Add all </span>
+                <span>Add all</span>
+              </a>
+              <a
+                (click)="analysis.addFirstNeighbors()"
+                class="card-footer-item text-primary"
+                tooltipPosition="top"
+                pTooltip="Add first neighbor proteins of selection."
+              >
+                <app-fa-solid-icon icon="plus"></app-fa-solid-icon>
+                <span>Add First neighbors</span>
+              </a>
+            </footer>
+            <footer class="card-footer">
+              <a
+                (click)="analysis.addConnectedComponents()"
+                class="card-footer-item text-primary"
+                tooltipPosition="top"
+                pTooltip="Add full connected components of all nodes in selection."
+              >
+                <app-fa-solid-icon icon="plus"></app-fa-solid-icon>
+                <span>Add Connected Components</span>
               </a>
+<!--              <a-->
+<!--                (click)="analysis.rectangleSelect()"-->
+<!--                class="card-footer-item text-primary"-->
+<!--                tooltipPosition="top"-->
+<!--                pTooltip="Use rectangle select mode to select genes."-->
+<!--              >-->
+<!--                <app-fa-solid-icon icon="plus"></app-fa-solid-icon>-->
+<!--                <span>Select mode</span>-->
+<!--              </a>-->
             </footer>
             <footer class="card-footer">
               <a
@@ -502,6 +483,18 @@
                 <app-fa-solid-icon icon="sync"></app-fa-solid-icon>
                 <span> Invert </span>
               </a>
+              <a
+                *ngIf="analysis.getSelection().length"
+                (click)="analysis.viewFromSelection()"
+                class="card-footer-item text-primary"
+                tooltipPosition="top"
+                pTooltip="Create view from the selection."
+              >
+                <app-fa-solid-icon icon="check"></app-fa-solid-icon>
+                <span> Save selection </span>
+              </a>
+            </footer>
+            <footer class="card-footer">
               <a
                 *ngIf="analysis.getSelection().length"
                 (click)="analysis.resetSelection()"
@@ -512,20 +505,121 @@
                 <app-fa-solid-icon icon="broom"></app-fa-solid-icon>
                 <span> Reset </span>
               </a>
+
             </footer>
 
             <!-- </div> -->
             <!-- </div>  -->
           </div>
         </div>
+        <div *ngIf="drugstoneConfig.config.showViews" class="card bar-large">
+          <header
+            class="card-header"
+            [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }"
+          >
+            <p class="card-header-title">
+              <app-fa-solid-icon icon="tasks"></app-fa-solid-icon>
+              Views ({{ analysis.viewTokens != null ? analysis.viewTokens.length : 0 }})
+            </p>
+            <a
+              (click)="collapseViews = !collapseViews"
+              data-action="collapse"
+              class="card-header-icon is-hidden-fullscreen"
+              aria-label="more options"
+            >
+              <app-fa-solid-icon
+                *ngIf="collapseViews"
+                icon="angle-down"
+              ></app-fa-solid-icon>
+              <app-fa-solid-icon
+                *ngIf="!collapseViews"
+                icon="angle-left"
+              ></app-fa-solid-icon>
+            </a>
+          </header>
+          <div *ngIf="collapseViews">
+            <div
+              class="card-content overflow task-list-container"
+              *ngIf="analysis.viewTokens && analysis.viewTokens.length > 0"
+            >
+              <app-view-list [(token)]="selectedViewToken"></app-view-list>
+            </div>
+            <footer class="card-footer">
+              <a
+                *ngIf="analysis.viewTokens && analysis.viewTokens.length > 0"
+                (click)="
+                  analysis.removeAllSelections(); selectedViewToken = null
+                "
+                class="card-footer-item has-text-danger"
+                pTooltip="Delete all selection views."
+                [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-top'"
+                tooltipPosition="top"
+              >
+                <app-fa-solid-icon icon="trash"></app-fa-solid-icon>
+                <span> Delete all </span>
+              </a>
+            </footer>
+          </div>
+        </div>
+        <div *ngIf="drugstoneConfig.config.showTasks" class="card bar-large">
+          <header
+            class="card-header"
+            [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }"
+          >
+            <p class="card-header-title">
+              <app-fa-solid-icon icon="tasks"></app-fa-solid-icon>
+              Tasks ({{ analysis.tasks != null ? analysis.tasks.length : 0 }})
+            </p>
+            <a
+              (click)="collapseTask = !collapseTask"
+              data-action="collapse"
+              class="card-header-icon is-hidden-fullscreen"
+              aria-label="more options"
+            >
+              <app-fa-solid-icon
+                *ngIf="collapseTask"
+                icon="angle-down"
+              ></app-fa-solid-icon>
+              <app-fa-solid-icon
+                *ngIf="!collapseTask"
+                icon="angle-left"
+              ></app-fa-solid-icon>
+            </a>
+          </header>
+          <div *ngIf="collapseTask">
+            <div
+              class="card-content overflow task-list-container"
+              *ngIf="analysis.tasks && analysis.tasks.length > 0"
+            >
+              <app-task-list [(token)]="selectedAnalysisToken"></app-task-list>
+            </div>
+            <footer class="card-footer">
+              <a
+                *ngIf="analysis.tasks && analysis.tasks.length > 0"
+                (click)="
+                  analysis.removeAllTasks(); selectedAnalysisToken = null
+                "
+                class="card-footer-item has-text-danger"
+                pTooltip="Delete all tasks."
+                [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-top'"
+                tooltipPosition="top"
+              >
+                <app-fa-solid-icon icon="trash"></app-fa-solid-icon>
+                <span> Delete all </span>
+              </a>
+            </footer>
+          </div>
+        </div>
+
       </div>
 
       <!-- Start network block -->
       <div class="drugstone network column" id="main-column">
         <!-- analysis panel with analysis network -->
-        <div *ngIf="selectedAnalysisToken">
+        <div *ngIf="selectedToken">
           <app-analysis-panel
-            [(token)]="selectedAnalysisToken"
+            [(token)]="selectedToken"
+            [(tokenType)]="selectedAnalysisTokenType"
             (showDetailsChange)="
               networkHandler.activeNetwork.selectedWrapper = $event
             "
diff --git a/src/app/pages/explorer-page/explorer-page.component.scss b/src/app/pages/explorer-page/explorer-page.component.scss
index cd4da80f526376dba8f5b43e5b57ee805d948f30..1464f1993b22e29c1414c1d8b6600d21346d6076 100644
--- a/src/app/pages/explorer-page/explorer-page.component.scss
+++ b/src/app/pages/explorer-page/explorer-page.component.scss
@@ -7,6 +7,10 @@
   margin: auto;
 }
 
+.seed-selection {
+  max-height: 600px;
+}
+
 .quick-find {
   .notification {
     padding: 1.25rem 1rem 1.25rem 1rem !important;
diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts
index c6fa80a3d5d2872629dc5595c686a1af93ef2282..1f9c0ff46aa75812a8e5a2a9576a80f85bb5d14e 100644
--- a/src/app/pages/explorer-page/explorer-page.component.ts
+++ b/src/app/pages/explorer-page/explorer-page.component.ts
@@ -107,6 +107,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
 
   public collapseAnalysis = true;
   public collapseTask = true;
+  public collapseViews = true;
   public collapseSelection = true;
   public collapseBaitFilter = true;
   public collapseQuery = true;
@@ -127,8 +128,41 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
 
 
   public showCustomProteinsDialog = false;
+  public selectedAnalysisTokenType: 'task' | 'view' | null = null;
+  // public selectedAnalysisToken: string | null = null;
+  public selectedToken: string | null = null;
 
-  public selectedAnalysisToken: string | null = null;
+  public set selectedViewToken(token: string | null) {
+    if (token == null || token.length === 0) {
+      this.selectedToken = null;
+    } else {
+      this.selectedToken = token;
+      this.selectedAnalysisTokenType = 'view';
+    }
+  }
+
+  public set selectedAnalysisToken(token: string | null) {
+    if (token == null || token.length === 0) {
+      this.selectedToken = null;
+    } else {
+      this.selectedToken = token;
+      this.selectedAnalysisTokenType = 'task';
+    }
+  }
+
+  public get selectedAnalysisToken() {
+    if (this.selectedAnalysisTokenType === 'view') {
+      return null;
+    }
+    return this.selectedToken;
+  }
+
+  public get selectedViewToken() {
+    if (this.selectedAnalysisTokenType === 'task') {
+      return null;
+    }
+    return this.selectedToken;
+  }
 
   @Input() set taskId(token: string | null) {
     if (token == null || token.length === 0) {
@@ -500,6 +534,67 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
     this.drugstoneConfig.smallStyle = this.windowWidth < 1250;
   }
 
+  public initNetworkListeners(resolve){
+    this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => {
+      const nodeIds: Array<string> = properties.nodes;
+      if (nodeIds != null && nodeIds.length > 0) {
+        const nodeId = nodeIds[0];
+        const node = this.nodeData.nodes.get(nodeId);
+        if (node.drugstoneId === undefined || node.drugstoneType !== 'protein') {
+          this.analysis.unmappedNodeToast();
+          // skip if node is not a protein mapped to backend
+          return;
+        }
+        const wrapper = getWrapperFromNode(node);
+        if (this.analysis.inSelection(node)) {
+          this.analysis.removeItems([wrapper]);
+        } else {
+          this.analysis.addItems([wrapper]);
+        }
+      }
+    });
+
+    this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => {
+      if (properties.nodes.length === 0 && properties.edges.length === 1) {
+        // clicked on one edge
+        const edgeId = properties.edges[0];
+        this.networkHandler.activeNetwork.openEdgeSummary(edgeId);
+      } else {
+        // clicked not on one edge
+        const nodeIds: Array<string> = properties.nodes;
+        if (nodeIds != null && nodeIds.length > 0) {
+          const nodeId = nodeIds[0];
+          const node = this.nodeData.nodes.get(nodeId);
+          const wrapper = getWrapperFromNode(node);
+          this.openNodeSummary(wrapper, false);
+        } else {
+          this.closeSummary();
+        }
+      }
+    });
+
+    this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => {
+      this.closeSummary();
+    });
+
+    if (this.networkHandler.activeNetwork.selectedWrapper) {
+      this.zoomToNode(this.networkHandler.activeNetwork.selectedWrapper.id);
+    }
+
+    this.networkHandler.activeNetwork.currentViewNodes = this.nodeData.nodes;
+    this.networkHandler.activeNetwork.currentViewEdges = this.nodeData.edges;
+
+    this.networkHandler.activeNetwork.queryItems = [];
+    this.networkHandler.activeNetwork.updateQueryItems();
+    this.networkHandler.activeNetwork.currentViewProteins = this.networkHandler.activeNetwork.inputNetwork.nodes;
+    // this.fillQueryItems(this.currentViewNodes);
+    if (this.networkHandler.activeNetwork.selectedWrapper) {
+      this.networkHandler.activeNetwork.networkInternal.selectNodes([this.networkHandler.activeNetwork.selectedWrapper.id]);
+    }
+
+    resolve(true);
+  }
+
   public async openNodeSummary(item: Wrapper, zoom: boolean) {
     // close edge summary if open
     this.networkHandler.activeNetwork.activeEdge = null;
diff --git a/src/app/services/analysis/analysis.service.ts b/src/app/services/analysis/analysis.service.ts
index 4afebd0a32ddb067823f73aef5fa3366eca79a1f..fd8b8051cd93094d22e812be0f78c20cd65987ff 100644
--- a/src/app/services/analysis/analysis.service.ts
+++ b/src/app/services/analysis/analysis.service.ts
@@ -61,7 +61,10 @@ export class AnalysisService {
   private selections = new Map<string, Map<string, Wrapper>>();
 
   public tokens: string[] = [];
+  public viewTokens: string[] = [];
+  public viewInfos = [];
   private tokensCookieKey = `drugstone-tokens-${window.location.host}`;
+  private selectionsCookieKey = `drugstone-selections-${window.location.host}`;
   private tokensFinishedCookieKey = `drugstone-finishedTokens-${window.location.host}`;
   public finishedTokens: string[] = [];
   public tasks: Task[] = [];
@@ -81,11 +84,16 @@ export class AnalysisService {
     public networkHandler: NetworkHandlerService
   ) {
     const tokens = localStorage.getItem(this.tokensCookieKey);
+    const selections = localStorage.getItem(this.selectionsCookieKey);
     const finishedTokens = localStorage.getItem(this.tokensFinishedCookieKey);
 
     if (tokens) {
       this.tokens = JSON.parse(tokens);
     }
+    if (selections) {
+      this.viewTokens = JSON.parse(selections);
+      this.setViewInfos();
+    }
     if (finishedTokens) {
       this.finishedTokens = JSON.parse(finishedTokens);
     }
@@ -96,6 +104,21 @@ export class AnalysisService {
     });
   }
 
+  setViewInfos(): void {
+    this.netex.getViewInfos(this.viewTokens).then(res => {
+      // @ts-ignore
+      this.viewInfos = res.reverse();
+    });
+  }
+
+  removeAnalysis(token, type) {
+    if (type !== 'view') {
+      this.removeTask(token);
+    } else {
+      this.removeView(token);
+    }
+  }
+
   removeTask(token) {
     this.tokens = this.tokens.filter((item) => item !== token);
     this.finishedTokens = this.finishedTokens.filter((item) => item !== token);
@@ -103,6 +126,12 @@ export class AnalysisService {
     localStorage.setItem(this.tokensCookieKey, JSON.stringify(this.tokens));
   }
 
+  removeView(token) {
+    this.viewTokens = this.viewTokens.filter((item) => item !== token);
+    localStorage.setItem(this.selectionsCookieKey, JSON.stringify(this.viewTokens));
+    this.setViewInfos();
+  }
+
   removeAllTasks() {
     this.tasks = [];
     this.finishedTokens = [];
@@ -110,12 +139,24 @@ export class AnalysisService {
     localStorage.removeItem(this.tokensCookieKey);
   }
 
+  removeAllSelections() {
+    this.viewTokens = [];
+    this.viewInfos = [];
+    localStorage.removeItem(this.selectionsCookieKey);
+  }
+
   async getTasks() {
     return await this.netex.getTasks(this.finishedTokens.length > 0 && this.tasks.length === 0 ? this.tokens : this.tokens.filter(t => this.finishedTokens.indexOf(t) === -1)).catch((e) => {
       clearInterval(this.intervalId);
     });
   }
 
+  async getViews() {
+    return await this.netex.getTasks(this.finishedTokens.length > 0 && this.tasks.length === 0 ? this.tokens : this.tokens.filter(t => this.finishedTokens.indexOf(t) === -1)).catch((e) => {
+      clearInterval(this.intervalId);
+    });
+  }
+
   public getTissues(): Tissue[] {
     return this.tissues;
   }
@@ -172,6 +213,69 @@ export class AnalysisService {
     }
   }
 
+
+  // Adds first neighbors of selected nodes to selection
+  public addFirstNeighbors() {
+    const wrappers: Wrapper[] = [];
+    const mappedNodes = {};
+    this.networkHandler.activeNetwork.currentViewNodes.forEach((node) => {
+      if (node.drugstoneType === 'protein' && node.drugstoneId) {
+        mappedNodes[node.label] = node;
+      }
+    });
+    const selectedNodes = new Set(this.selectedItems.keys());
+    const firstNeighborNodes: Set<string> = new Set();
+    this.networkHandler.activeNetwork.currentViewEdges.forEach(edge => {
+      if (selectedNodes.has(edge.from)) {
+        firstNeighborNodes.add(edge.to);
+      }
+      if (selectedNodes.has(edge.to)) {
+        firstNeighborNodes.add(edge.from);
+      }
+    });
+
+    firstNeighborNodes.forEach(n => {
+      wrappers.push(getWrapperFromNode(mappedNodes[n]));
+    });
+    this.addItems(wrappers);
+  }
+
+
+  public rectangleSelect(){
+    this.networkHandler.activeNetwork.rectangleSelect(true);
+  }
+
+  // Identifies connected components of all selected nodes and adds all nodes of the components to the selection
+  public addConnectedComponents() {
+    const wrappers: Wrapper[] = [];
+    const mappedNodes = {};
+    this.networkHandler.activeNetwork.currentViewNodes.forEach((node) => {
+      if (node.drugstoneType === 'protein' && node.drugstoneId) {
+        mappedNodes[node.label] = node;
+      }
+    });
+    const selectedNodes = new Set(this.selectedItems.keys());
+    let previousSize = 0;
+    while (previousSize !== selectedNodes.size) {
+      previousSize = selectedNodes.size;
+      this.networkHandler.activeNetwork.currentViewEdges.forEach(edge => {
+        if (selectedNodes.has(edge.from)) {
+          selectedNodes.add(edge.to);
+        }
+        if (selectedNodes.has(edge.to)) {
+          selectedNodes.add(edge.from);
+        }
+      });
+    }
+
+    selectedNodes.forEach(n => {
+      if (!this.selectedItems.has(n)){
+        wrappers.push(getWrapperFromNode(mappedNodes[n]));
+      }
+    });
+    this.addItems(wrappers);
+  }
+
   public addAllToSelection() {
     const wrappers: Wrapper[] = [];
     const unmappedNodes = [];
@@ -244,6 +348,33 @@ export class AnalysisService {
     this.selectedItems.clear();
   }
 
+  async viewFromSelection() {
+
+    const seeds = this.getSelection().map((item) => item.id);
+    const seedsFiltered = seeds.filter(el => el != null);
+    const initialNetwork = this.networkHandler.activeNetwork.getResetInputNetwork();
+    const filteredNodes = initialNetwork.nodes.filter(node => seedsFiltered.includes(node.id));
+    const filteredEdges = initialNetwork.edges.filter(edge => seedsFiltered.includes(edge.from) && seedsFiltered.includes(edge.to));
+    this.resetSelection();
+    const payload: any = {
+      config: this.drugstoneConfig.currentConfig(),
+      network: {nodes: filteredNodes, edges: filteredEdges}
+    };
+    const resp = await this.http.post<any>(`${this.netex.getBackend()}save_selection`, payload).toPromise();
+    // @ts-ignore
+    this.viewTokens.push(resp.token);
+    this.setViewInfos();
+    localStorage.setItem(this.selectionsCookieKey, JSON.stringify(this.viewTokens));
+
+    this.toast.setNewToast({
+      message: 'Analysis task started. This may take a while. ' +
+        `Once the computation finished you can view the results in the task list to the ${this.drugstoneConfig.config.showSidebar}.`,
+      type: 'success'
+    });
+    // @ts-ignore
+    return resp.token;
+  }
+
   idInSelection(nodeId: string): boolean {
     return this.selectedItems.has(nodeId);
   }
diff --git a/src/app/services/drugstone-config/drugstone-config.service.ts b/src/app/services/drugstone-config/drugstone-config.service.ts
index c83d3f682ae9c70264593831fae2d3c783cddc64..6da6535239f10f038518656d2c313b8754e4c524 100644
--- a/src/app/services/drugstone-config/drugstone-config.service.ts
+++ b/src/app/services/drugstone-config/drugstone-config.service.ts
@@ -18,6 +18,7 @@ export class DrugstoneConfigService {
   public smallStyle = false;
 
   public showLicense = false;
+  public showBugreport = false;
 
   constructor() {
   }
diff --git a/src/app/services/netex-controller/netex-controller.service.ts b/src/app/services/netex-controller/netex-controller.service.ts
index 230f850cf4b499beaf95c792091d69a612fe6617..4d8364d7d0a1138340f5fb0ed67bb5cdf8e5d206 100644
--- a/src/app/services/netex-controller/netex-controller.service.ts
+++ b/src/app/services/netex-controller/netex-controller.service.ts
@@ -100,6 +100,7 @@ export class NetexControllerService {
     return this.http.post<any>(`${this.getBackend()}adjacent_drugs/`, params).toPromise();
   }
 
+
   public graphExport(graph_data: { edges: EdgeType[], nodes: Node[] }) {
     /**
      * Sends complete graph data to backend where it is written to graphml or json File.
@@ -117,6 +118,13 @@ export class NetexControllerService {
     return this.http.post(`${this.getBackend()}fetch_edges/`, payload).toPromise();
   }
 
+  public sendBugreport(payload): Promise<any> {
+    /**
+     * Sends a bugreport to the backend
+     */
+    return this.http.post(`${this.getBackend()}send_bugreport/`, payload).toPromise();
+  }
+
 
   public async getLicense(): Promise<any> {
     /**
@@ -124,4 +132,9 @@ export class NetexControllerService {
      */
     return this.http.get(`${this.getBackend()}get_license`).toPromise();
   }
+
+  public async getViewInfos(tokens) {
+    return await this.http.post(`${this.getBackend()}view_infos`, {tokens}).toPromise();
+  }
+
 }