diff --git a/src/App.js b/src/App.js
index dad8a107abcd43ff12c53dfb175906423ba6e7a2..e2aa82627f3d8544c7612e1ea26a204a06c701ff 100644
--- a/src/App.js
+++ b/src/App.js
@@ -4,7 +4,8 @@ import { BrowserRouter, Switch, Route } from 'react-router-dom';
 
 import EntryPage from './components/entry-page/entry-page';
 import ErrorDialog from './components/dialog/error-dialog.js';
-import ExperimentOverview from './components/experiment-overview/experiment-overview';
+import ExperimentsOverview from './components/experiments-overview/experiments-overview';
+import ExperimentWorkbench from './components/experiment-workbench/experiment-workbench';
 import SimulationView from './components/simulation-view/simulation-view';
 import NotificationDialog from './components/dialog/notification-dialog.js';
 //import MqttClientService from './services/nrp-core/mqtt-client-service';
@@ -22,7 +23,8 @@ class App extends React.Component {
         <NotificationDialog/>
         <BrowserRouter>
           <Switch>
-            <Route path='/experiments-overview' component={ExperimentOverview} />
+            <Route path='/experiments-overview' component={ExperimentsOverview} />
+            <Route path='/experiment/:experimentID' component={ExperimentWorkbench} />
             <Route path='/simulation-view/:serverIP/:simulationID' component={SimulationView} />
             <Route path='/' component={EntryPage} />
           </Switch>
diff --git a/src/components/experiment-list/experiment-list-element.js b/src/components/experiment-list/experiment-list-element.js
index 01264d6cddb9f8c76ead5af1f93a6d7529375389..546f6ffe5bec7d450acf28e0fdb611f666b494ab 100644
--- a/src/components/experiment-list/experiment-list-element.js
+++ b/src/components/experiment-list/experiment-list-element.js
@@ -11,7 +11,7 @@ import PublicExperimentsService from '../../services/experiments/files/public-ex
 import ExperimentStorageService from '../../services/experiments/files/experiment-storage-service.js';
 
 import SimulationDetails from './simulation-details';
-import ExperimentOverview from '../experiment-overview/experiment-overview.js';
+import ExperimentOverview from '../experiments-overview/experiments-overview.js';
 
 import './experiment-list-element.css';
 import '../main.css';
diff --git a/src/components/experiment-workbench/experiment-tools-service.js b/src/components/experiment-workbench/experiment-tools-service.js
new file mode 100644
index 0000000000000000000000000000000000000000..1d16e533f7f3722ea40880c881adce782605bee0
--- /dev/null
+++ b/src/components/experiment-workbench/experiment-tools-service.js
@@ -0,0 +1,109 @@
+import NrpCoreDashboard from '../nrp-core-dashboard/nrp-core-dashboard';
+
+
+let _instance = null;
+const SINGLETON_ENFORCER = Symbol();
+
+/**
+ * Service handling server resources for simulating experiments.
+ */
+class SimulationToolsService {
+  constructor(enforcer) {
+    if (enforcer !== SINGLETON_ENFORCER) {
+      throw new Error('Use ' + this.constructor.name + '.instance');
+    }
+
+    this.tools = new Map();
+    for (const toolEntry in SimulationToolsService.TOOLS) {
+      this.registerToolConfig(SimulationToolsService.TOOLS[toolEntry]);
+    }
+    this.registerToolConfig(NrpCoreDashboard.CONSTANTS.TOOL_CONFIG);
+  }
+
+  static get instance() {
+    if (_instance == null) {
+      _instance = new SimulationToolsService(SINGLETON_ENFORCER);
+    }
+
+    return _instance;
+  }
+
+  registerToolConfig(toolConfig) {
+    console.info('registerToolConfig');
+    console.info(toolConfig);
+    let id = toolConfig.flexlayoutNode.component;
+    if (this.tools.has(id)) {
+      console.warn('SimulationToolsService.registerToolConfig() - tool with ID ' + id + ' already exists');
+      return;
+    }
+
+    this.tools.set(id, toolConfig);
+  }
+
+  flexlayoutNodeFactory(node) {
+    var component = node.getComponent();
+
+    let toolConfig = this.tools.get(component);
+    if (toolConfig && toolConfig.flexlayoutFactoryCb) {
+      return toolConfig.flexlayoutFactoryCb();
+    }
+
+    if (component === 'button') {
+      return <button>{node.getName()}</button>;
+    }
+    else if (component === 'nest_wiki') {
+      return <iframe src='https://en.wikipedia.org/wiki/NEST_(software)' title='nest_wiki'
+        className='flexlayout-iframe'></iframe>;
+    }
+  }
+
+  startToolDrag(flexlayoutNode, layoutReference) {
+    layoutReference.current.addTabWithDragAndDrop(flexlayoutNode.name, flexlayoutNode);
+  }
+}
+
+SimulationToolsService.TOOLS = Object.freeze({
+  NEST_DESKTOP: {
+    singleton: true,
+    flexlayoutNode: {
+      'type': 'tab',
+      'name': 'NEST Desktop',
+      'component': 'nest-desktop'
+    },
+    flexlayoutFactoryCb: () =>  {
+      return <iframe src='http://localhost:8000' title='NEST Desktop' />;
+    },
+    getIcon: () => {
+      return <div>
+        <img src={'https://www.nest-simulator.org/wp-content/uploads/2015/03/nest_logo.png'}
+          alt="NEST Desktop"
+          style={{width: 40+ 'px', height: 20 + 'px'}} />
+        <span>Desktop</span>
+      </div>;
+    }
+  },
+  TEST_NRP_CORE_DOCU: {
+    singleton: true,
+    flexlayoutNode: {
+      'type': 'tab',
+      'name': 'NRP-Core Docs',
+      'component': 'nrp-core-docu'
+    },
+    flexlayoutFactoryCb: () =>  {
+      return <iframe src='https://hbpneurorobotics.bitbucket.io/index.html'
+        title='NRP-Core Documentation' />;
+    },
+    getIcon: () => {
+      return <span>NRP-Core Docs</span>;
+    }
+  }
+});
+
+SimulationToolsService.CONSTANTS = Object.freeze({
+  CATEGORY: {
+    EXTERNAL_IFRAME: 'EXTERNAL_IFRAME',
+    REACT_COMPONENT: 'REACT_COMPONENT'
+  }
+});
+
+export default SimulationToolsService;
diff --git a/src/components/experiment-workbench/experiment-workbench.css b/src/components/experiment-workbench/experiment-workbench.css
new file mode 100644
index 0000000000000000000000000000000000000000..ca655e87f8942a6b32574ed5312e886ec5e0bf54
--- /dev/null
+++ b/src/components/experiment-workbench/experiment-workbench.css
@@ -0,0 +1,80 @@
+.simulation-view-wrapper {
+  display: grid;
+  grid-template-rows: auto auto;
+  grid-template-columns: 68px auto;
+  grid-template-areas: 
+      "simulation-view-header simulation-view-header"
+      "simulation-view-sidebar simulation-view-mainview";
+}
+
+.simulation-view-header {
+  grid-area: simulation-view-header;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  background-color: yellow;
+  padding: 3px;
+}
+
+.simulation-view-sidebar {
+  padding: 2px;
+  grid-area: simulation-view-sidebar;
+  background-color: green;
+}
+
+.simulation-view-mainview {
+  grid-area: simulation-view-mainview;
+  background-color: red;
+}
+
+.flexlayout__layout {
+  position: relative;
+  height: calc(100vh - 63px);
+}
+
+.flexlayout__tab {
+  overflow: hidden;
+}
+
+.simulation-view-controls {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+}
+
+.simulation-view-control-buttons {
+  padding: 0px 10px 0px 10px;
+}
+
+.simulation-view-time-info {
+  display: grid;
+  gap: 3px;
+  grid-template-rows: repeat(3, 1fr);
+  grid-template-columns: repeat(2, 1fr);
+
+  padding: 0px 10px 0px 10px;
+
+  font-size: 0.7em;
+}
+
+.simulation-view-experiment-title {
+  padding: 0px 10px 0px 10px;
+  font-weight: bold;
+}
+
+.simulation-tool-button {
+  width: 60px;
+  height: 60px;
+  margin: 2px;
+  padding: 2px;
+  font-size: 0.7em;
+  color: black;
+  font-weight: bold;
+  background-color: lightgray;
+}
+
+iframe {
+  width: 100%;
+  height: 100%;
+}
\ No newline at end of file
diff --git a/src/components/experiment-workbench/experiment-workbench.js b/src/components/experiment-workbench/experiment-workbench.js
new file mode 100644
index 0000000000000000000000000000000000000000..771a93765d71e48d2f4a7183e9ad187e31b0199a
--- /dev/null
+++ b/src/components/experiment-workbench/experiment-workbench.js
@@ -0,0 +1,205 @@
+import React from 'react';
+import FlexLayout from 'flexlayout-react';
+import { OverlayTrigger, Tooltip, Button } from 'react-bootstrap';
+import { RiPlayFill, RiPauseFill, RiLayout6Line } from 'react-icons/ri';
+import { GiExitDoor } from 'react-icons/gi';
+import { TiMediaRecord } from 'react-icons/ti';
+import { VscDebugRestart } from 'react-icons/vsc';
+
+import ExperimentToolsService from './experiment-tools-service';
+import ServerResourcesService from '../../services/experiments/execution/server-resources-service.js';
+import ExperimentStorageService from '../../services/experiments/files/experiment-storage-service';
+import RunningSimulationService from '../../services/experiments/execution/running-simulation-service';
+import { EXPERIMENT_STATE } from '../../services/experiments/experiment-constants';
+import timeDDHHMMSS from '../../utility/time-filter';
+
+import LeaveWorkbenchDialog from './leave-workbench-dialog';
+
+import '../../../node_modules/flexlayout-react/style/light.css';
+import './experiment-workbench.css';
+
+const jsonBaseLayout = {
+  global: {},
+  borders: [],
+  layout:{
+    'type': 'row',
+    'weight': 100,
+    'children': [
+      {
+        'type': 'tabset',
+        'weight': 50,
+        'selected': 0,
+        'children': [
+          {
+            'type': 'tab',
+            'name': 'NEST wiki page',
+            'component':'nest_wiki'
+          }
+        ]
+      }
+    ]
+  }
+};
+
+export default class ExperimentWorkbench extends React.Component {
+  constructor(props) {
+    super(props);
+
+    const {experimentID} = props.match.params;
+    //console.info('SimulationView ' + serverIP + ' ' + simulationID);
+    this.experimentID = experimentID;
+    this.serverURL = 'http://' + this.serverIP + ':8080'; // this should probably be part of some config
+
+    this.state = {
+      modelFlexLayout: FlexLayout.Model.fromJson(jsonBaseLayout),
+      showLeaveDialog: false
+    };
+
+    this.refLayout = React.createRef();
+  }
+
+  async componentDidMount() {
+    await this.updateSimulationInfo();
+    let experiments = await ExperimentStorageService.instance.getExperiments();
+    this.experimentInfo = experiments.find(experiment => experiment.id === this.experimentID);
+    console.info('ExperimentWorkbench - experimentInfo');
+    console.info(this.experimentInfo);
+
+    let experimentName = this.experimentInfo.configuration.name;
+    this.setState({experimentName: experimentName});
+
+    let server = this.experimentInfo.joinableServers.find(
+      server => server.runningSimulation.creationUniqueID === this.state.simulationInfo.creationUniqueID);
+    this.serverConfig = await ServerResourcesService.instance.getServerConfig(server.server);
+    console.info('this.serverConfig');
+    console.info(this.serverConfig);
+    RunningSimulationService.instance.addRosStatusInfoCallback(
+      this.serverConfig.rosbridge.websocket,
+      (data) => {
+        this.onStatusInfoROS(data);
+      }
+    );
+  }
+
+  async updateSimulationInfo() {
+    let simInfo = await RunningSimulationService.instance.getInfo(this.serverURL, this.simulationID);
+    this.setState({simulationInfo: simInfo});
+    console.info('SimulationView.updateSimulationInfo - simulationInfo');
+    console.info(this.state.simulationInfo);
+  }
+
+  onStatusInfoROS(message) {
+    this.setState({
+      timingRealtime: timeDDHHMMSS(message.realTime),
+      timingSimulationTime: timeDDHHMMSS(message.simulationTime),
+      timingTimeout: timeDDHHMMSS(message.timeout)
+    });
+  }
+
+  async onButtonStartPause() {
+    let newState = this.state.simulationInfo.state === EXPERIMENT_STATE.PAUSED
+      ? EXPERIMENT_STATE.STARTED
+      : EXPERIMENT_STATE.PAUSED;
+    await RunningSimulationService.instance.updateState(this.serverURL, this.simulationID, newState);
+
+    this.updateSimulationInfo();
+  }
+
+  onButtonLayout() {
+    console.info(this.state.modelFlexLayout.toJson());
+  }
+
+  showLeaveDialog(show) {
+    this.setState({showLeaveDialog: show});
+  }
+
+  leaveWorkbench() {
+    this.props.history.push({
+      pathname: '/experiments-overview'
+    });
+  }
+
+  render() {
+    return (
+      <div>
+        <LeaveWorkbenchDialog visible={this.state.showLeaveDialog}
+          setVisibility={(visible) => this.showLeaveDialog(visible)}
+          stopSimulation={async () => {
+            await RunningSimulationService.instance.updateState(this.serverURL, this.simulationID,
+              EXPERIMENT_STATE.STOPPED);
+            this.leaveWorkbench();
+          }}
+          leaveWorkbench={() => {
+            this.leaveWorkbench();
+          }} />
+        <div className='simulation-view-wrapper'>
+          <div className='simulation-view-header'>
+            <div className='simulation-view-controls'>
+              <div className='simulation-view-control-buttons'>
+                <button className='nrp-btn btn-default' onClick={() => this.showLeaveDialog(true)}>
+                  <GiExitDoor className='icon' />
+                </button>
+                <button disabled={true} className='nrp-btn btn-default'><VscDebugRestart className='icon' /></button>
+                <button className='nrp-btn btn-default' onClick={() => {
+                  this.onButtonStartPause();
+                }}>
+                  {this.state.simulationInfo && this.state.simulationInfo.state === EXPERIMENT_STATE.PAUSED
+                    ? <RiPlayFill className='icon' />
+                    : <RiPauseFill className='icon' />}
+                </button>
+                <button disabled={true} className='nrp-btn btn-default'><TiMediaRecord className='icon' /></button>
+              </div>
+
+              <div className='simulation-view-time-info'>
+                <div>Simulation time:</div>
+                <div>{this.state.timingSimulationTime}</div>
+                <div>Real time:</div>
+                <div>{this.state.timingRealtime}</div>
+                <div>Real timeout:</div>
+                <div>{this.state.timingTimeout}</div>
+              </div>
+            </div>
+
+            <div className='simulation-view-experiment-title'>{this.state.experimentName}</div>
+            <button className='nrp-btn btn-default' onClick={() => {
+              this.onButtonLayout();
+            }}><RiLayout6Line className='icon' /></button>
+          </div>
+          <div className='simulation-view-sidebar'>
+            {Array.from(ExperimentToolsService.instance.tools.values()).map(tool => {
+              return (
+                <OverlayTrigger
+                  key={`overlaytrigger-${tool.flexlayoutNode.component}`}
+                  placement={'right'}
+                  overlay={
+                    <Tooltip id={`tooltip-${tool.flexlayoutNode.component}`}>
+                      {tool.flexlayoutNode.name}
+                    </Tooltip>
+                  }
+                >
+                  <Button key={tool.flexlayoutNode.component}
+                    className="simulation-tool-button"
+                    onMouseDown={() => {
+                      ExperimentToolsService.instance.startToolDrag(
+                        tool.flexlayoutNode,
+                        this.refLayout);
+                    }}>{tool.getIcon && tool.getIcon()}</Button>
+                </OverlayTrigger>
+              );
+            })}
+          </div>
+          <div className='simulation-view-mainview'>
+            <FlexLayout.Layout ref={this.refLayout} model={this.state.modelFlexLayout}
+              factory={(node) => {
+                return ExperimentToolsService.instance.flexlayoutNodeFactory(node);
+              }} />
+          </div>
+        </div>
+      </div>
+    );
+  }
+}
+
+ExperimentWorkbench.CONSTANTS = Object.freeze({
+  INTERVAL_INTERNAL_UPDATE_MS: 1000
+});
diff --git a/src/components/experiment-workbench/leave-workbench-dialog.css b/src/components/experiment-workbench/leave-workbench-dialog.css
new file mode 100644
index 0000000000000000000000000000000000000000..17673cef3053f4308b70ab85226ef78e1932c781
--- /dev/null
+++ b/src/components/experiment-workbench/leave-workbench-dialog.css
@@ -0,0 +1,4 @@
+.leave-simulation-dialog-header {
+  color: black;
+  background-color: white;
+}
\ No newline at end of file
diff --git a/src/components/experiment-workbench/leave-workbench-dialog.js b/src/components/experiment-workbench/leave-workbench-dialog.js
new file mode 100644
index 0000000000000000000000000000000000000000..dafd51bf9716e46f04a783ac586a49aee407ee57
--- /dev/null
+++ b/src/components/experiment-workbench/leave-workbench-dialog.js
@@ -0,0 +1,32 @@
+import React from 'react';
+import {Button } from 'react-bootstrap';
+import Modal from 'react-bootstrap/Modal';
+
+import './leave-workbench-dialog.css';
+
+export default class LeaveWorkbenchDialog extends React.Component{
+  render(){
+    return (
+      <div>
+        <div>
+          <Modal show={this.props.visible} onHide={() => this.props.setVisibility(false)}>
+            <Modal.Header closeButton className="leave-workbench-dialog-header">
+              <Modal.Title>Exit menu</Modal.Title>
+            </Modal.Header>
+            <Modal.Body>Would you like to leave or stop the simulation?</Modal.Body>
+            <Modal.Footer>
+              <div>
+                <Button variant="light" onClick={() => this.props.leaveWorkbench()}>
+                  Leave
+                </Button>
+                <Button variant="danger" onClick={() => this.props.stopSimulation()}>
+                  Stop
+                </Button>
+              </div>
+            </Modal.Footer>
+          </Modal>
+        </div>
+      </div>
+    );
+  }
+}
\ No newline at end of file
diff --git a/src/components/experiment-overview/experiment-overview.css b/src/components/experiments-overview/experiments-overview.css
similarity index 100%
rename from src/components/experiment-overview/experiment-overview.css
rename to src/components/experiments-overview/experiments-overview.css
diff --git a/src/components/experiment-overview/experiment-overview.js b/src/components/experiments-overview/experiments-overview.js
similarity index 97%
rename from src/components/experiment-overview/experiment-overview.js
rename to src/components/experiments-overview/experiments-overview.js
index b43fb7a9d504792832640f57a7b35acfa5de78c6..8a95830d9cd565d86ab138fadd5203c1d69d6c43 100644
--- a/src/components/experiment-overview/experiment-overview.js
+++ b/src/components/experiments-overview/experiments-overview.js
@@ -13,9 +13,9 @@ import ExperimentList from '../experiment-list/experiment-list.js';
 import NrpHeader from '../nrp-header/nrp-header.js';
 import ExperimentFilesViewer from '../experiment-files-viewer/experiment-files-viewer.js';
 
-import './experiment-overview.css';
+import './experiments-overview.css';
 
-export default class ExperimentOverview extends React.Component {
+export default class ExperimentsOverview extends React.Component {
   static CONSTANTS = {
     TAB_INDEX: {
       MY_EXPERIMENTS: 0,
@@ -35,7 +35,7 @@ export default class ExperimentOverview extends React.Component {
       joinableExperiments: [],
       availableServers: [],
       startingExperiment: undefined,
-      selectedTabIndex: ExperimentOverview.CONSTANTS.TAB_INDEX.MY_EXPERIMENTS
+      selectedTabIndex: ExperimentsOverview.CONSTANTS.TAB_INDEX.MY_EXPERIMENTS
     };
   }
 
diff --git a/src/components/simulation-view/simulation-tools-service.js b/src/components/simulation-view/simulation-tools-service.js
index 1d16e533f7f3722ea40880c881adce782605bee0..1f0f9b5d99411b25520ab1af94e7d0296513f367 100644
--- a/src/components/simulation-view/simulation-tools-service.js
+++ b/src/components/simulation-view/simulation-tools-service.js
@@ -7,22 +7,22 @@ const SINGLETON_ENFORCER = Symbol();
 /**
  * Service handling server resources for simulating experiments.
  */
-class SimulationToolsService {
+class ExperimentToolsService {
   constructor(enforcer) {
     if (enforcer !== SINGLETON_ENFORCER) {
       throw new Error('Use ' + this.constructor.name + '.instance');
     }
 
     this.tools = new Map();
-    for (const toolEntry in SimulationToolsService.TOOLS) {
-      this.registerToolConfig(SimulationToolsService.TOOLS[toolEntry]);
+    for (const toolEntry in ExperimentToolsService.TOOLS) {
+      this.registerToolConfig(ExperimentToolsService.TOOLS[toolEntry]);
     }
     this.registerToolConfig(NrpCoreDashboard.CONSTANTS.TOOL_CONFIG);
   }
 
   static get instance() {
     if (_instance == null) {
-      _instance = new SimulationToolsService(SINGLETON_ENFORCER);
+      _instance = new ExperimentToolsService(SINGLETON_ENFORCER);
     }
 
     return _instance;
@@ -62,7 +62,7 @@ class SimulationToolsService {
   }
 }
 
-SimulationToolsService.TOOLS = Object.freeze({
+ExperimentToolsService.TOOLS = Object.freeze({
   NEST_DESKTOP: {
     singleton: true,
     flexlayoutNode: {
@@ -99,11 +99,11 @@ SimulationToolsService.TOOLS = Object.freeze({
   }
 });
 
-SimulationToolsService.CONSTANTS = Object.freeze({
+ExperimentToolsService.CONSTANTS = Object.freeze({
   CATEGORY: {
     EXTERNAL_IFRAME: 'EXTERNAL_IFRAME',
     REACT_COMPONENT: 'REACT_COMPONENT'
   }
 });
 
-export default SimulationToolsService;
+export default ExperimentToolsService;
diff --git a/src/components/simulation-view/simulation-view.js b/src/components/simulation-view/simulation-view.js
index f2c5459f13bdbbc4a150ca3888942c5e5f78ced4..a09b475c77ea3497029e85d7928cdd5259104e1b 100644
--- a/src/components/simulation-view/simulation-view.js
+++ b/src/components/simulation-view/simulation-view.js
@@ -6,7 +6,7 @@ import { GiExitDoor } from 'react-icons/gi';
 import { TiMediaRecord } from 'react-icons/ti';
 import { VscDebugRestart } from 'react-icons/vsc';
 
-import SimulationToolsService from './simulation-tools-service';
+import ExperimentToolsService from './simulation-tools-service';
 import ServerResourcesService from '../../services/experiments/execution/server-resources-service.js';
 import ExperimentStorageService from '../../services/experiments/files/experiment-storage-service';
 import RunningSimulationService from '../../services/experiments/execution/running-simulation-service';
@@ -167,7 +167,7 @@ export default class SimulationView extends React.Component {
             }}><RiLayout6Line className='icon' /></button>
           </div>
           <div className='simulation-view-sidebar'>
-            {Array.from(SimulationToolsService.instance.tools.values()).map(tool => {
+            {Array.from(ExperimentToolsService.instance.tools.values()).map(tool => {
               return (
                 <OverlayTrigger
                   key={`overlaytrigger-${tool.flexlayoutNode.component}`}
@@ -181,7 +181,7 @@ export default class SimulationView extends React.Component {
                   <Button key={tool.flexlayoutNode.component}
                     className="simulation-tool-button"
                     onMouseDown={() => {
-                      SimulationToolsService.instance.startToolDrag(
+                      ExperimentToolsService.instance.startToolDrag(
                         tool.flexlayoutNode,
                         this.refLayout);
                     }}>{tool.getIcon && tool.getIcon()}</Button>
@@ -192,7 +192,7 @@ export default class SimulationView extends React.Component {
           <div className='simulation-view-mainview'>
             <FlexLayout.Layout ref={this.refLayout} model={this.state.modelFlexLayout}
               factory={(node) => {
-                return SimulationToolsService.instance.flexlayoutNodeFactory(node);
+                return ExperimentToolsService.instance.flexlayoutNodeFactory(node);
               }} />
           </div>
         </div>