diff --git a/labs/bbb-webrtc-sfu/.gitignore b/labs/bbb-webrtc-sfu/.gitignore
deleted file mode 100644
index 8d87b1d267eabcb51a652ac62f9e0862dbde5541..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules/*
diff --git a/labs/bbb-webrtc-sfu/Dockerfile b/labs/bbb-webrtc-sfu/Dockerfile
deleted file mode 100644
index ebba290ee6887c5df9ec7f5424a8fe6deb40fb77..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/Dockerfile
+++ /dev/null
@@ -1,17 +0,0 @@
-FROM node:8
-
-ADD . /source
-RUN cp /source/config/default.example.yml /source/config/production.yml
-
-ENV NODE_ENV production
-
-RUN cd /source \
- && mv docker-entrypoint.sh /usr/local/bin/ \
- && npm install \
- && npm cache clear --force
-
-WORKDIR /source
-
-EXPOSE 3008
-
-CMD [ "docker-entrypoint.sh" ]
diff --git a/labs/bbb-webrtc-sfu/README.md b/labs/bbb-webrtc-sfu/README.md
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/labs/bbb-webrtc-sfu/config/custom-environment-variables.yml b/labs/bbb-webrtc-sfu/config/custom-environment-variables.yml
deleted file mode 100644
index 074de09626d59cbb357795d1c39eb81d35f51044..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/config/custom-environment-variables.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-kurentoUrl: KURENTO_URL
-kurentoIp: KURENTO_IP
-redisHost: REDIS_HOST
-freeswitch:
-    ip: FREESWITCH_IP
-log:
-    level: LOG_LEVEL
diff --git a/labs/bbb-webrtc-sfu/config/default.example.yml b/labs/bbb-webrtc-sfu/config/default.example.yml
deleted file mode 100644
index 9e6f515fc9682a9a5980c5bdefdca528e2bdfce1..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/config/default.example.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-# Websocket URL under which kurento is listening
-kurentoUrl: "ws://HOST/kurento"
-# The external IP of the host where Kurento is located
-kurentoIp: ""
-# The external IP of the host where Red5/BBB is located. Used for the RTMP url
-localIpAddress: ""
-acceptSelfSignedCertificate: false
-redisHost : "127.0.0.1"
-redisPort : "6379"
-# Port under which bbb-webrtc-sfu serves client
-clientPort : "3008"
-# The following UDP port boundary is related to the ports ffmpeg can use to generate the RTMP stream
-minVideoPort: 30000
-maxVideoPort: 33000
-# Timeout (ms) that triggers a failure when no media has reached the server
-mediaFlowTimeoutDuration: 5000
-from-screenshare: "from-screenshare-sfu"
-to-screenshare: "to-screenshare-sfu"
-from-video: "from-video-sfu"
-to-video: "to-video-sfu"
-from-audio: "from-audio-sfu"
-to-audio: "to-audio-sfu"
-to-akka: "to-akka-apps-redis-channel"
-from-akka: "from-akka-apps-redis-channel"
-common-message-version: "2.x"
-# FORCES H.264 for webcams. Endpoints without H.264 WILL NOT WORK.
-# Disabling it will make the process go untouched and may cause transcoding.
-webcam-force-h264: true
-# Preferred H.264 profile-level-id for webcams. Forces everyone to use CB
-webcam-preferred-h264-profile: "42e01f"
-# Target bitrate (kbps) for webcams. Value 0 leaves it unconstrained.
-webcam-target-bitrate: 300
-# FORCES H.264 for screenshare. Endpoints without H.264 WILL NOT WORK.
-# Disabling it will make the process go untouched and may cause transcoding.
-screenshare-force-h264: true
-# Preferred H.264 profile-level-id for screenshare. Forces everyone to use CB
-screenshare-preferred-h264-profile: "42e01f"
-# Base interval for keyframe requsitions to the screenshare streamer
-screenshareKeyframeInterval: 2
-# Target bitrate (kbps) for screenshare. Value 0 leaves it unconstrained.
-screenshare-target-bitrate: 0
-# Size of the websocket pool SFU uses to connect to Kurento.
-kurento-websocket-pool-size: 1
-
-recordScreenSharing: true
-recordWebcams: false
-recordingBasePath: "file:///var/kurento"
-
-recordingMediaProfile: 'MKV_VIDEO_ONLY'
-recordingFormat: 'mkv'
-
-redisExpireTime: 1209600 # 14 days as per the akka keys
-
-# Used for the listen only bridge. The IP MUST be the one where FS is binded to
-freeswitch:
-    ip: 'FREESWITCH_IP'
-    port: '5066'
-
-# Log levels, in order of specificity: info, warn, verbose, debug, trace
-log:
-    filename: '/var/log/bbb-webrtc-sfu/bbb-webrtc-sfu.log'
-    level: 'verbose'
diff --git a/labs/bbb-webrtc-sfu/debug-start.sh b/labs/bbb-webrtc-sfu/debug-start.sh
deleted file mode 100644
index b7c6990b40943deef6c8529bfec832f0d929927b..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/debug-start.sh
+++ /dev/null
@@ -1 +0,0 @@
-node --inspect --debug-brk server.js
diff --git a/labs/bbb-webrtc-sfu/docker-entrypoint.sh b/labs/bbb-webrtc-sfu/docker-entrypoint.sh
deleted file mode 100755
index d424e511a15e8814d6dbb9fad53b62c07729b2d6..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/docker-entrypoint.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash -e
-
-CONTAINER_IP=$(hostname -I | awk '{print $1}')
-
-sed -i "s|^\(localIpAddress\):.*|\1: \"$CONTAINER_IP\"|g" config/production.yml
-
-if [ ! -z "$KURENTO_NAME" ]; then
-    export KURENTO_IP=$(getent hosts $KURENTO_NAME | awk '{ print $1 }')
-fi
-
-npm start
diff --git a/labs/bbb-webrtc-sfu/lib/ProcessManager.js b/labs/bbb-webrtc-sfu/lib/ProcessManager.js
deleted file mode 100644
index 9753a37ebdfa59c49e434aa6847d6dd0c5d129e7..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/ProcessManager.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-'use strict';
-
-const cp = require('child_process');
-const Logger = require('./utils/Logger');
-const SCREENSHARE_PATH = './lib/screenshare/ScreenshareProcess';
-const VIDEO_PATH = './lib/video/VideoProcess.js';
-const AUDIO_PATH = './lib/audio/AudioProcess.js';
-
-module.exports = class ProcessManager {
-  constructor() {
-    this.screensharePid;
-    this.videoPid;
-    this.screenshareProcess;
-    this.videoProcess;
-    this.audioProcess;
-    this.processes = {};
-    this.runningState = "RUNNING";
-  }
-
-  async start () {
-    let screenshareProcess = this.startProcess(SCREENSHARE_PATH);
-    let videoProcess = this.startProcess(VIDEO_PATH);
-    let audioProcess = this.startProcess(AUDIO_PATH);
-
-
-    this.processes[screenshareProcess.pid] = screenshareProcess;
-    this.processes[videoProcess.pid] = videoProcess;
-    this.processes[audioProcess.pid] = audioProcess;
-
-    process.on('SIGTERM', async () => {
-      await this.finishChildProcesses();
-      process.exit(0);
-    });
-
-    process.on('SIGINT', async () => {
-      await this.finishChildProcesses();
-      process.exit(0);
-    });
-
-    process.on('uncaughtException', async (error) => {
-      Logger.error('[ProcessManager] Uncaught exception', error.stack);
-      await this.finishChildProcesses();
-      process.exit('1');
-    });
-
-    // Added this listener to identify unhandled promises, but we should start making
-    // sense of those as we find them
-    process.on('unhandledRejection', (reason, p) => {
-      Logger.error('[ProcessManager] Unhandled Rejection at: Promise', p, 'reason:', reason);
-    });
-  }
-
-  startProcess (processPath) {
-    Logger.info("[ProcessManager] Starting process at path", processPath);
-    let proc = cp.fork(processPath, {
-      // Pass over all of the environment.
-      env: process.ENV,
-      // Share stdout/stderr, so we can hear the inevitable errors.
-      silent: false
-    });
-
-    proc.path = processPath;
-
-    proc.on('message', this.onMessage);
-    proc.on('error', this.onError);
-
-    // Tries to restart process on unsucessful exit
-    proc.on('exit', (code, signal) => {
-      let processId = proc.pid;
-      if (this.runningState === 'RUNNING' && code === 1) {
-        Logger.error('[ProcessManager] Received exit event from child process with PID', proc.pid, ' with code', code, '. Restarting it');
-        this.restartProcess(processId);
-      }
-    });
-
-    return proc;
-  }
-
-  restartProcess (pid) {
-    let proc = this.processes[pid];
-    if (proc) {
-      let newProcess = this.startProcess(proc.path);
-      this.processes[newProcess.pid] = newProcess;
-      delete this.processes[pid];
-    }
-  }
-
-  onMessage (message) {
-    Logger.info('[ProcessManager] Received child message from', this.pid, message);
-  }
-
-  onError (e) {
-    Logger.error('[ProcessManager] Received child error', this.pid, e);
-  }
-
-  onDisconnect (e) {
-  }
-
-  async finishChildProcesses () {
-    this.runningState = "STOPPING";
-
-    for (var proc in this.processes) {
-      if (this.processes.hasOwnProperty(proc)) {
-        let procObj = this.processes[proc];
-        if (typeof procObj.exit === 'function' && !procObj.killed) {
-          await procObj.exit()
-        }
-      }
-    }
-
-    this.runningState = "STOPPED";
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/audio/AudioManager.js b/labs/bbb-webrtc-sfu/lib/audio/AudioManager.js
deleted file mode 100755
index 54d8eebd3d32633dfc053af49b31fc96ed51e8e4..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/audio/AudioManager.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-"use strict";
-
-const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
-const Audio = require('./audio');
-const BaseManager = require('../base/BaseManager');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const errors = require('../base/errors');
-
-module.exports = class AudioManager extends BaseManager {
-  constructor (connectionChannel, additionalChannels, logPrefix) {
-    super(connectionChannel, additionalChannels, logPrefix);
-    this.sfuApp = C.AUDIO_APP;
-    this._meetings = {};
-    this._trackMeetingTermination();
-    this.messageFactory(this._onMessage);
-    this._iceQueues = {};
-  }
-
-  _trackMeetingTermination () {
-    switch (C.COMMON_MESSAGE_VERSION) {
-      case "1.x":
-        this._bbbGW.on(C.DICONNECT_ALL_USERS, (payload) => {
-          let meetingId = payload[C.MEETING_ID];
-          this._disconnectAllUsers(meetingId);
-        });
-        break;
-      default:
-        this._bbbGW.on(C.DICONNECT_ALL_USERS_2x, (payload) => {
-          let meetingId = payload[C.MEETING_ID_2x];
-          this._disconnectAllUsers(meetingId);
-        });
-    }
-  }
-
-  _disconnectAllUsers(meetingId) {
-    let sessionId = this._meetings[meetingId];
-    if (typeof sessionId !== 'undefined') {
-      Logger.debug(this._logPrefix, 'Disconnecting all users from', sessionId);
-      delete this._meetings[meetingId];
-      this._stopSession(sessionId);
-    }
-  }
-
-  async _onMessage(message) {
-    Logger.debug(this._logPrefix, 'Received message [' + message.id + '] from connection', message.connectionId);
-    let sessionId = message.voiceBridge;
-    let voiceBridge = sessionId;
-    let connectionId = message.connectionId;
-
-    let session = this._fetchSession(sessionId);
-    let iceQueue = this._fetchIceQueue(sessionId+connectionId);
-
-    switch (message.id) {
-      case 'start':
-        try {
-          if (!session) {
-            session = new Audio(this._bbbGW, connectionId, voiceBridge);
-          }
-
-          this._meetings[message.internalMeetingId] = sessionId;
-          this._sessions[sessionId] = session;
-
-          const { sdpOffer, caleeName, userId, userName } = message;
-
-          // starts audio session by sending sessionID, websocket and sdpoffer
-          const sdpAnswer = await session.start(sessionId, connectionId, sdpOffer, caleeName, userId, userName);
-          Logger.info(this._logPrefix, "Started presenter ", sessionId, " for connection", connectionId);
-
-          // Empty the ICE queue
-          this._flushIceQueue(session, iceQueue);
-
-          session.once(C.MEDIA_SERVER_OFFLINE, async (event) => {
-            const errorMessage = this._handleError(this._logPrefix, connectionId, caleeName, C.RECV_ROLE, errors.MEDIA_SERVER_OFFLINE);
-            errorMessage.id = 'webRTCAudioError';
-            this._bbbGW.publish(JSON.stringify({
-              ...errorMessage,
-            }), C.FROM_AUDIO);
-          });
-
-          this._bbbGW.publish(JSON.stringify({
-            connectionId: connectionId,
-            id : 'startResponse',
-            type: 'audio',
-            response : 'accepted',
-            sdpAnswer : sdpAnswer
-          }), C.FROM_AUDIO);
-
-          Logger.info(this._logPrefix, "Sending startResponse to user", sessionId, "for connection", session._id);
-        } catch (err) {
-          const errorMessage = this._handleError(this._logPrefix, connectionId, message.caleeName, C.RECV_ROLE, err);
-          errorMessage.id = 'webRTCAudioError';
-          return this._bbbGW.publish(JSON.stringify({
-            ...errorMessage
-          }), C.FROM_AUDIO);
-        }
-        break;
-
-      case 'stop':
-        Logger.info(this._logPrefix, 'Received stop message for session', sessionId, "at connection", connectionId);
-
-        if (session) {
-          session.stopListener(connectionId);
-        } else {
-          Logger.warn(this._logPrefix, "There was no audio session on stop for", sessionId);
-        }
-        break;
-
-      case 'iceCandidate':
-        if (session) {
-          session.onIceCandidate(message.candidate, connectionId);
-        } else {
-          Logger.warn(this._logPrefix, "There was no audio session for onIceCandidate for", sessionId, ". There should be a queue here");
-          iceQueue.push(message.candidate);
-        }
-        break;
-
-      case 'close':
-        Logger.info(this._logPrefix, 'Connection ' + connectionId + ' closed');
-        this._deleteIceQueue(sessionId+connectionId);
-        if (typeof session !== 'undefined') {
-          Logger.info(this._logPrefix, "Stopping viewer " + sessionId);
-          session.stopListener(message.connectionId);
-        }
-        break;
-
-      default:
-        const errorMessage = this._handleError(this._logPrefix, connectionId, null, null, errors.SFU_INVALID_REQUEST);
-        this._bbbGW.publish(JSON.stringify({
-          ...errorMessage,
-        }), C.FROM_AUDIO);
-        break;
-    }
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/audio/AudioProcess.js b/labs/bbb-webrtc-sfu/lib/audio/AudioProcess.js
deleted file mode 100644
index 08903d4f8d8ae831a36c13d7150b2d9763c34dd2..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/audio/AudioProcess.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict';
-
-const AudioManager= require('./AudioManager');
-const BaseProcess = require('../base/BaseProcess');
-const C = require('../bbb/messages/Constants');
-
-const manager = new AudioManager(C.TO_AUDIO, [C.FROM_BBB_MEETING_CHAN], C.AUDIO_MANAGER_PREFIX);
-const newProcess = new BaseProcess(manager, C.AUDIO_PROCESS_PREFIX);
-
-newProcess.start();
diff --git a/labs/bbb-webrtc-sfu/lib/audio/audio.js b/labs/bbb-webrtc-sfu/lib/audio/audio.js
deleted file mode 100644
index f1b8e059fae84e31971c857bac44ff61e5abe3bc..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/audio/audio.js
+++ /dev/null
@@ -1,316 +0,0 @@
-'use strict';
-
-const kurento = require('kurento-client');
-const config = require('config');
-const kurentoUrl = config.get('kurentoUrl');
-const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const Messaging = require('../bbb/messages/Messaging');
-const BaseProvider = require('../base/BaseProvider');
-const LOG_PREFIX = "[audio]";
-
-module.exports = class Audio extends BaseProvider {
-  constructor(_bbbGW, _id, voiceBridge) {
-    super();
-    this.sfuApp = C.AUDIO_APP;
-    this.mcs = new MCSApi();
-    this.bbbGW = _bbbGW;
-    this.id = _id;
-    this.voiceBridge = voiceBridge;
-    this.sourceAudio;
-    this.sourceAudioStarted = false;
-    this.audioEndpoints = {};
-    this.role;
-    this.webRtcEndpoint = null;
-    this.userId;
-
-    this.connectedUsers = {};
-    this.candidatesQueue = {}
-  }
-
-  onIceCandidate (_candidate, connectionId) {
-    if (this.audioEndpoints[connectionId]) {
-      try {
-        this.flushCandidatesQueue(connectionId);
-        this.mcs.addIceCandidate(this.audioEndpoints[connectionId], _candidate);
-      }
-      catch (err)   {
-        const userId = this.getUser(connectionId);
-        this._handleError(LOG_PREFIX, err, "recv", userId);
-      }
-    }
-    else {
-      if(!this.candidatesQueue[connectionId]) {
-        this.candidatesQueue[connectionId] = [];
-      }
-      this.candidatesQueue[connectionId].push(_candidate);
-    }
-  };
-
-  flushCandidatesQueue (connectionId) {
-    if (this.audioEndpoints[connectionId]) {
-      try {
-        if (this.candidatesQueue[connectionId]) {
-          while(this.candidatesQueue[connectionId].length) {
-            const candidate = this.candidatesQueue[connectionId].shift();
-            this.mcs.addIceCandidate(this.audioEndpoints[connectionId], candidate);
-          }
-        }
-      }
-      catch (err) {
-        const userId = this.getUser(connectionId);
-        this._handleError(LOG_PREFIX, err, "recv", userId);
-        Logger.error(LOG_PREFIX, "ICE candidate could not be added to media controller.", err);
-      }
-    }
-  }
-
-/**
- * Include user to a hash object indexed by it's connectionId
- * @param  {String} connectionId Current connection id at the media manager
- * @param  {Object} user {userId: String, userName: String}
- */
-  addUser(connectionId, user) {
-    if (this.connectedUsers.hasOwnProperty(connectionId)) {
-      Logger.warn(LOG_PREFIX, "Updating user for connectionId", connectionId)
-    }
-    this.connectedUsers[connectionId] = user;
-  };
-
-/**
- * Exclude user from a hash object indexed by it's connectionId
- * @param  {String} connectionId Current connection id at the media manager
- */
-  removeUser(connectionId) {
-    if (this.connectedUsers.hasOwnProperty(connectionId)) {
-      delete this.connectedUsers[connectionId];
-    } else {
-      Logger.error(LOG_PREFIX, "Missing connectionId", connectionId);
-    }
-  };
-
-/**
- * Consult user from a hash object indexed by it's connectionId
- * @param  {String} connectionId Current connection id at the media manager
- * @return  {Object} user {userId: String, userName: String}
- */
-  getUser(connectionId) {
-    if (this.connectedUsers.hasOwnProperty(connectionId)) {
-      return this.connectedUsers[connectionId];
-    } else {
-      Logger.error(LOG_PREFIX, "Missing connectionId", connectionId);
-    }
-  };
-
-  mediaState (event) {
-    let msEvent = event.event;
-
-    switch (event.eventTag) {
-
-      case "MediaStateChanged":
-        break;
-
-      default: Logger.warn(LOG_PREFIX, "Unrecognized event");
-    }
-  }
-
-  mediaStateWebRtc (event, id) {
-    let msEvent = event.event;
-
-    switch (event.eventTag) {
-      case "OnIceCandidate":
-        let candidate = msEvent.candidate;
-        Logger.debug(LOG_PREFIX, 'Received ICE candidate from mcs-core for media session', event.id, '=>', candidate);
-
-        this.bbbGW.publish(JSON.stringify({
-          connectionId: id,
-          id : 'iceCandidate',
-          type: 'audio',
-          cameraId: this._id,
-          candidate : candidate
-        }), C.FROM_AUDIO);
-
-        break;
-
-      case "MediaStateChanged":
-        break;
-
-      case "MediaFlowOutStateChange":
-        Logger.info('[audio]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session',  event.id);
-        // TODO treat this accordingly =( (prlanzarin 05/02/2018)
-
-        break;
-
-      case "MediaFlowInStateChange":
-        Logger.info('[audio]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session ',  event.id);
-        if (msEvent.state === 'FLOWING') {
-          this._onRtpMediaFlowing(id);
-        } else {
-          this._onRtpMediaNotFlowing(id);
-        }
-        break;
-
-      default: Logger.warn(LOG_PREFIX, "Unrecognized event", event);
-    }
-  }
-
-  start (sessionId, connectionId, sdpOffer, caleeName, userId, userName) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info(LOG_PREFIX, "Starting audio instance for", this.id);
-      let sdpAnswer;
-
-      // Storing the user data to be used by the pub calls
-      let user = {userId: userId, userName: userName};
-      this.addUser(connectionId, user);
-
-      try {
-        if (!this.sourceAudioStarted) {
-          this.userId = await this.mcs.join(this.voiceBridge, 'SFU', {});
-          Logger.info(LOG_PREFIX, "MCS join for", this.id, "returned", this.userId);
-
-          const ret = await this.mcs.publish(this.userId,
-            this.voiceBridge,
-            'RtpEndpoint',
-            {descriptor: sdpOffer, adapter: 'Freeswitch', name: caleeName});
-
-          this.sourceAudio = ret.sessionId;
-          this.mcs.on('MediaEvent' + this.sourceAudio, this.mediaState.bind(this));
-          this.mcs.on('ServerState' + this.sourceAudio, this.serverState.bind(this));
-          this.sourceAudioStarted = true;
-
-          Logger.info(LOG_PREFIX, "MCS publish for user", this.userId, "returned", this.sourceAudio);
-        }
-
-        const retSubscribe  = await this.mcs.subscribe(this.userId,
-          this.sourceAudio,
-          'WebRtcEndpoint',
-          {descriptor: sdpOffer, adapter: 'Kurento'});
-
-        this.audioEndpoints[connectionId] = retSubscribe.sessionId;
-
-        sdpAnswer = retSubscribe.answer;
-        this.flushCandidatesQueue(connectionId);
-
-        this.mcs.on('MediaEvent' + retSubscribe.sessionId, (event) => {
-          this.mediaStateWebRtc(event, connectionId)
-        });
-
-        Logger.info(LOG_PREFIX, "MCS subscribe for user", this.userId, "returned", retSubscribe.sessionId);
-
-        return resolve(sdpAnswer);
-      }
-      catch (err) {
-        return reject(this._handleError(LOG_PREFIX, err, "recv", userId));
-      }
-    });
-  }
-
-  async stopListener(id) {
-    const listener = this.audioEndpoints[id];
-    const userId = this.getUser(id);
-    Logger.info(LOG_PREFIX, 'Releasing endpoints for', listener);
-
-    this.sendUserDisconnectedFromGlobalAudioMessage(id);
-
-    if (listener) {
-      try {
-        if (this.audioEndpoints && Object.keys(this.audioEndpoints).length === 1) {
-          await this.mcs.leave(this.voiceBridge, this.userId);
-          this.sourceAudioStarted = false;
-        }
-        else {
-          await this.mcs.unsubscribe(this.userId, listener);
-        }
-
-        delete this.candidatesQueue[id];
-        delete this.audioEndpoints[id];
-
-        return;
-      }
-      catch (err) {
-        this._handleError(LOG_PREFIX, err, "recv", userId);
-        return;
-      }
-    }
-  }
-
-  async stop () {
-    Logger.info(LOG_PREFIX, 'Releasing endpoints for user', this.userId, 'at room', this.voiceBridge);
-
-    try {
-      await this.mcs.leave(this.voiceBridge, this.userId);
-
-      for (var listener in this.audioEndpoints) {
-        delete this.audioEndpoints[listener];
-      }
-
-      for (var queue in this.candidatesQueue) {
-        delete this.candidatesQueue[queue];
-      }
-
-      for (var connection in this.connectedUsers) {
-        this.sendUserDisconnectedFromGlobalAudioMessage(connection);
-      }
-
-      this.sourceAudioStarted = false;
-
-      return Promise.resolve();
-    }
-    catch (err) {
-      throw (this._handleError(LOG_PREFIX, err, "recv", this.userId));
-    }
-  };
-
-  sendUserDisconnectedFromGlobalAudioMessage(connectionId) {
-    let user = this.getUser(connectionId);
-    let msg = Messaging.generateUserDisconnectedFromGlobalAudioMessage(this.voiceBridge, user.userId, user.userName);
-    Logger.info(LOG_PREFIX, 'Sending global audio disconnection for user', user);
-
-    // Interoperability between transcoder messages
-    switch (C.COMMON_MESSAGE_VERSION) {
-      case "1.x":
-        this.bbbGW.publish(msg, C.TO_BBB_MEETING_CHAN, function(error) {});
-        break;
-      default:
-        this.bbbGW.publish(msg, C.TO_AKKA_APPS_CHAN_2x, function(error) {});
-    }
-
-    this.removeUser(connectionId);
-  };
-
-  sendUserConnectedToGlobalAudioMessage(connectionId) {
-    let user = this.getUser(connectionId);
-    let msg = Messaging.generateUserConnectedToGlobalAudioMessage(this.voiceBridge, user.userId, user.userName);
-    Logger.info(LOG_PREFIX, 'Sending global audio connection for user', user);
-
-    // Interoperability between transcoder messages
-    switch (C.COMMON_MESSAGE_VERSION) {
-      case "1.x":
-        this.bbbGW.publish(msg, C.TO_BBB_MEETING_CHAN, function(error) {});
-        break;
-      default:
-        this.bbbGW.publish(msg, C.TO_AKKA_APPS_CHAN_2x, function(error) {});
-    }
-  };
-
-  _onRtpMediaFlowing(connectionId) {
-    Logger.info(LOG_PREFIX, "RTP Media FLOWING for voice bridge", this.voiceBridge);
-    this.sendUserConnectedToGlobalAudioMessage(connectionId);
-    this.bbbGW.publish(JSON.stringify({
-        connectionId: connectionId,
-        id: "webRTCAudioSuccess",
-        success: "MEDIA_FLOWING"
-    }), C.FROM_AUDIO);
-  };
-
-  _onRtpMediaNotFlowing(connectionId) {
-    Logger.warn(LOG_PREFIX, "RTP Media NOT FLOWING for voice bridge" + this.voiceBridge);
-    this.bbbGW.publish(JSON.stringify({
-        connectionId: connectionId,
-        id: "webRTCAudioError",
-        error: C.MEDIA_ERROR
-    }), C.FROM_AUDIO);
-    this.removeUser(connectionId);
-  };
-};
diff --git a/labs/bbb-webrtc-sfu/lib/base/BaseManager.js b/labs/bbb-webrtc-sfu/lib/base/BaseManager.js
deleted file mode 100644
index cae3a0346030aac83dbb8a521525580a2ecb5f13..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/base/BaseManager.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-"use strict";
-
-const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const errors = require('../base/errors');
-
-module.exports = class BaseManager {
-  constructor (connectionChannel, additionalChannels = [], logPrefix = C.BASE_MANAGER_PREFIX) {
-    this._sessions = {};
-    this._bbbGW = new BigBlueButtonGW();
-    this._redisGateway;
-    this._connectionChannel = connectionChannel;
-    this._additionalChanels = additionalChannels;
-    this._logPrefix = logPrefix;
-    this._iceQueues = {};
-  }
-
-  async start() {
-    try {
-      // Additional channels that this manager is going to use
-      this._additionalChanels.forEach((channel) => {
-        this._bbbGW.addSubscribeChannel(channel);
-      });
-    }
-    catch (error) {
-      Logger.error(this._logPrefix, 'Could not connect to Redis channel', error);
-      await this.stopAll();
-      throw new Error(error);
-    }
-  }
-
-  async messageFactory (handler) {
-    // Entrypoint for messages to the manager (from the connection-manager/ws module
-    this._redisGateway = await this._bbbGW.addSubscribeChannel(this._connectionChannel);
-    this._redisGateway.on(C.REDIS_MESSAGE, handler.bind(this));
-  }
-
-  _fetchSession (sessionId) {
-    return this._sessions[sessionId];
-  }
-
-  _fetchIceQueue (sessionId) {
-    if (this._iceQueues[sessionId] == null) {
-      this._iceQueues[sessionId] = [];
-    }
-
-    return this._iceQueues[sessionId] ;
-  }
-
-  _flushIceQueue (session, queue) {
-    if (queue) {
-      let candidate;
-      while(candidate = queue.pop()) {
-        session.onIceCandidate(candidate);
-      }
-    }
-  }
-
-  _deleteIceQueue (sessionId) {
-    if (this._iceQueues[sessionId]) {
-      delete this._iceQueues[sessionId];
-    }
-  }
-
-  _killConnectionSessions (connectionId) {
-    const keys = Object.keys(this._sessions);
-    keys.forEach((sessionId) => {
-      let session = this._sessions[sessionId];
-      if(session && session.connectionId === connectionId) {
-        let killedSessionId = session.connectionId + session.id + "-" + session.role;
-        this._stopSession(killedSessionId);
-      }
-    });
-  }
-
-  _stopSession (sessionId) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info(this._logPrefix, 'Stopping session ' + sessionId);
-      try {
-        if (this._sessions == null|| sessionId == null) {
-          return resolve();
-        }
-
-        let session = this._sessions[sessionId];
-        if(session) {
-          if (typeof session.stop === 'function') {
-            await session.stop();
-          }
-          delete this._sessions[sessionId];
-          this._logAvailableSessions();
-          return resolve();
-        }
-      }
-      catch (err) {
-        Logger.error(err);
-        return resolve();
-      }
-    });
-  }
-
-  stopAll() {
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.info(this._logPrefix, 'Stopping everything! ');
-        if (this._sessions == null) {
-          return resolve;
-        }
-
-        let sessionIds = Object.keys(this._sessions);
-        let stopProcedures = [];
-
-        for (let i = 0; i < sessionIds.length; i++) {
-          stopProcedures.push(this._stopSession(sessionIds[i]));
-        }
-        resolve(Promise.all(stopProcedures));
-      }
-      catch (err) {
-        Logger.error(error);
-        resolve();
-      }
-    });
-  }
-
-  _logAvailableSessions () {
-    if(this._sessions) {
-      let sessionMainKeys = Object.keys(this._sessions);
-      let logInfo = this._logPrefix + 'There are ' + sessionMainKeys.length + ' sessions available =>\n';
-      for (var k in this._sessions) {
-        if(this._sessions[k]) {
-          logInfo += '(Session[' +  k +']' + ' of type ' + this._sessions[k].constructor.name + ');\n';
-        }
-      }
-      Logger.debug(logInfo);
-    }
-  }
-
-  _handleError (logPrefix, connectionId, streamId, role, error) {
-    // Setting a default error in case it was unhandled
-    if (error == null) {
-      error = { code: 2200, reason: errors[2200] }
-    }
-
-    if (error && this._validateErrorMessage(error)) {
-      return error;
-    }
-
-    const { code } = error;
-    const reason = errors[code];
-
-    if (reason == null) {
-      return;
-    }
-
-    error.message = reason;
-
-    Logger.debug(logPrefix, "Handling error", error.code, error.message);
-    Logger.trace(logPrefix, error.stack);
-
-    return this._assembleErrorMessage(error, role, streamId, connectionId);
-  }
-
-  _assembleErrorMessage (error, role, streamId, connectionId) {
-    return {
-      connectionId,
-      type: this.sfuApp,
-      id: 'error',
-      role,
-      streamId,
-      code: error.code,
-      reason: error.message,
-    };
-  }
-
-  _validateErrorMessage (error) {
-    const {
-      connectionId = null,
-      type = null,
-      id = null,
-      role = null,
-      streamId = null,
-      code = null,
-      reason = null,
-    } = error;
-    return connectionId && type && id && role && streamId && code && reason;
-  }
-
-};
diff --git a/labs/bbb-webrtc-sfu/lib/base/BaseProcess.js b/labs/bbb-webrtc-sfu/lib/base/BaseProcess.js
deleted file mode 100644
index b229c262b70d0a562b72e8ebaa82c4998c2d381e..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/base/BaseProcess.js
+++ /dev/null
@@ -1,64 +0,0 @@
-'use strict'
-
-const Logger = require('../utils/Logger');
-const config = require('config');
-const C = require('../bbb/messages/Constants');
-
-module.exports = class BaseProcess {
-  constructor(manager, logPrefix = C.BASE_PROCESS_PREFIX) {
-    this.runningState = "RUNNING";
-    this.manager = manager;
-    this.logPrefix = logPrefix;
-  }
-
-  start () {
-    this.manager.start();
-
-    if (config.get('acceptSelfSignedCertificate')) {
-      process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
-    }
-
-    process.on('disconnect', this.stop.bind(this));
-    process.on('SIGTERM', this.stop.bind(this));
-    process.on('SIGINT', this.stop.bind(this));
-    process.on('uncaughtException', this.handleException.bind(this));
-    process.on('unhandledRejection', this.handleRejection.bind(this));
-  }
-
-  async stop () {
-    try {
-      this.runningState = "STOPPING";
-      Promise.race([this.manager.stopAll(), this._failOver()]).then(() => {
-        Logger.info(this.logPrefix, "Exiting process with code 0");
-        process.exit();
-      });
-    }
-    catch (err) {
-      Logger.error(this.logPrefix, err);
-      Logger.info(this.logPrefix, "Exiting process with code 1");
-      process.exit(1);
-    }
-  }
-
-  _failOver () {
-    return new Promise((resolve, reject) => {
-      setTimeout(resolve, 5000);
-    });
-  }
-
-  handleException (error) {
-    Logger.error(this.logPrefix, 'TODO => Uncaught exception', error.stack);
-    if (this.runningState === "STOPPING") {
-      Logger.warn(this.logPrefix, "Exiting process with code 1");
-      process.exit(1);
-    }
-  }
-
-  handleRejection (reason, promise) {
-    Logger.error(this.logPrefix, 'TODO => Unhandled Rejection at: Promise', promise, 'reason:', reason);
-    if (this.runningState === "STOPPING") {
-      Logger.warn(this.logPrefix, "Exiting process with code 1");
-      process.exit(1);
-    }
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/base/BaseProvider.js b/labs/bbb-webrtc-sfu/lib/base/BaseProvider.js
deleted file mode 100644
index cf89a4c71f1521e087453be9f5d2c962d3d4f47a..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/base/BaseProvider.js
+++ /dev/null
@@ -1,90 +0,0 @@
-"use strict";
-
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const EventEmitter = require('events').EventEmitter;
-const errors = require('../base/errors');
-const config = require('config');
-const LOG_PREFIX = '[base-provider]';
-
-module.exports = class BaseProvider extends EventEmitter {
-  constructor () {
-    super();
-    this.sfuApp = "base";
-  }
-
-  serverState (event) {
-    let code = null;
-    const { eventTag } = { ...event };
-    if (eventTag && eventTag.code) {
-      code = eventTag.code;
-    }
-
-    switch (code) {
-      case C.MEDIA_SERVER_OFFLINE:
-        Logger.error(LOG_PREFIX, "Provider received MEDIA_SERVER_OFFLINE event");
-        this.emit(C.MEDIA_SERVER_OFFLINE, event);
-        break;
-
-      default:
-        Logger.warn(LOG_PREFIX, "Unknown server state", event);
-    }
-  }
-
-
-  _handleError (logPrefix, error, role, streamId) {
-    // Setting a default error in case it was unhandled
-    if (error == null) {
-      error = { code: 2200, reason: errors[2200] }
-    }
-
-    if (this._validateErrorMessage(error)) {
-      return error;
-    }
-
-    const { code } = error;
-    const reason = errors[code];
-
-    if (reason == null) {
-      return;
-    }
-
-    error.message = reason;
-
-    Logger.debug(logPrefix, "Handling error", error.code, error.message);
-    Logger.trace(logPrefix, error.stack);
-
-    return this._assembleErrorMessage(error, role, streamId);
-  }
-
-  _assembleErrorMessage (error, role, streamId) {
-    return {
-      type: this.sfuApp,
-      id: 'error',
-      role,
-      streamId,
-      code: error.code,
-      reason: error.message,
-    };
-  }
-
-  _validateErrorMessage (error) {
-    const {
-      type = null,
-      id = null,
-      role = null,
-      streamId = null,
-      code = null,
-      reason = null,
-    } = error;
-    return type && id && role && streamId && code && reason;
-  }
-
-  getRecordingPath (room, subPath, recordingName) {
-    const format = config.get('recordingFormat');
-    const basePath = config.get('recordingBasePath');
-    const timestamp = (new Date()).getTime();
-
-    return `${basePath}/${subPath}/${room}/${recordingName}-${timestamp}.${format}`
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/base/errors.js b/labs/bbb-webrtc-sfu/lib/base/errors.js
deleted file mode 100644
index adabafbedf9dda7034fc027dd4466f17dd9d012b..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/base/errors.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const errorCodes =  {
-  2000: "MEDIA_SERVER_CONNECTION_ERROR",
-  2001: "MEDIA_SERVER_OFFLINE",
-  2002: "MEDIA_SERVER_NO_RESOURCES",
-  2003: "MEDIA_SERVER_REQUEST_TIMEOUT",
-  2004: "MEDIA_SERVER_GENERIC_ERROR",
-  2020: "ICE_ADD_CANDIDATE_FAILED",
-  2021: "ICE_GATHERING_FAILED",
-  2022: "ICE_STATE_FAILED",
-  2200: "MEDIA_GENERIC_ERROR",
-  2201: "MEDIA_NOT_FOUND",
-  2202: "MEDIA_INVALID_SDP",
-  2203: "MEDIA_NO_AVAILABLE_CODEC",
-  2208: "MEDIA_GENERIC_PROCESS_ERROR",
-  2209: "MEDIA_ADAPTER_OBJECT_NOT_FOUND",
-  2210: "MEDIA_CONNECT_ERROR",
-  2211: "MEDIA_NOT_FLOWING",
-  2300: "SFU_INVALID_REQUEST",
-}
-
-const expandErrors = () => {
-  let expandedErrors = Object.keys(errorCodes).reduce((map, key) => {
-    map[errorCodes[key]] = { code: key, reason: errorCodes[key] };
-    return map;
-  }, {});
-
-  return { ...errorCodes, ...expandedErrors };
-}
-
-module.exports = expandErrors();
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js
deleted file mode 100644
index 038a0c01ddccc39f7340ad1e17ae667f20d2981f..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js
+++ /dev/null
@@ -1,180 +0,0 @@
-"use strict";
-
-const config = require('config');
-/**
- * @classdesc
- * Message constants for the communication with BigBlueButton
- * @constructor
- */
-  function Constants () {
-    return {
-        // Media elements
-        WEBRTC: "WebRtcEndpoint",
-        RTP: "RtpEndpoint",
-        AUDIO: "AUDIO",
-        VIDEO: "VIDEO",
-        ALL: "ALL",
-
-        // SFU app types
-        SCREENSHARE_APP:  'screenshare',
-        VIDEO_APP: 'video',
-        AUDIO_APP: 'audio',
-
-        // SFU requisition roles
-        SEND_ROLE: 'send',
-        RECV_ROLE: 'recv',
-        SEND_RECV_ROLE: 'sendrecv',
-
-        // Redis channels
-        FROM_BBB_TRANSCODE_SYSTEM_CHAN : "bigbluebutton:from-bbb-transcode:system",
-        FROM_VOICE_CONF_SYSTEM_CHAN: "from-voice-conf-redis-channel",
-        TO_BBB_TRANSCODE_SYSTEM_CHAN: "bigbluebutton:to-bbb-transcode:system",
-        TO_BBB_MEETING_CHAN: "bigbluebutton:to-bbb-apps:meeting",
-        FROM_BBB_MEETING_CHAN: "bigbluebutton:from-bbb-apps:meeting",
-        TO_AKKA_APPS_CHAN_2x: "to-akka-apps-redis-channel",
-        FROM_SCREENSHARE: config.get('from-screenshare'),
-        TO_SCREENSHARE: config.get('to-screenshare'),
-        FROM_VIDEO: config.get('from-video'),
-        TO_VIDEO: config.get('to-video'),
-        FROM_AUDIO: config.get('from-audio'),
-        TO_AUDIO: config.get('to-audio'),
-        TO_AKKA_APPS: config.get('to-akka'),
-        FROM_AKKA_APPS: config.get('from-akka'),
-
-        // RedisWrapper events
-        REDIS_MESSAGE : "redis_message",
-        WEBSOCKET_MESAGE: "ws_message",
-        GATEWAY_MESSAGE: "gateway_message",
-
-        RECORDING_STATUS_REQUEST_MESSAGE_2x: "GetRecordingStatusReqMsg",
-        RECORDING_STATUS_REPLY_MESSAGE_2x: "GetRecordingStatusRespMsg",
-
-        // Message identifiers 1x
-        START_TRANSCODER_REQUEST: "start_transcoder_request_message",
-        START_TRANSCODER_REPLY: "start_transcoder_reply_message",
-        STOP_TRANSCODER_REQUEST: "stop_transcoder_request_message",
-        STOP_TRANSCODER_REPLY: "stop_transcoder_reply_message",
-        DESKSHARE_RTMP_BROADCAST_STARTED: "deskshare_rtmp_broadcast_started_message",
-        DESKSHARE_RTMP_BROADCAST_STOPPED: "deskshare_rtmp_broadcast_stopped_message",
-        GLOBAL_AUDIO_CONNECTED: "user_connected_to_global_audio",
-        GLOBAL_AUDIO_DISCONNECTED: "user_disconnected_from_global_audio",
-        DICONNECT_ALL_USERS: "disconnect_all_users_message",
-
-        //Message identifiers 2x
-        SCREENSHARE_RTMP_BROADCAST_STARTED_2x: "ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg",
-        SCREENSHARE_RTMP_BROADCAST_STOPPED_2x: "ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg",
-        START_TRANSCODER_REQ_2x: "StartTranscoderSysReqMsg",
-        START_TRANSCODER_RESP_2x: "StartTranscoderSysRespMsg",
-        STOP_TRANSCODER_REQ_2x: "StopTranscoderSysReqMsg",
-        STOP_TRANSCODER_RESP_2x: "StopTranscoderSysRespMsg",
-        GLOBAL_AUDIO_CONNECTED_2x: "UserConnectedToGlobalAudioMsg",
-        GLOBAL_AUDIO_DISCONNECTED_2x: "UserDisconnectedFromGlobalAudioMsg",
-        DICONNECT_ALL_USERS_2x: "DisconnectAllClientsSysMsg",
-        USER_CAM_BROADCAST_STOPPED_2x: "UserBroadcastCamStopMsg",
-        PRESENTER_ASSIGNED_2x: "PresenterAssignedEvtMsg",
-
-        STREAM_IS_RECORDED: "StreamIsRecordedMsg",
-
-        START_WEBCAM_SHARE: "StartWebRTCShareEvent",
-        STOP_WEBCAM_SHARE: "StopWebRTCShareEvent",
-
-        // Redis messages fields
-        //  Transcoder 1x
-        USER_ID : "user_id",
-        OPTIONS: "options",
-        VOICE_CONF_ID : "voice_conf_id",
-        TRANSCODER_ID : "transcoder_id",
-
-        // Transcoder 2x
-        USER_ID_2x : "userId",
-        TRANSCODER_ID_2x : "transcoderId",
-        MEETING_ID_2x: "meetingId",
-
-        // Akka Apps 2x
-        REQUESTED_BY: "requestedBy",
-
-        //  Screenshare 2x
-        CONFERENCE_NAME: "voiceConf",
-        SCREENSHARE_CONF: "screenshareConf",
-        STREAM_URL: "stream",
-        TIMESTAMP: "timestamp",
-        VIDEO_WIDTH: "vidWidth",
-        VIDEO_HEIGHT: "vidHeight",
-
-        // Audio
-        NAME: "name",
-        USERID: "userid",
-
-        // RTP params
-        MEETING_ID : "meeting_id",
-        VOICE_CONF : "voice_conf",
-        KURENTO_ENDPOINT_ID : "kurento_endpoint_id",
-        PARAMS : "params",
-        MEDIA_DESCRIPTION: "media_description",
-        LOCAL_IP_ADDRESS: "local_ip_address",
-        LOCAL_VIDEO_PORT: "local_video_port",
-        DESTINATION_IP_ADDRESS : "destination_ip_address",
-        DESTINATION_VIDEO_PORT : "destination_video_port",
-        REMOTE_VIDEO_PORT : "remote_video_port",
-        CODEC_NAME: "codec_name",
-        CODEC_ID: "codec_id",
-        CODEC_RATE: "codec_rate",
-        RTP_PROFILE: "rtp_profile",
-        SEND_RECEIVE: "send_receive",
-        FRAME_RATE: "frame_rate",
-        INPUT: "input",
-        KURENTO_TOKEN : "kurento_token",
-        SCREENSHARE: "deskShare",
-        STREAM_TYPE: "stream_type",
-        STREAM_TYPE_SCREENSHARE: "stream_type_deskshare",
-        STREAM_TYPE_VIDEO: "stream_type_video",
-        RTP_TO_RTMP: "transcode_rtp_to_rtmp",
-        TRANSCODER_CODEC: "codec",
-        TRANSCODER_TYPE: "transcoder_type",
-        CALLERNAME: "callername",
-
-        EVENT_NAME: 'eventName',
-
-        TIMESTAMP: 'timestamp',
-        TIMESTAMP_UTC: 'timestampUTC',
-
-        MODULE: 'module',
-        MODULE_WEBCAM: 'bbb-webrtc-sfu',
-
-        FILENAME: 'filename',
-
-        // Log prefixes
-        BASE_PROCESS_PREFIX: '[BaseProcess]',
-        BASE_MANAGER_PREFIX: '[BaseManager]',
-        BASE_PROVIDER_PREFIX: '[BaseProvider]',
-        SCREENSHARE_PROCESS_PREFIX: '[ScreenshareProcess]',
-        SCREENSHARE_MANAGER_PREFIX: '[ScreenshareManager]',
-        SCREENSHARE_PROVIDER_PREFIX: '[ScreenshareProvider]',
-        VIDEO_PROCESS_PREFIX: '[VideoProcess]',
-        VIDEO_MANAGER_PREFIX: '[VideoManager]',
-        VIDEO_PROVIDER_PREFIX: '[VideoProvider]',
-        AUDIO_PROCESS_PREFIX: '[AudioProcess]',
-        AUDIO_MANAGER_PREFIX: '[AudioManager]',
-        AUDIO_PROVIDER_PREFIX: '[AudioProvider]',
-
-        // MCS error codes
-        MEDIA_SERVER_OFFLINE: 2001,
-
-        // Media states'
-        MEDIA_FLOWING_IN: 'MEDIA_FLOWING_IN',
-        MEDIA_FLOWING_OUT: 'MEDIA_FLOWING_OUT',
-        MEDIA_NOT_FLOWING_IN: 'MEDIA_NOT_FLOWING_IN',
-        MEDIA_NOT_FLOWING_OUT: 'MEDIA_NOT_FLOWING_OUT',
-        MEDIA_CONNECTED: 'MEDIA_CONNECTED',
-        MEDIA_DISCONNECTED: 'MEDIA_DISCONNECTED',
-        ON_ICE_CANDIDATE: 'ON_ICE_CANDIDATE',
-
-        MEDIA_STARTED: 'MEDIA_STARTED',
-        MEDIA_STOPPED: 'MEDIA_STOPPED',
-        MEDIA_STARTING: 'MEDIA_STARTING',
-        MEDIA_PAUSED: 'MEDIA_PAUSE'
-    }
-}
-
-module.exports = Constants();
-
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/Messaging.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/Messaging.js
deleted file mode 100644
index af8225fa613b975c651998c0658da575a30e64e0..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/Messaging.js
+++ /dev/null
@@ -1,124 +0,0 @@
-const Constants = require('./Constants.js');
-
-// Messages
-
-let OutMessage = require('./OutMessage.js');
-
-let StartTranscoderRequestMessage =
-    require('./transcode/StartTranscoderRequestMessage.js')(Constants);
-let StopTranscoderRequestMessage =
-    require('./transcode/StopTranscoderRequestMessage.js')(Constants);
-let StartTranscoderSysReqMsg =
-    require('./transcode/StartTranscoderSysReqMsg.js')();
-let StopTranscoderSysReqMsg =
-    require('./transcode/StopTranscoderSysReqMsg.js')();
-let DeskShareRTMPBroadcastStartedEventMessage =
-    require('./screenshare/DeskShareRTMPBroadcastStartedEventMessage.js')(Constants);
-let DeskShareRTMPBroadcastStoppedEventMessage =
-    require('./screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js')(Constants);
-let ScreenshareRTMPBroadcastStartedEventMessage2x =
-    require('./screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js')(Constants);
-let ScreenshareRTMPBroadcastStoppedEventMessage2x =
-    require('./screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js')(Constants);
-let UserCamBroadcastStoppedEventMessage2x =
-    require('./video/UserCamBroadcastStoppedEventMessage2x.js')(Constants);
-let WebRTCShareEvent = require('./video/WebRTCShareEvent.js')(Constants);
-let RecordingStatusRequestMessage2x =
-    require('./recording/RecordingStatusRequestMessage2x.js')(Constants);
-let UserConnectedToGlobalAudio =
-    require('./audio/UserConnectedToGlobalAudio.js')(Constants);
-let UserDisconnectedFromGlobalAudio =
-    require('./audio/UserDisconnectedFromGlobalAudio.js')(Constants);
-let UserConnectedToGlobalAudio2x =
-    require('./audio/UserConnectedToGlobalAudio2x.js')(Constants);
-let UserDisconnectedFromGlobalAudio2x =
-    require('./audio/UserDisconnectedFromGlobalAudio2x.js')(Constants);
-
- /**
-  * @classdesc
-  * Messaging utils to assemble JSON/Redis BigBlueButton messages
-  * @constructor
-  */
-function Messaging() {}
-
-Messaging.prototype.generateStartTranscoderRequestMessage =
-  function(meetingId, transcoderId, params) {
-  let statrm = new StartTranscoderSysReqMsg(meetingId, transcoderId, params);
-  return statrm.toJson();
-}
-
-Messaging.prototype.generateStopTranscoderRequestMessage =
-  function(meetingId, transcoderId) {
-  let stotrm = new StopTranscoderSysReqMsg(meetingId, transcoderId);
-  return stotrm.toJson();
-}
-
-Messaging.prototype.generateDeskShareRTMPBroadcastStartedEvent =
-  function(conferenceName, streamUrl, vw, vh, timestamp) {
-  let stadrbem = new DeskShareRTMPBroadcastStartedEventMessage(conferenceName, streamUrl, vw, vh, timestamp);
-  return stadrbem.toJson();
-}
-
-Messaging.prototype.generateDeskShareRTMPBroadcastStoppedEvent =
-  function(conferenceName, streamUrl, vw, vh, timestamp) {
-  let stodrbem = new DeskShareRTMPBroadcastStoppedEventMessage(conferenceName, streamUrl, vw, vh, timestamp);
-  return stodrbem.toJson();
-}
-
-Messaging.prototype.generateScreenshareRTMPBroadcastStartedEvent2x =
-  function(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp) {
-  let stadrbem = new ScreenshareRTMPBroadcastStartedEventMessage2x(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp);
-  return stadrbem.toJson();
-}
-
-Messaging.prototype.generateScreenshareRTMPBroadcastStoppedEvent2x =
-  function(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp) {
-  let stodrbem = new ScreenshareRTMPBroadcastStoppedEventMessage2x(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp);
-  return stodrbem.toJson();
-}
-
-Messaging.prototype.generateUserCamBroadcastStoppedEventMessage2x =
-  function(meetingId, userId, streamUrl) {
-  let stodrbem = new UserCamBroadcastStoppedEventMessage2x(meetingId, userId, streamUrl);
-  return stodrbem.toJson();
-}
-
-Messaging.prototype.generateWebRTCShareEvent =
-  function(name, meetingId, streamUrl) {
-  let stodrbem = new WebRTCShareEvent(name, meetingId, streamUrl);
-  return stodrbem.payload;
-}
-
-Messaging.prototype.generateRecordingStatusRequestMessage =
-  function(meetingId, userId = '') {
-    let rsqm = new RecordingStatusRequestMessage2x(meetingId, userId);
-    return rsqm.toJson();
-}
-
-Messaging.prototype.generateUserConnectedToGlobalAudioMessage =
-  function(voiceConf, userId, name) {
-  let msg;
-  switch (Constants.COMMON_MESSAGE_VERSION) {
-    case "1.x":
-      msg = new UserConnectedToGlobalAudio(voiceConf, userId, name);
-      break;
-    default:
-      msg = new UserConnectedToGlobalAudio2x(voiceConf, userId, name);
-  }
-  return msg.toJson();
-}
-
-Messaging.prototype.generateUserDisconnectedFromGlobalAudioMessage =
-  function(voiceConf, userId, name) {
-  let msg;
-  switch (Constants.COMMON_MESSAGE_VERSION) {
-    case "1.x":
-      msg = new UserDisconnectedFromGlobalAudio(voiceConf, userId, name);
-      break;
-    default:
-      msg = new UserDisconnectedFromGlobalAudio2x(voiceConf, userId, name);
-  }
-  return msg.toJson();
-}
-
-module.exports = new Messaging();
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/OutMessage.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/OutMessage.js
deleted file mode 100644
index 04776dca76e6513f20259b2a47c339f2c175c5e3..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/OutMessage.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * (C) Copyright 2016 Mconf Tecnologia (http://mconf.com/)
- */
-
-/**
- * @classdesc
- * Base class for output messages sent to BBB
- * @constructor
- */
-function OutMessage(messageName) {
-    /**
-     * The header template of the message
-     * @type {Object}
-     */
-    this.header = {
-        version: "0.0.1",
-        name: messageName
-    };
-
-    /**
-     * The payload of the message
-     * @type {Object}
-     */
-    this.payload = null;
-
-    /**
-     * Generates the JSON representation of the message
-     * @return {String} The JSON string of this message
-     */
-    this.toJson = function () {
-        return JSON.stringify(this);
-    }
-};
-
-module.exports = OutMessage;
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/OutMessage2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/OutMessage2x.js
deleted file mode 100644
index a6f9cafcfcd289d2ef95334743fb5c32f63bd8f6..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/OutMessage2x.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * (C) Copyright 2016 Mconf Tecnologia (http://mconf.com/)
- */
-
-/**
- * @classdesc
- * Base class for output messages sent to BBB
- * 2x model
- * @constructor
- */
-function OutMessage2x(messageName, routing, headerFields) {
-
-
-    this.envelope = {
-      name: messageName,
-      routing: routing 
-    }
-    /**
-     * The header template of the message
-     * @type {Object}
-     */
-    this.core = {
-      header : {
-        name: messageName
-      }
-    }
-
-    // Copy header fiels to the header object
-    var keys1 = Object.keys(headerFields);
-    for (var k=0; k < keys1.length; k++) {
-      var key = keys1[k];
-      if (typeof this.core.header[key] === 'undefined') {
-        this.core.header[key] = headerFields[key];
-      }
-    }
-
-    /**
-     * The body of the message
-     * @type {Object}
-     */
-    this.core.body = null;
-
-    /**
-     * Generates the JSON representation of the message
-     * @return {String} The JSON string of this message
-     */
-    this.toJson = function () {
-        return JSON.stringify(this);
-    }
-};
-
-module.exports = OutMessage2x;
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserConnectedToGlobalAudio.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserConnectedToGlobalAudio.js
deleted file mode 100644
index d9b868bc7e1fe9f58aac65627be4550396a1f0e0..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserConnectedToGlobalAudio.js
+++ /dev/null
@@ -1,16 +0,0 @@
-var inherits = require('inherits');
-var OutMessage = require('../OutMessage');
-
-module.exports = function(Constants) {
-  function UserConnectedToGlobalAudio(voiceConf, userId, name) {
-    UserConnectedToGlobalAudio.super_.call(this, Constants.GLOBAL_AUDIO_CONNECTED);
-
-    this.payload = {};
-    this.payload[Constants.VOICE_CONF] = voiceConf;
-    this.payload[Constants.USERID] = userId;
-    this.payload[Constants.NAME] = name;
-  };
-
-  inherits(UserConnectedToGlobalAudio, OutMessage);
-  return UserConnectedToGlobalAudio;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserConnectedToGlobalAudio2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserConnectedToGlobalAudio2x.js
deleted file mode 100644
index b5f318a9222cd18aec3808532d6e7dc5681cea2e..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserConnectedToGlobalAudio2x.js
+++ /dev/null
@@ -1,21 +0,0 @@
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-
-// TODO: Check if this is correct!
-module.exports = function(Constants) {
-  function UserConnectedToGlobalAudio2x(voiceConf, userId, name) {
-    UserConnectedToGlobalAudio2x.super_.call(
-        this,
-        Constants.GLOBAL_AUDIO_CONNECTED_2x,
-        {voiceConf: voiceConf},
-        {voiceConf: voiceConf}
-    );
-
-    this.core.body = {};
-    this.core.body[Constants.USER_ID_2x] = userId;
-    this.core.body[Constants.NAME] = name;
-  };
-
-  inherits(UserConnectedToGlobalAudio2x, OutMessage2x);
-  return UserConnectedToGlobalAudio2x;
-};
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserDisconnectedFromGlobalAudio.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserDisconnectedFromGlobalAudio.js
deleted file mode 100644
index a58bffb3b30036409d327ff7bb811943b019f373..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserDisconnectedFromGlobalAudio.js
+++ /dev/null
@@ -1,16 +0,0 @@
-var inherits = require('inherits');
-var OutMessage = require('../OutMessage');
-
-module.exports = function(Constants) {
-  function UserDisconnectedFromGlobalAudio(voiceConf, userId, name) {
-    UserDisconnectedFromGlobalAudio.super_.call(this, Constants.GLOBAL_AUDIO_DISCONNECTED);
-
-    this.payload = {};
-    this.payload[Constants.VOICE_CONF] = voiceConf;
-    this.payload[Constants.USERID] = userId;
-    this.payload[Constants.NAME] = name;
-  };
-
-  inherits(UserDisconnectedFromGlobalAudio, OutMessage);
-  return UserDisconnectedFromGlobalAudio;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserDisconnectedFromGlobalAudio2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserDisconnectedFromGlobalAudio2x.js
deleted file mode 100644
index e79b2772356b3840ab6e942acef111b0b65e9c2d..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/audio/UserDisconnectedFromGlobalAudio2x.js
+++ /dev/null
@@ -1,21 +0,0 @@
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-
-// TODO: Check if this is correct!
-module.exports = function(Constants) {
-  function UserDisconnectedFromGlobalAudio2x(voiceConf, userId, name) {
-    UserDisconnectedFromGlobalAudio2x.super_.call(
-        this,
-        Constants.GLOBAL_AUDIO_DISCONNECTED_2x,
-        {voiceConf: voiceConf},
-        {voiceConf: voiceConf}
-    );
-
-    this.core.body = {};
-    this.core.body[Constants.USER_ID_2x] = userId;
-    this.core.body[Constants.NAME] = name;
-  };
-
-  inherits(UserDisconnectedFromGlobalAudio2x, OutMessage2x);
-  return UserDisconnectedFromGlobalAudio2x;
-};
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/recording/RecordingStatusRequestMessage2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/recording/RecordingStatusRequestMessage2x.js
deleted file mode 100644
index 2f7e7f2c568f2fc70c04a72aa36ea52152fee4dd..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/recording/RecordingStatusRequestMessage2x.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-
-module.exports = function (C) {
-  function RecordingStatusRequestMessage2x (meetingId, userId) {
-    RecordingStatusRequestMessage2x.super_.call(this, C.RECORDING_STATUS_REQUEST_MESSAGE_2x, {sender: 'bbb-webrtc-sfu'}, {meetingId, userId});
-
-    this.core.body = {};
-    this.core.body[C.REQUESTED_BY] = userId;
-  };
-
-  inherits(RecordingStatusRequestMessage2x, OutMessage2x);
-  return RecordingStatusRequestMessage2x;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStartedEventMessage.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStartedEventMessage.js
deleted file mode 100644
index 34579de0bfa0854f7170d1e92efc7cb818b2cbee..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStartedEventMessage.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage = require('../OutMessage');
-
-module.exports = function (Constants) {
-  function DeskShareRTMPBroadcastStartedEventMessage (conferenceName, streamUrl, vw, vh, timestamp) {
-    DeskShareRTMPBroadcastStartedEventMessage.super_.call(this, Constants.DESKSHARE_RTMP_BROADCAST_STARTED);
-
-    this.payload = {};
-    this.payload[Constants.CONFERENCE_NAME] = conferenceName;
-    this.payload[Constants.STREAM_URL] = streamUrl;
-    this.payload[Constants.TIMESTAMP] = timestamp;
-    this.payload[Constants.VIDEO_WIDTH] = vw;
-    this.payload[Constants.VIDEO_HEIGHT] = vh;
-  };
-
-  inherits(DeskShareRTMPBroadcastStartedEventMessage, OutMessage);
-  return DeskShareRTMPBroadcastStartedEventMessage;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js
deleted file mode 100644
index 81e7125db7f9d7b61580f4dad93076387b6c8426..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage = require('../OutMessage');
-
-module.exports = function (Constants) {
-  function DeskShareRTMPBroadcastStoppedEventMessage (conferenceName, streamUrl, vw, vh, timestamp) {
-    DeskShareRTMPBroadcastStoppedEventMessage.super_.call(this, Constants.DESKSHARE_RTMP_BROADCAST_STOPPED);
-
-    this.payload = {};
-    this.payload[Constants.CONFERENCE_NAME] = conferenceName;
-    this.payload[Constants.STREAM_URL] = streamUrl;
-    this.payload[Constants.TIMESTAMP] = timestamp;
-    this.payload[Constants.VIDEO_WIDTH] = vw;
-    this.payload[Constants.VIDEO_HEIGHT] = vh;
-  };
-
-  inherits(DeskShareRTMPBroadcastStoppedEventMessage, OutMessage);
-  return DeskShareRTMPBroadcastStoppedEventMessage;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js
deleted file mode 100644
index 28867a2265f3a1d6393ebadc4936cc785e0be651..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-
-module.exports = function (C) {
-  function ScreenshareRTMPBroadcastStartedEventMessage2x (conferenceName, screenshareConf,
-      streamUrl, vw, vh, timestamp) {
-    ScreenshareRTMPBroadcastStartedEventMessage2x.super_.call(this, C.SCREENSHARE_RTMP_BROADCAST_STARTED_2x,
-        {voiceConf: conferenceName}, {voiceConf: conferenceName});
-
-    this.core.body = {};
-    this.core.body[C.CONFERENCE_NAME] = conferenceName;
-    this.core.body[C.SCREENSHARE_CONF] = screenshareConf; 
-    this.core.body[C.STREAM_URL] = streamUrl;
-    this.core.body[C.VIDEO_WIDTH] = vw;
-    this.core.body[C.VIDEO_HEIGHT] = vh;
-    this.core.body[C.TIMESTAMP] = timestamp;
-  };
-
-  inherits(ScreenshareRTMPBroadcastStartedEventMessage2x, OutMessage2x);
-  return ScreenshareRTMPBroadcastStartedEventMessage2x;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js
deleted file mode 100644
index d02dfb2cd3a335518cf5a207880cbb4b17e8cf64..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-
-module.exports = function (C) {
-  function ScreenshareRTMPBroadcastStoppedEventMessage2x (conferenceName, screenshareConf,
-      streamUrl, vw, vh, timestamp) {
-    ScreenshareRTMPBroadcastStoppedEventMessage2x.super_.call(this, C.SCREENSHARE_RTMP_BROADCAST_STOPPED_2x,
-        {voiceConf: conferenceName}, {voiceConf: conferenceName});
-
-    this.core.body = {};
-    this.core.body[C.CONFERENCE_NAME] = conferenceName;
-    this.core.body[C.SCREENSHARE_CONF] = screenshareConf; 
-    this.core.body[C.STREAM_URL] = streamUrl;
-    this.core.body[C.VIDEO_WIDTH] = vw;
-    this.core.body[C.VIDEO_HEIGHT] = vh;
-    this.core.body[C.TIMESTAMP] = timestamp;
-  };
-
-  inherits(ScreenshareRTMPBroadcastStoppedEventMessage2x, OutMessage2x);
-  return ScreenshareRTMPBroadcastStoppedEventMessage2x;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StartTranscoderRequestMessage.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StartTranscoderRequestMessage.js
deleted file mode 100644
index 69d5f0890f7c38d94a62e99e41cd7672ba8269fe..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StartTranscoderRequestMessage.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage = require('../OutMessage');
-
-module.exports = function (Constants) {
-  function StartTranscoderRequestMessage (meetingId, transcoderId, params) {
-    StartTranscoderRequestMessage.super_.call(this, Constants.START_TRANSCODER_REQUEST);
-
-    this.payload = {};
-    this.payload[Constants.MEETING_ID] = meetingId;
-    this.payload[Constants.TRANSCODER_ID] = transcoderId;
-    this.payload[Constants.PARAMS] = params;
-  };
-
-  inherits(StartTranscoderRequestMessage, OutMessage);
-  return StartTranscoderRequestMessage;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StartTranscoderSysReqMsg.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StartTranscoderSysReqMsg.js
deleted file mode 100644
index bd517a14905d51effe3abdc28987d3bca2b91a82..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StartTranscoderSysReqMsg.js
+++ /dev/null
@@ -1,18 +0,0 @@
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-var C = require('../Constants');
-
-module.exports = function() {
-  function StartTranscoderSysReqMsg(meetingId, transcoderId, params) {
-    StartTranscoderSysReqMsg.super_.call(this, C.START_TRANSCODER_REQ_2x,
-        {sender: "kurento-screenshare"},
-        {meetingId: meetingId});
-
-    this.core.body = {};
-    this.core.body[C.TRANSCODER_ID_2x] = transcoderId;
-    this.core.body[C.PARAMS] = params;
-  };
-
-  inherits(StartTranscoderSysReqMsg, OutMessage2x);
-  return StartTranscoderSysReqMsg;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StopTranscoderRequestMessage.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StopTranscoderRequestMessage.js
deleted file mode 100644
index ad030d2c623252d385c8298bdf79c112caf12623..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StopTranscoderRequestMessage.js
+++ /dev/null
@@ -1,15 +0,0 @@
-var inherits = require('inherits');
-var OutMessage = require('../OutMessage');
-
-module.exports = function (Constants) {
-  function StopTranscoderRequestMessage (meetingId, transcoderId) {
-    StopTranscoderRequestMessage.super_.call(this, Constants.STOP_TRANSCODER_REQUEST);
-
-    this.payload = {};
-    this.payload[Constants.MEETING_ID] = meetingId;
-    this.payload[Constants.TRANSCODER_ID] = transcoderId;
-  };
-
-  inherits(StopTranscoderRequestMessage, OutMessage);
-  return StopTranscoderRequestMessage;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StopTranscoderSysReqMsg.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StopTranscoderSysReqMsg.js
deleted file mode 100644
index 639b415792b643ff20bfa47ad523bf4e72f27d5a..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/transcode/StopTranscoderSysReqMsg.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-var C = require('../Constants');
-
-module.exports = function() {
-  function StopTranscoderSysReqMsg(meetingId, transcoderId) {
-    StopTranscoderSysReqMsg.super_.call(this, C.STOP_TRANSCODER_REQ_2x,
-        {sender: "kurento-screenshare"},
-        {meetingId: meetingId});
-
-    this.core.body = {};
-    this.core.body[C.TRANSCODER_ID_2x] = transcoderId;
-  };
-
-  inherits(StopTranscoderSysReqMsg, OutMessage2x);
-  return StopTranscoderSysReqMsg;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/video/UserCamBroadcastStoppedEventMessage2x.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/video/UserCamBroadcastStoppedEventMessage2x.js
deleted file mode 100644
index a4a320250011ab7d836a1f540e5a2db75e50dc26..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/video/UserCamBroadcastStoppedEventMessage2x.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * 
- */
-
-var inherits = require('inherits');
-var OutMessage2x = require('../OutMessage2x');
-
-module.exports = function (C) {
-  function UserCamBroadcastStoppedEventMessage2x (meetingId, userId, stream) {
-    UserCamBroadcastStoppedEventMessage2x.super_.call(this, C.USER_CAM_BROADCAST_STOPPED_2x, {sender: 'bbb-webrtc-sfu'}, {meetingId, userId});
-
-    this.core.body = {};
-    this.core.body[C.STREAM_URL] = stream; 
-  };
-
-  inherits(UserCamBroadcastStoppedEventMessage2x, OutMessage2x);
-  return UserCamBroadcastStoppedEventMessage2x;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/video/WebRTCShareEvent.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/video/WebRTCShareEvent.js
deleted file mode 100644
index 1d43a68d0b9810ddb4409c61a51aacb1199f0809..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/messages/video/WebRTCShareEvent.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 
- */
-
-var hrTime = require('../../../utils/Utils').hrTime;
-
-module.exports = function (C) {
-  function WebRTCShareEvent (name, meetingId, filename) {
-
-    let date = new Date();
-    let timestamp = hrTime();
-
-    this.payload = {};
-    this.payload[C.EVENT_NAME] = name;
-    this.payload[C.MODULE] = C.MODULE_WEBCAM;
-    this.payload[C.MEETING_ID] = meetingId;
-    this.payload[C.TIMESTAMP] = timestamp;
-    this.payload[C.TIMESTAMP_UTC] = date.getTime() ;
-    this.payload[C.FILENAME] = filename;
-  };
-
-  return WebRTCShareEvent;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js
deleted file mode 100644
index 5e14fba7fec8f363b54f5a7fa983839bcb33350a..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * @classdesc
- * Redis wrapper class for connecting to Redis channels
- */
-
-'use strict';
-
-/* Modules */
-
-const redis = require('redis');
-const config = require('config');
-const Constants = require('../messages/Constants.js');
-const EventEmitter = require('events').EventEmitter;
-const Logger = require('../../utils/Logger');
-
-/* Public members */
-
-module.exports = class RedisWrapper extends EventEmitter {
-  constructor(subpattern) {
-    super();
-    // Redis PubSub client holders
-    this.redisCli = null;
-    this.redisPub = null;
-    // Pub and Sub channels/patterns
-    this.subpattern = subpattern;
-  }
-
-  static get _retryThreshold() {
-    return 1000 * 60 * 60;
-  }
-
-  static get _maxRetries() {
-    return 10;
-  }
-
-  startPublisher () {
-    var options = {
-      host : config.get('redisHost'),
-      port : config.get('redisPort'),
-      //password: config.get('redis.password')
-      retry_strategy: this._redisRetry
-    };
-
-    this.redisPub = redis.createClient(options);
-  }
-
-  startSubscriber () {
-    let self = this;
-    if (this.redisCli) {
-      Logger.warn("[RedisWrapper] Redis Client already exists");
-      return;
-    }
-
-    var options = {
-      host : config.get('redisHost'),
-      port : config.get('redisPort'),
-      //password: config.get('redis.password')
-      retry_strategy: this._redisRetry
-    };
-
-    this.redisCli = redis.createClient(options);
-
-    this.redisCli.on("connect", () => {
-      //TODO
-    });
-
-    this.redisCli.on("error", (error) => {
-      Logger.error("[RedisWrapper] Wrapper returned an error", error);
-    });
-
-    this.redisCli.on("reconnecting", (msg) => {
-      Logger.warn("[RedisWrapper] Wrapper instance is reconnecting", msg);
-      //TODO
-    });
-
-    this.redisCli.on("psubscribe", (channel, count) => {
-      Logger.info("[RedisWrapper] Successfully subscribed to pattern [" + channel + "]");
-    });
-
-    this.redisCli.on("pmessage", this._onMessage.bind(this));
-
-    if (!this.subpattern) {
-      throw new Error("[RedisWrapper] No subscriber pattern");
-    }
-
-    this.redisCli.psubscribe(this.subpattern);
-
-    Logger.info("[RedisWrapper] Started Redis client at " + options.host + ":" + options.port +
-        " for subscription pattern: " + this.subpattern);
-  }
-
-  stopRedis (callback) {
-    if (this.redisCli){
-      this.redisCli.quit();
-    }
-    callback(false);
-  }
-
-  publishToChannel (_message, channel) {
-    let message = _message;
-    if(this.redisPub) {
-      this.redisPub.publish(channel, message);
-    }
-  }
-
-  pushToList (key, string, callback) {
-    if (this.redisPub) {
-      this.redisPub.rpush(key, string, callback);
-    } else {
-      callback(true, null)
-    }
-  }
-
-  setKeyWithIncrement (key, message, callback) {
-    let blowObject = function (obj) {
-      let arr = [];
-      Object.keys(obj).map(function (key) {
-        arr.push(key)
-        arr.push(obj[key]);
-      });
-      return arr;
-    }
-
-    if (this.redisPub){
-      this.redisPub.incr('global:nextRecordedMsgId', (err, msgId) => {
-        if (err) {
-          return callback(err, null);
-        }
-
-        let incr = key + ':' + msgId;
-        let value = blowObject(message);
-        this.redisPub.hmset(incr, value, (err) => {
-          if (err) {
-            return callback(err, null);
-          }
-
-          // Return the increment number to the caller
-          callback(err, msgId);
-        });
-      });
-
-    } else {
-      callback(true, null);
-    }
-  }
-
-  expireKey (key, seconds, callback) {
-    if (this.redisPub) {
-      this.redisPub.expire(key, seconds, callback);
-    } else {
-      callback(true, null);
-    }
-  }
-
-  getChannels () {
-    return new Promise((resolve, reject) => {
-      this.redisPub.pubsub('channels', (error, channels) => {
-        if (error) {
-          return reject(error);
-        }
-        return resolve(channels);
-      });
-    });
-  }
-
-  /* Private members */
-
-  _onMessage (pattern, channel, _message) {
-    let message = (typeof _message !== 'object')?JSON.parse(_message):_message;
-    // use event emitter to throw new message
-    this.emit(Constants.REDIS_MESSAGE, message);
-  }
-
-  static _redisRetry (options) {
-    // if (options.error && options.error.code === 'ECONNREFUSED') {
-    //   return new Error('The server refused the connection');
-    // }
-    if (options.total_retry_time > RedisWrapper._retryThreshold) {
-      return new Error('Retry time exhausted');
-    }
-    if (options.times_connected > RedisWrapper._maxRetries) {
-      return undefined;
-    }
-    return Math.max(options.attempt * 100, 3000);
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js
deleted file mode 100644
index bf6c4d062fe5906dda82efa4579c7a0eacf61c1c..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @classdesc
- * BigBlueButton redis gateway for bbb-screenshare node app
- */
-
-'use strict';
-
-/* Modules */
-
-const C = require('../messages/Constants.js');
-const RedisWrapper = require('./RedisWrapper.js');
-const config = require('config');
-const util = require('util');
-const EventEmitter = require('events').EventEmitter;
-const Logger = require('../../utils/Logger');
-
-let instance = null;
-
-module.exports = class BigBlueButtonGW extends EventEmitter {
-  constructor() {
-    if(!instance){
-      super();
-      this.subscribers = {};
-      this.publisher = null;
-      instance = this;
-    }
-
-    return instance;
-  }
-
-  addSubscribeChannel (channel) {
-    if (this.subscribers[channel]) {
-      return this.subscribers[channel];
-    }
-
-    let wrobj = new RedisWrapper(channel);
-    this.subscribers[channel] = {};
-    this.subscribers[channel] = wrobj;
-    try {
-      wrobj.startSubscriber();
-      wrobj.on(C.REDIS_MESSAGE, this.incomingMessage.bind(this));
-      Logger.info("[BigBlueButtonGW] Added redis client to this.subscribers[" + channel + "]");
-      return Promise.resolve(wrobj);
-    }
-    catch (error) {
-      return Promise.reject("[BigBlueButtonGW] Could not start redis client for channel " + channel);
-    }
-  }
-
-  /**
-   * Capture messages from subscribed channels and emit an event with it's
-   * identifier and payload. Check Constants.js for the identifiers.
-   *
-   * @param {Object} message  Redis message
-   */
-  incomingMessage (message) {
-    let header;
-    let payload;
-    let msg = (typeof message !== 'object')?JSON.parse(message):message;
-    let meetingId;
-
-    // Trying to parse both message types, 1x and 2x
-    if (msg.header) {
-      header = msg.header;
-      payload = msg.payload;
-    }
-    else if (msg.core) {
-      header = msg.core.header;
-      payload = msg.core.body;
-    }
-
-    if (header){
-      switch (header.name) {
-        // interoperability with 1.1
-        case C.START_TRANSCODER_REPLY:
-          meetingId = payload[C.MEETING_ID];
-          this.emit(C.START_TRANSCODER_REPLY+meetingId, payload);
-          break;
-        case C.STOP_TRANSCODER_REPLY:
-          meetingId = payload[C.MEETING_ID];
-          this.emit(C.STOP_TRANSCODER_REPLY+meetingId, payload);
-          break;
-        case C.DICONNECT_ALL_USERS:
-          this.emit(C.DICONNECT_ALL_USERS, payload);
-          break;
-          // 2x messages
-        case C.START_TRANSCODER_RESP_2x:
-          meetingId = header[C.MEETING_ID_2x];
-          payload[C.MEETING_ID_2x] = meetingId;
-          this.emit(C.START_TRANSCODER_RESP_2x+meetingId, payload);
-          break;
-        case C.STOP_TRANSCODER_RESP_2x:
-          meetingId = header[C.MEETING_ID_2x];
-          payload[C.MEETING_ID_2x] = meetingId;
-          this.emit(C.STOP_TRANSCODER_RESP_2x+meetingId, payload);
-          break;
-        case C.USER_CAM_BROADCAST_STARTED_2x:
-          this.emit(C.USER_CAM_BROADCAST_STARTED_2x, payload[C.STREAM_URL]);
-          break;
-        case C.RECORDING_STATUS_REPLY_MESSAGE_2x:
-          meetingId = header[C.MEETING_ID_2x];
-          this.emit(C.RECORDING_STATUS_REPLY_MESSAGE_2x+meetingId, payload);
-          break;
-        case C.DICONNECT_ALL_USERS_2x:
-          payload[C.MEETING_ID_2x] = header[C.MEETING_ID_2x];
-          this.emit(C.DICONNECT_ALL_USERS_2x, payload);
-          break;
-        case C.PRESENTER_ASSIGNED_2x:
-          meetingId = header[C.MEETING_ID_2x];
-          payload[C.MEETING_ID_2x] = meetingId;
-          this.emit(C.PRESENTER_ASSIGNED_2x+meetingId, payload);
-          break;
-        default:
-          this.emit(C.GATEWAY_MESSAGE, msg);
-      }
-    }
-    else {
-      this.emit(C.GATEWAY_MESSAGE, msg);
-    }
-  }
-
-  publish (message, channel) {
-    if (!this.publisher) {
-      this.publisher = new RedisWrapper();
-      this.publisher.startPublisher();
-    }
-
-    if (typeof this.publisher.publishToChannel === 'function') {
-      this.publisher.publishToChannel(message, channel);
-    }
-  }
-
-  writeMeetingKey(meetingId, message, callback) {
-    const EXPIRE_TIME = config.get('redisExpireTime');
-    if (!this.publisher) {
-      this.publisher = new RedisWrapper();
-      this.publisher.startPublisher();
-    }
-
-    let recKey = 'recording:' + meetingId;
-
-    this.publisher.setKeyWithIncrement(recKey, message, (err, msgId) => {
-
-      this.publisher.pushToList('meeting:' + meetingId + ':recordings', msgId);
-
-      // Not implemented yet
-      this.publisher.expireKey(recKey + ':' + msgId, EXPIRE_TIME, (err) => {
-        Logger.info('Recording key will expire in', EXPIRE_TIME, 'seconds', err);
-      });
-    });
-  }
-
-  async isChannelAvailable (channel) {
-    const channels = await this.publisher.getChannels();
-    return channels.includes(channel);
-  }
-
-  getChannels () {
-    return this.publisher.getChannels();
-  }
-
-  setEventEmitter (emitter) {
-    this.emitter = emitter;
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js
deleted file mode 100644
index efd15d8746f181c322d31dfd3798ee66705dc844..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-'use strict';
-
-const http = require('http');
-const EventEmitter = require('events');
-const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-
-// Global variables
-module.exports = class ConnectionManager {
-
-  constructor (settings, logger) {
-    this._screenshareSessions = {};
-
-    this._setupBBB();
-
-    this._emitter = this._setupEventEmitter();
-    this._adapters = [];
-  }
-
-  setHttpServer(httpServer) {
-    this.httpServer = httpServer;
-  }
-
-  listen(callback) {
-    this.httpServer.listen(callback);
-  }
-
-  addAdapter(adapter) {
-    adapter.setEventEmitter(this._emitter);
-    this._adapters.push(adapter);
-  }
-
-  _setupEventEmitter() {
-    let self = this;
-    let emitter = new EventEmitter();
-
-    emitter.on(C.WEBSOCKET_MESSAGE, (data) => {
-      switch (data.type) {
-        case "screenshare":
-          self._bbbGW.publish(JSON.stringify(data), C.TO_SCREENSHARE);
-          break;
-
-        case "video":
-          self._bbbGW.publish(JSON.stringify(data), C.TO_VIDEO);
-          break;
-
-        case "audio":
-          self._bbbGW.publish(JSON.stringify(data), C.TO_AUDIO);
-          break;
-
-        case "default":
-          // TODO handle API error message;
-      }
-    });
-
-    return emitter;
-  }
-
-  async _setupBBB() {
-    this._bbbGW = new BigBlueButtonGW();
-
-    try {
-      const screenshare = await this._bbbGW.addSubscribeChannel(C.FROM_SCREENSHARE);
-      const video = await this._bbbGW.addSubscribeChannel(C.FROM_VIDEO);
-      const audio = await this._bbbGW.addSubscribeChannel(C.FROM_AUDIO);
-
-      const emitFunk = (data) => {
-        this._emitter.emit('response', data);
-      };
-
-      screenshare.on(C.REDIS_MESSAGE, emitFunk);
-      video.on(C.REDIS_MESSAGE, emitFunk);
-
-      audio.on(C.REDIS_MESSAGE, (data) => {
-        this._emitter.emit('response', data);
-      });
-
-      Logger.info('[ConnectionManager] Successfully subscribed to processes redis channels');
-    }
-    catch (err) {
-      Logger.info('[ConnectionManager] ' + err);
-      this._stopAll;
-    }
-  }
-
-  _stopSession(sessionId) {
-  }
-
-  _stopAll() {
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js b/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js
deleted file mode 100644
index 8b49a75f47f5794c9a2d0f8afff13dfd572e0d4c..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js
+++ /dev/null
@@ -1,31 +0,0 @@
-"use strict";
-
-const http = require("http");
-const fs = require("fs");
-const config = require('config');
-const Logger = require('../utils/Logger');
-
-module.exports = class HttpServer {
-
-  constructor() {
-    //const privateKey  = fs.readFileSync('sslcert/server.key', 'utf8');
-    //const certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
-    //const credentials = {key: privateKey, cert: certificate};
-
-    this.port = config.get('clientPort');
-
-    this.server = http.createServer((req,res) => {
-      //
-    });
-  }
-
-  getServerObject() {
-    return this.server;
-  }
-
-  listen(callback) {
-    Logger.info('[HttpServer] Listening in port ' + this.port);
-    this.server.listen(this.port, callback);
-  }
-
-}
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/MessageValidator.js b/labs/bbb-webrtc-sfu/lib/connection-manager/MessageValidator.js
deleted file mode 100644
index 84022e268838c571893d3bf0c2b6f5d092584dbf..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/MessageValidator.js
+++ /dev/null
@@ -1,81 +0,0 @@
-const Joi = require('joi');
-
-let instance = null;
-
-module.exports = class MessageParser {
-  constructor() {
-    if(!instance){
-      instance = this;
-    }
-    return instance;
-  }
-
-  static const schema {
-    startScreenshare: Joi.object().keys({
-      sdpOffer : Joi.string().required(),
-      vh: Joi.number().required(),
-      vw: Joi.number().required()
-    }),
-
-    startVideo: Joi.object().keys({
-      internalMeetingId: joi.string().required(),
-      callerName : Joi.string().required(),
-    }),
-
-    startAudio: Joi.object().keys({
-      internalMeetingId: joi.string().required(),
-      callerName : Joi.string().required(),
-    }),
-
-    playStart: Joi.object().keys({
-    }),
-
-    playStop: Joi.object().keys.({
-    }),
-
-    stop: Joi.object().keys({
-    }),
-
-    onIceCandidate: Joi.object().keys({
-      internalMeetingId: joi.string().required(),
-      candidate: Joi.object().required(),
-    }),
-  }
-
-  static const messageTemplate Joi.object().keys({
-    id: Joi.string().required(),
-    type: joi.string().required(),
-    role: joi.string().required(),
-  })
-
-  static const validateMessage (msg) {
-    let res = Joi.validate(msg, messageTemplate, {allowUnknown: true});
-
-    if (!res.error) {
-      res = Joi.validate(msg, schema[msg.id]);
-    }
-
-    return res;
-  }
-
-  _parse (message) {
-    let parsed = { id: '' };
-
-    try {
-      parsed = JSON.parse(message);
-    } catch (e) {
-      console.error(e);
-    }
-
-    let res = validateMessage(parsed);
-
-    if (res.error) {
-      parsed.validMessage = false;
-      parsed.errors = res.error;
-    } else {
-      parsed.validMessage = true;
-    }
-
-    return parsed;
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
deleted file mode 100644
index b0fbcc3ae7aba66172ce4506ef6966174a87ca41..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
+++ /dev/null
@@ -1,142 +0,0 @@
-'use strict';
-
-const ws = require('ws');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-
-// ID counter
-let connectionIDCounter = 0;
-
-module.exports = class WebsocketConnectionManager {
-  constructor (server, path) {
-    this.wss = new ws.Server({
-      server,
-      path
-    });
-
-    this.webSockets = {};
-
-    this.wss.on('connection', this._onNewConnection.bind(this));
-  }
-
-  setEventEmitter (emitter) {
-    this.emitter = emitter;
-    this.emitter.on('response', this._onServerResponse.bind(this));
-  }
-
-  _onServerResponse (data) {
-    // Here this is the 'ws' instance
-    const connectionId = data? data.connectionId : null;
-    const ws = this.webSockets[connectionId];
-    if (ws) {
-      if (data.id === 'close') {
-        try {
-          ws.close();
-        } catch (err) {
-          Logger.warn('[WebsocketConnectionManager] Error on closing WS for', connectionId,  err)
-        }
-      } else {
-        this.sendMessage(ws, data);
-      }
-    }
-  }
-
-  _onNewConnection (ws) {
-    ws.id = connectionIDCounter++;
-    this.webSockets[ws.id] = ws;
-    Logger.info("[WebsocketConnectionManager] New connection with id [ " + ws.id + " ]");
-
-    ws.on('message', (data) => {
-      this._onMessage(ws, data);
-    });
-
-    ws.on('close', (err) => {
-      this._onClose(ws, err);
-    });
-
-    ws.on('error', (err) => {
-      this._onError(ws, err);
-    });
-  };
-
-  _onMessage (ws, data) {
-    let message = {};
-
-    try {
-      message = JSON.parse(data);
-
-      if (message.id === 'ping') {
-        this.sendMessage(ws, {id: 'pong'});
-        return;
-      }
-
-      message.connectionId = ws.id;
-
-      if (!ws.sessionId) {
-        ws.sessionId = message.voiceBridge;
-      }
-
-      if (!ws.route) {
-        ws.route = message.type;
-      }
-
-      if (!ws.role) {
-        ws.role = message.role;
-      }
-    } catch(e) {
-      Logger.error("  [WebsocketConnectionManager] JSON message parse error " + e);
-      message = {};
-    }
-
-    // Test for empty or invalid JSON
-    if (Object.getOwnPropertyNames(message).length !== 0) {
-      this.emitter.emit(C.WEBSOCKET_MESSAGE, message);
-    }
-  }
-
-  _onError (ws, err) {
-    Logger.debug('[WebsocketConnectionManager] Connection error [' + ws.id + ']', err);
-    let message = {
-      id: 'error',
-      type: ws.route,
-      role: ws.role,
-      voiceBridge: ws.sessionId,
-      connectionId: ws.id
-    }
-
-    this.emitter.emit(C.WEBSOCKET_MESSAGE, message);
-
-    delete this.webSockets[ws.id];
-  }
-
-  _onClose (ws, err) {
-    Logger.info('[WebsocketConnectionManager] Closed connection on [' + ws.id + ']');
-    let message = {
-      id: 'close',
-      type: ws.route,
-      role: ws.role,
-      voiceBridge: ws.sessionId,
-      connectionId: ws.id
-    }
-
-    this.emitter.emit(C.WEBSOCKET_MESSAGE, message);
-
-    delete this.webSockets[ws.id];
-  }
-
-  sendMessage (ws, json) {
-
-    if (ws._closeCode === 1000) {
-      Logger.error("[WebsocketConnectionManager] Websocket closed, not sending");
-      this._onError(ws, "[WebsocketConnectionManager] Error: not opened");
-    }
-
-    return ws.send(JSON.stringify(json), (error) => {
-      if(error) {
-        Logger.error('[WebsocketConnectionManager] Websocket error "' + error + '" on message "' + json.id + '"');
-
-        this._onError(ws, error);
-      }
-    });
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/h264-sdp.js b/labs/bbb-webrtc-sfu/lib/h264-sdp.js
deleted file mode 100644
index e65c0581263d8bc5764dcd0294e4131408661257..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/h264-sdp.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * A module with the sole purpose of removing all non h264 options from an sdpOffer
- *
- * We use this to prevent any transcoding from the Kurento side if Firefox or Chrome offer VP8/VP9 as
- * the default format.
- */
-
-const sdpTransform = require('sdp-transform');
-
-exports.transform = function(sdp, preferredProfile = null) {
-
-  let mediaIndex = 0;
-  let res = sdpTransform.parse(sdp);
-  let validPayloads;
-
-  if (res.media[0].type === 'audio') {
-    // Audio
-    res.media[mediaIndex].rtp = res.media[mediaIndex].rtp.filter(function(elem) {
-      return elem.codec === 'opus';
-    });
-
-    validPayloads = res.media[mediaIndex].rtp.map(function(elem) {
-      return elem.payload;
-    });
-
-    res.media[mediaIndex].fmtp = res.media[mediaIndex].fmtp.filter(function(elem) {
-      return validPayloads.indexOf(elem.payload) >= 0;
-    });
-
-    res.media[mediaIndex].payloads = validPayloads.join(' ');
-
-    mediaIndex += 1;
-  }
-
-  // Video
-  const availablePayloads = res.media[mediaIndex].rtp.map(elem => {
-    return elem.payload;
-  });
-
-  res.media[mediaIndex].rtp = res.media[mediaIndex].rtp.filter(function(elem) {
-    return elem.codec === 'H264';
-  });
-
-  preferProfile(res.media[mediaIndex], preferredProfile);
-
-  validPayloads = res.media[mediaIndex].rtp.map(function(elem) {
-    return elem.payload;
-  });
-
-  res.media[mediaIndex].fmtp = res.media[mediaIndex].fmtp.filter(function(elem) {
-    return validPayloads.indexOf(elem.payload) >= 0;
-  });
-
-  res.media[mediaIndex].rtcpFb = res.media[mediaIndex].rtcpFb.filter(function(elem) {
-    return validPayloads.indexOf(elem.payload) >= 0;
-  });
-
-
-  res.media[mediaIndex].payloads = validPayloads.join(' ');
-
-  return sdpTransform.write(res);
-};
-
-const preferProfile = function (mediaLine, profileToFilter) {
-  if (profileToFilter == null) {
-    return;
-  }
-
-  const profileRegex = /(?:profile\-level\-id\=)([\d\w]*)/i;
-  const validProfilePayloads = mediaLine.fmtp.filter(e => {
-    let profileSpec = profileRegex.exec(e.config);
-    return profileSpec && profileSpec[1] && profileSpec[1] === profileToFilter;
-  }).map(e => e.payload);
-
-  if (validProfilePayloads.length > 0) {
-    mediaLine.rtp = mediaLine.rtp.filter(e => {
-      return validProfilePayloads.includes(e.payload);
-    });
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js b/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js
deleted file mode 100644
index 9717a8807f42736294f5d24330fefad925e24488..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * WIP: the mcs-core lib will be turned into a dependecy sometime in the near
- * future, and it will probably act with a separate process that answers via
- * its own redis channel
- */
-const Logger = require('../../utils/Logger');
-const MCSApiStub = require('./media/MCSApiStub');
-
-process.on('uncaughtException', function (error) {
-  Logger.error("[mcs-core-process] Uncaught exception with error", error.stack);
-});
-
-process.on('disconnect',function() {
-  Logger.info("[mcs-core-process] Parent process exited!");
-  process.kill();
-});
-
-core = new MCSApiStub();
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/freeswitch/AudioHandler.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/freeswitch/AudioHandler.js
deleted file mode 100644
index e5028f2a4b0bd0b2519d8a7af356f09b5c2a5fd7..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/freeswitch/AudioHandler.js
+++ /dev/null
@@ -1,99 +0,0 @@
-'use strict';
-const Logger = require('../../../../utils/Logger');
-const config = require('config');
-const KURENTO_IP = config.get('kurentoIp');
-
-var kmh = function(sdp) {
-  this.endpointSdp = sdp;
-};
-/**
- * @classdesc
- * 	Custom sipjs's MediaHandler to manage media communication between
- * 	Kurento and Freeswitch
- * 	@constructor
- */
-kmh.prototype.AudioHandler = function (session, options ) {
-  this.session = session;
-  this.options = options;
-  this.Kurento;
-  this.sdp = null;
-  this.endpointSdp = null;
-  this.remote_sdp = null;
-  this.version = '0.0.1';
-
-  //Default video configuration
-  this.video = {
-      configuration: {
-          codecId: '96',
-          sendReceive: 'sendrecv',
-          rtpProfile: 'RTP/AVP',
-          codecName: 'H264' ,
-          codecRate: '90000',
-          frameRate: '30.000000'
-      }
-  };
-};
-
-/**
- * Factory method for AudioHandler
- * @param  {Object} session Current session of this media handler
- * @param  {Object} options Options
- * @return {AudioHandler} A AudioHandler
- */
-kmh.prototype.AudioHandler.defaultFactory = function audioDefaultFactory(session, options) {
-  return new kmh.prototype.AudioHandler(session, options);
-};
-
-/**
- * Setup method for this media handler. This method MUST be called before
- * the SIP session starts.
- * @param  {Object} configuration Configuration parameters for the session
- */
-kmh.prototype.AudioHandler.setup = function (sdp, rtp, kurento) {
-    kmh.prototype.AudioHandler.prototype.sendSdp = sdp;
-    kmh.prototype.AudioHandler.prototype.rtp = rtp;
-    kmh.prototype.AudioHandler.prototype.Kurento = kurento;
-
-    Logger.info('[mcs-audio-handler] Setting SDP');
-};
-
-kmh.prototype.AudioHandler.prototype = {
-
-  isReady: function () { return true; },
-
-  close: function () {
-    if (this.timeout) {
-      clearTimeout(this.timeout);
-      delete this.timeout;
-    }
-    delete this.session;
-  },
-
-  render: function(){},
-  mute: function(){},
-  unmute: function(){},
-
-  getDescription: async function (onSuccess, onFailure, mediaHint) {
-    if(this.endpointSdp === null) {
-      Logger.info("[mcs-audio-handler] Processing SDP for Kurento RTP endpoint", this.rtp);
-      this.endpointSdp = await this.Kurento.processOffer(this.rtp, this.remote_sdp);
-      this.endpointSdp = this.endpointSdp.replace(/(IP4\s[0-9.]*)/g, 'IP4 ' + KURENTO_IP);
-    }
-    this.sdp = this.endpointSdp;
-    this.timeout = setTimeout(function () {
-      delete this.timeout;
-      onSuccess(this.sdp);
-  }.bind(this), 0);
-  },
-
-  setDescription: function (description, onSuccess, onFailure) {
-    Logger.debug("  [AudioHandler] Remote SDP: ", description);
-    this.remote_sdp = description;
-    this.timeout = setTimeout(function () {
-      delete this.timeout;
-      onSuccess();
-    }.bind(this), 0);
-  }
-};
-
-module.exports = new kmh();
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/freeswitch/freeswitch.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/freeswitch/freeswitch.js
deleted file mode 100644
index 10f8e5c254f82842aaf81658583e1e5d3dc8332b..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/freeswitch/freeswitch.js
+++ /dev/null
@@ -1,289 +0,0 @@
-'use strict'
-
-const C = require('../../constants/Constants.js');
-const config = require('config');
-const EventEmitter = require('events').EventEmitter;
-const audioHandler = require('./AudioHandler.js');
-const Logger = require('../../../../utils/Logger');
-const SIPJS = require('sip.js');
-const LOCAL_IP_ADDRESS = config.get('localIpAddress');
-const FREESWITCH_IP = config.get('freeswitch').ip;
-const FREESWITCH_PORT = config.get('freeswitch').port;
-const Kurento = require('../kurento/kurento');
-const isError = require('../../utils/util').isError;
-
-let instance = null;
-
-/* Public members */
-module.exports = class Freeswitch extends EventEmitter {
-  constructor(serverUri) {
-    if(!instance){
-      super();
-      this._serverUri = serverUri;
-      this._userAgents = {};
-      this._sessions = {};
-      this._rtpConverters = {};
-      this._Kurento = new Kurento(config.get('kurentoUrl'));
-      this._Kurento.on(C.ERROR.MEDIA_SERVER_OFFLINE, () => {
-        this.emit(C.ERROR.MEDIA_SERVER_OFFLINE);
-      });
-
-      instance = this;
-    }
-
-    return instance;
-  }
-
-  async init () {
-    Logger.debug("[mcs-media] freeswitch init stub");
-    await this._Kurento.init();
-  }
-
-
-  _getMediaServerClient (serverUri) {
-    return new Promise((resolve, reject) =>  {
-    });
-  }
-
-  async createMediaElement (roomId, type, params) {
-    if (this._userAgents[roomId]) {
-      return Promise.resolve(roomId);
-    }
-    try {
-      let userAgent = await this._createUserAgent(type, params.name, roomId);
-      this._userAgents[roomId] = userAgent;
-      return Promise.resolve(roomId);
-    }
-    catch (err) {
-      return Promise.reject(err);
-    }
-  }
-
-  async connect (sourceId, sinkId, type) {
-    let source = this._sessions[sourceId];
-    Logger.debug("[mcs-media-freeswitch] Connecting", this._rtpConverters[sourceId], "to", sinkId);
-
-    if (source) {
-      return new Promise((resolve, reject) => {
-        switch (type) {
-          case 'ALL':
-
-          case 'AUDIO':
-
-          case 'VIDEO':
-            this._Kurento.connect(this._rtpConverters[sourceId], sinkId, type);
-            return resolve();
-            break;
-
-          default: return reject("[mcs-media] Invalid connect type");
-        }
-      });
-    }
-    else {
-      return Promise.reject("[mcs-media] Failed to connect " + type + ": " + sourceId + " to " + sinkId);
-    }
-  }
-
-  stop (roomId, type = {}, elementId) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.info("[mcs-media-freeswitch] Releasing endpoint", elementId, "from room", roomId);
-
-        await this._stopUserAgent(elementId);
-        await this._stopRtpConverter(roomId, elementId);
-        return resolve();
-      }
-      catch (error) {
-        error = this._handleError(error);
-        return reject(error);
-      }
-    });
-  }
-
-  async _stopUserAgent (elementId) {
-    return new Promise(async (resolve, reject) => {
-      Logger.debug("[mcs-media-freeswitch] Releasing userAgent", elementId);
-      let userAgent = this._userAgents[elementId];
-
-      if (userAgent) {
-        Logger.debug("[mcs-media-freeswitch] Stopping user agent", elementId);
-        await userAgent.stop();
-        delete this._userAgents[elementId];
-        return resolve();
-      }
-      else {
-        return resolve();
-      }
-    });
-  }
-
-  async _stopRtpConverter (roomId, elementId) {
-    return new Promise(async (resolve, reject) => {
-      let rtpConverter = this._rtpConverters[elementId];
-      if (rtpConverter) {
-        Logger.debug("[mcs-media-freeswitch] Stopping converter", rtpConverter);
-        await this._Kurento.stop(roomId, C.MEDIA_TYPE.RTP, this._rtpConverters[elementId]);
-        delete this._rtpConverters[elementId];
-        return resolve();
-      }
-      else {
-        return resolve();
-      }
-    });
-  }
-
-  async processOffer (elementId, sdpOffer, params) {
-    let userAgent = this._userAgents[elementId];
-    let rtpEndpoint;
-
-    return new Promise(async (resolve, reject) => {
-      try {
-        if (userAgent) {
-
-          if (this._rtpConverters[elementId]) {
-            rtpEndpoint = this._rtpConverters[elementId];
-          }
-          else {
-            rtpEndpoint = await this._Kurento.createMediaElement(elementId, 'RtpEndpoint');
-            this._rtpConverters[elementId] = rtpEndpoint;
-          }
-
-          Logger.info("[mcs-media-freeswitch] RTP endpoint equivalent to SIP instance is", rtpEndpoint);
-
-          let session = this.sipCall(userAgent,
-              params.name,
-              elementId,
-              FREESWITCH_IP,
-              FREESWITCH_PORT,
-              rtpEndpoint
-              //sdpOffer
-              );
-
-          session.on('accepted', (response, cause) => {
-            this._sessions[elementId] = session;
-            return resolve(session.remote_sdp);
-          });
-
-          session.on('rejected', (response, cause) => {
-            Logger.info("session rejected", response, cause);
-          });
-
-          session.on('failed', (response, cause) => {
-            Logger.info("session failed", response, cause);
-          });
-
-          session.on('progress', (response) => {
-            Logger.info("session progress", response);
-          });
-
-        } else {
-          return reject("[mcs-media] There is no element " + elementId);
-        }
-      }
-      catch (error) {
-        this._handleError(error);
-        reject(error);
-      }
-    });
-  }
-
-  trackMediaState (elementId, type) {
-    let userAgent = this._userAgents[elementId];
-    if (userAgent) {
-      userAgent.on('invite', function(session) {
-        Logger.info("[mcs-media-freeswitch] On UserAgentInvite");
-      });
-
-      userAgent.on('message', function(message) {
-        Logger.info("[mcs-media-freeswitch] On UserAgentMessage", message);
-      });
-
-      userAgent.on('connected', function() {
-        Logger.info("[mcs-media-freeswitch] On UserAgentConnected");
-      });
-
-      userAgent.on('disconnected', function (){
-        Logger.warn("[mcs-media-freeswitch] UserAgent disconnected");
-      });
-
-      return;
-    }
-  }
-
-  _destroyElements() {
-    for (var ua in this._userAgents) {
-      if (this._userAgents.hasOwnProperty(ua)) {
-        delete this._mediaElements[ua];
-      }
-    }
-  }
-
-  _createUserAgent (type, displayName, roomId) {
-    var mediaFactory = audioHandler.AudioHandler.defaultFactory;
-    var newUA = new SIPJS.UA({
-      uri: 'sip:' + C.FREESWITCH.GLOBAL_AUDIO_PREFIX + roomId + '@' + LOCAL_IP_ADDRESS,
-      wsServers: 'ws://' + FREESWITCH_IP + ':' + FREESWITCH_PORT,
-      displayName: displayName,
-      register: false,
-      mediaHandlerFactory: mediaFactory,
-      userAgentString: C.STRING.SIP_USER_AGENT,
-      log: {
-        builtinEnabled: false,
-        level: 3,
-        connector: this.sipjsLogConnector
-      },
-      traceSip: true,
-      hackIpInContact: LOCAL_IP_ADDRESS
-    });
-
-    Logger.info("[mcs-freeswitch-adapter] Created new user agent for endpoint " + displayName);
-
-    return newUA;
-  }
-
-/**
-   * Makes a sip call to a Freeswitch instance
-   * @param {UA} caller's SIP.js User Agent
-   * @param {String} username The user identifier (Kurento Endpoint ID)
-   * @param {String} voiceBridge The voiceBridge we are going to call to
-   * @param {String} host Freeswitch host address
-   * @param {String} port Freeswitch port
-   */
-  sipCall (userAgent, username, voiceBridge, host, port, rtp) {
-    //call options
-    var options = {
-      media: {
-        constraints: {
-          audio: true,
-          video: false
-        },
-      },
-      inviteWithoutSdp: true,
-      params: {
-        from_displayName : username
-      }
-    };
-
-    audioHandler.AudioHandler.setup(null, rtp, this._Kurento);
-
-    var sipUri = new SIPJS.URI('sip', voiceBridge, host, port);
-
-    Logger.info('[mcs-media-freeswitch] Making SIP call to: ' + sipUri + ' from: ' + username);
-
-    return userAgent.invite(sipUri, options);
-  }
-
-  _handleError(error) {
-    // Checking if the error needs to be wrapped into a JS Error instance
-    if (!isError(error)) {
-      error = new Error(error);
-    }
-
-    error.code = C.ERROR.MEDIA_SERVER_ERROR;
-    Logger.error('[mcs-media] Media Server returned error', error);
-  }
-
-  sipjsLogConnector (level, category, label, content) {
-    Logger.debug('[SIP.js]  ' + content);
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/kurento/errors.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/kurento/errors.js
deleted file mode 100644
index b96dea1954dbeb353dfad15f831679d2b8185769..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/kurento/errors.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Adapted translation of https""://github.com/Kurento/kms-core/blob/master/src/server/interface/KurentoException.hpp
-
-const C = require('../../constants/Constants');
-
-module.exports = {
-  /* GENERIC MEDIA ERRORS */
-  40001:  { type: "MARSHALL_ERROR", error: C.ERROR.MEDIA_SERVER_GENERIC_ERROR },
-  40003:  { type: "UNEXPECTED_ERROR", error: C.ERROR.MEDIA_SERVER_GENERIC_ERROR },
-  40004:  { type: "CONNECT_ERROR", error: C.ERROR.MEDIA_CONNECT_ERROR },
-  40005:  { type: "UNSUPPORTED_MEDIA_TYPE",  error: C.ERROR.MEDIA_INVALID_TYPE },
-  40006:  { type: "NOT_IMPLEMENTED" , error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40007:  { type: "INVALID_SESSION", error: C.ERROR.CONNECTION_ERROR },
-  40008:  { type: "MALFORMED_TRANSACTION", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40009:  { type: "NOT_ENOUGH_RESOURCES", error: C.ERROR.MEDIA_SERVER_NO_RESOURCES },
-
-  /* MediaObject ERRORS */
-  40100:  { type: "MEDIA_OBJECT_TYPE_NOT_FOUND", error: C.ERROR.MEDIA_INVALID_TYPE },
-  40101:  { type: "MEDIA_OBJECT_NOT_FOUND", error: C.ERROR.MEDIA_NOT_FOUND },
-  40104:  { type: "MEDIA_OBJECT_CONSTRUCTOR_NOT_FOUND", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40105:  { type: "MEDIA_OBJECT_METHOD_NOT_FOUND", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40106:  { type: "MEDIA_OBJECT_EVENT_NOT_SUPPORTED", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40107:  { type: "MEDIA_OBJECT_ILLEGAL_PARAM_ERROR", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40108:  { type: "MEDIA_OBJECT_NOT_AVAILABLE", error: C.ERROR.MEDIA_NOT_FOUND },
-  40109:  { type: "MEDIA_OBJECT_NOT_FOUND_TRANSACTION_NO_COMMIT", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40110:  { type: "MEDIA_OBJECT_TAG_KEY_NOT_FOUND", error: C.ERROR.MEDIA_INVALID_OPERATION },
-  40111:  { type: "MEDIA_OBJECT_OPERATION_NOT_SUPPORTED", error: C.ERROR.MEDIA_INVALID_OPERATION },
-
-  /* SDP ERRORS */
-  40200:  { type: "SDP_CREATE_ERROR", error: C.ERROR.MEDIA_GENERIC_ERROR },
-  40201:  { type: "SDP_PARSE_ERROR", error: C.ERROR.MEDIA_INVALID_SDP },
-  40202:  { type: "SDP_END_POINT_NO_LOCAL_SDP_ERROR", error: C.ERROR.MEDIA_INVALID_SDP },
-  40203:  { type: "SDP_END_POINT_NO_REMOTE_SDP_ERROR", error: C.ERROR.MEDIA_INVALID_SDP },
-  40204:  { type: "SDP_END_POINT_GENERATE_OFFER_ERROR", error: C.ERROR.MEDIA_GENERATE_OFFER_FAILED },
-  40205:  { type: "SDP_END_POINT_PROCESS_OFFER_ERROR" , error: C.ERROR.MEDIA_PROCESS_OFFER_FAILED },
-  40206:  { type: "SDP_END_POINT_PROCESS_ANSWER_ERROR", error: C.ERROR.MEDIA_PROCESS_ANSWER_FAILED },
-  40207:  { type: "SDP_CONFIGURATION_ERROR", error: C.ERROR.MEDIA_GENERIC_ERROR },
-  40208:  { type: "SDP_END_POINT_ALREADY_NEGOTIATED", error: C.ERROR.MEDIA_PROCESS_OFFER_FAILED },
-  40209:  { type: "SDP_END_POINT_NOT_OFFER_GENERATED", error: C.ERROR.MEDIA_GENERATE_OFFER_FAILED },
-  40210:  { type: "SDP_END_POINT_ANSWER_ALREADY_PROCCESED", error: C.ERROR.MEDIA_PROCESS_ANSWER_FAILED },
-  40211:  { type: "SDP_END_POINT_CANNOT_CREATE_SESSON", error: C.ERROR.MEDIA_GENERIC_ERROR },
-
-  /* HTTP ERRORS */
-  40300:  { type: "HTTP_END_POINT_REGISTRATION_ERROR" },
-
-  /* ICE ERRORS */
-  40400:  { type: "ICE_GATHER_CANDIDATES_ERROR", error: C.ERROR.ICE_GATHERING_FAILED },
-  40401:  { type: "ICE_ADD_CANDIDATE_ERROR", error: C.ERROR.ICE_CANDIDATE_FAILED },
-
-  /* SERVER MANAGER ERRORS */
-  40500:  { type: "SERVER_MANAGER_ERROR_KMD_NOT_FOUND", error: C.ERROR.MEDIA_SERVER_GENERIC_ERROR },
-
-  /* URI ERRORS */
-  40600:  { type: "URI_ERROR_MIN" },
-  40699:  { type: "URI_ERROR_MAX" },
-  40600:  { type: "URI_PATH_FILE_NOT_FOUND", error: C.ERROR.MEDIA_INVALID_OPERATION },
-
-  /* PLAYER ERRORS */
-  40700:  { type: "PLAYER_ERROR_MIN" },
-  40799:  { type: "PLAYER_ERROR_MAX" },
-  40700:  { type: "PLAYER_SEEK_FAIL", error: C.ERROR.MEDIA_GENERIC_ERROR },
-};
-
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/kurento/kurento.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/kurento/kurento.js
deleted file mode 100644
index d4ca0bf9708db30ba8b7949877c5bd6dfddf725f..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/adapters/kurento/kurento.js
+++ /dev/null
@@ -1,640 +0,0 @@
-'use strict'
-
-const C = require('../../constants/Constants.js');
-const config = require('config');
-const mediaServerClient = require('kurento-client');
-const EventEmitter = require('events').EventEmitter;
-const Logger = require('../../../../utils/Logger');
-const isError = require('../../utils/util').isError;
-const ERRORS = require('./errors.js');
-const KURENTO_WEBSOCKET_POOL_SIZE = config.get('kurento-websocket-pool-size');
-
-let instance = null;
-
-module.exports = class MediaServer extends EventEmitter {
-  constructor(serverUri, globalEmitter) {
-    if (!instance){
-      super();
-      this._serverUri = serverUri;
-      this._globalEmitter = globalEmitter;
-      this._mediaPipelines = {};
-      this._mediaElements = {};
-      this._mediaServers;
-      this._status = C.STATUS.STOPPED;
-      this._reconnectionRoutine = null;
-      instance = this;
-    }
-
-    return instance;
-  }
-
-  init () {
-    return new Promise(async (resolve, reject) => {
-      try {
-        if (this._mediaServers == null || this._mediaServers.length === 0) {
-          this._mediaServers = [];
-          for (var i = 0; i < KURENTO_WEBSOCKET_POOL_SIZE; i++) {
-            let client = await this._getMediaServerClient(this._serverUri);
-            this._mediaServers.push(client);
-          }
-          this._globalEmitter.on(C.EVENT.ROOM_EMPTY, this._releasePipeline.bind(this));
-          Logger.info("[mcs-media] Retrieved", this._mediaServers.length, "media server clients");
-          this._status = C.STATUS.STARTING;
-          this._monitorConnectionState();
-          return resolve();
-        }
-        resolve();
-      }
-      catch (error) {
-        this.emit(C.ERROR.MEDIA_SERVER_OFFLINE);
-        reject(this._handleError(error));
-      }
-    });
-  }
-
-  _getMediaServerClient (serverUri) {
-    return new Promise((resolve, reject) =>  {
-      mediaServerClient(serverUri, {failAfter: 1}, (error, client) => {
-        if (error) {
-          return reject(this._handleError(error));
-        }
-        resolve(client);
-      });
-    });
-  }
-
-  _monitorConnectionState () {
-    try {
-      if (this._mediaServers) {
-        Logger.debug('[mcs-media] Monitoring connection state');
-        this._mediaServers.forEach(ms => {
-          ms.on('disconnect', this._onDisconnection.bind(this));
-          ms.on('reconnected',this._onReconnection.bind(this));
-        });
-       }
-    }
-    catch (err) {
-      this._handleError(err);
-    }
-  }
-
-  _onDisconnection () {
-    if (this._status !== C.STATUS.STOPPED) {
-      Logger.error('[mcs-media] Media server was disconnected for some reason, will have to clean up all elements and notify users');
-      this._status = C.STATUS.STOPPED;
-      this._destroyElements();
-      this._destroyMediaServer();
-      this.emit(C.ERROR.MEDIA_SERVER_OFFLINE);
-      this._reconnectToServer();
-    }
-  }
-
-  _onReconnection (sameSession) {
-    if (!sameSession) {
-      if (this._status !== C.STATUS.STOPPED) {
-        this._status = C.STATUS.RESTARTING;
-        this._destroyElements();
-        this._destroyMediaServer();
-        this.emit(C.ERROR.MEDIA_SERVER_OFFLINE);
-      }
-
-      this._status = C.STATUS.STARTED;
-      Logger.info('[mcs-media] Media server is back online');
-      this.emit(C.EVENT.MEDIA_SERVER_ONLINE);
-    }
-  }
-
-  _reconnectToServer () {
-    if (this._reconnectionRoutine == null && this._status !== C.STATUS.RESTARTING) {
-      this._status = C.STATUS.RESTARTING;
-      this._reconnectionRoutine = setInterval(async () => {
-        try {
-          for (var i = 0; i < KURENTO_WEBSOCKET_POOL_SIZE; i++) {
-            let client = await this._getMediaServerClient(this._serverUri);
-            this._mediaServers.push(client);
-          }
-          Logger.info("[mcs-media] Retrieved", this._mediaServers.length, "media server clients");
-          this._monitorConnectionState();
-          clearInterval(this._reconnectionRoutine);
-          this._reconnectionRoutine = null;
-          Logger.warn("[mcs-media] Reconnection to media server succeeded");
-        }
-        catch (error) {
-          this._mediaServers = [];
-        }
-      }, 2000);
-    }
-  }
-
-  _getClientFromPool () {
-    // Round robin the pool
-    let client = this._mediaServers.shift();
-    this._mediaServers.push(client);
-    return client;
-  }
-
-  _getMediaPipeline (roomId) {
-    return new Promise((resolve, reject) => {
-      try {
-        let mediaServer = this._getClientFromPool();
-        if (this._mediaPipelines[roomId]) {
-          mediaServer.getMediaobjectById(this._mediaPipelines[roomId].id, (error, pipeline) => {
-            if (error) {
-              return reject(this._handleError(error));
-            }
-            Logger.warn('[mcs-media] Pipeline for', roomId, 'already exists.', pipeline.id);
-            return resolve(pipeline);
-          });
-        } else {
-          mediaServer.create('MediaPipeline', (error, pipeline) => {
-            if (error) {
-              return reject(this._handleError(error));
-            }
-            this._mediaPipelines[roomId] = pipeline;
-            pipeline.activeElements = {};
-            resolve(pipeline);
-          });
-        }
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  _releasePipeline (room) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.debug("[mcs-media] Releasing room", room, "pipeline");
-        const pipeline = this._mediaPipelines[room];
-        if (pipeline && typeof pipeline.release === 'function') {
-          pipeline.release((error) => {
-            if (error) {
-              return reject(this._handleError(error));
-            }
-            Logger.debug("[mcs-media] Pipeline", pipeline.id, "released");
-            delete this._mediaPipelines[room];
-            return resolve()
-          });
-        }
-      }
-      catch (error) {
-        return reject(this._handleError(error));
-      }
-    });
-  }
-
-  _createElement (pipeline, type, options) {
-    return new Promise((resolve, reject) => {
-      try {
-        pipeline.create(type, options, (error, mediaElement) => {
-          if (error) {
-            return reject(this._handleError(error));
-          }
-          Logger.info("[mcs-media] Created [" + type + "] media element: " + mediaElement.id);
-          this._mediaElements[mediaElement.id] = mediaElement;
-          return resolve(mediaElement);
-        });
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  createMediaElement (roomId, type, options = {}) {
-    options = options || {};
-    return new Promise(async (resolve, reject) => {
-      try {
-        const pipeline = await this._getMediaPipeline(roomId);
-        const mediaElement = await this._createElement(pipeline, type, options);
-        if (typeof mediaElement.setKeyframeInterval === 'function' && options.keyframeInterval) {
-          Logger.debug("[mcs-media] Creating element with keyframe interval set to", options.keyframeInterval);
-          mediaElement.setKeyframeInterval(options.keyframeInterval);
-        }
-        this._mediaPipelines[roomId].activeElements[mediaElement.id] = mediaElement.id;
-        resolve(mediaElement.id);
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  _getMediaElement (elementId) {
-    return new Promise((resolve, reject) => {
-      try {
-        let mediaServer = this._getClientFromPool();
-        if (this._mediaElements[elementId]) {
-          mediaServer.getMediaobjectById(elementId, (error, element) => {
-            if (error || element == null) {
-              return reject(this._handleError(error));
-            }
-            Logger.trace('[mcs-media] Element', elementId, 'found');
-            return resolve(element);
-          });
-        } else {
-          return reject(this._handleError(ERRORS[40101]));
-        }
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  async startRecording (sourceId) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const source = await this._getMediaElement(sourceId);
-        source.record((err) => {
-          if (err) {
-            return reject(this._handleError(err));
-          }
-          return resolve();
-        });
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  async _stopRecording (sourceId) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const source = await this._getMediaElement(sourceId);
-        source.stopAndWait((err) => {
-          if (err) {
-            return reject(this._handleError(err));
-          }
-          return resolve();
-        });
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  async connect (sourceId, sinkId, type) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const source = await this._getMediaElement(sourceId);
-        const sink = await this._getMediaElement(sinkId);
-
-        switch (type) {
-          case 'ALL':
-            source.connect(sink, (error) => {
-              if (error) {
-                return reject(this._handleError(error));
-              }
-              return resolve();
-            });
-            break;
-
-
-          case 'AUDIO':
-            source.connect(sink, 'AUDIO', (error) => {
-              if (error) {
-                return reject(this._handleError(error));
-              }
-              return resolve();
-            });
-
-          case 'VIDEO':
-            source.connect(sink, (error) => {
-              if (error) {
-                return reject(this._handleError(error));
-              }
-              return resolve();
-            });
-            break;
-
-          default:
-            return reject(this._handleError(ERRORS[40107]));
-        }
-      }
-      catch (error) {
-        return reject(this._handleError(error));
-      }
-    });
-  }
-
-  async disconnect (sourceId, sinkId, type) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const source = await this._getMediaElement(sourceId);
-        const sink = await this._getMediaElement(sinkId);
-
-        switch (type) {
-          case 'ALL':
-            source.disconnect(sink, (error) => {
-              if (error) {
-                return reject(this._handleError(error));
-              }
-              return resolve();
-            });
-            break;
-
-          case 'AUDIO':
-            source.disconnect(sink, 'AUDIO', (error) => {
-              if (error) {
-                return reject(this._handleError(error));
-              }
-              return resolve();
-            });
-
-          case 'VIDEO':
-            source.disconnect(sink, (error) => {
-              if (error) {
-                return reject(this._handleError(error));
-              }
-              return resolve();
-            });
-            break;
-
-          default:
-            return reject(this._handleError(ERRORS[40107]));
-        }
-      }
-      catch (error) {
-        return reject(this._handleError(error));
-      }
-    });
-  }
-
-  stop (room, type, elementId) {
-    const pipeline = this._mediaPipelines[room];
-    const cleanPipeline = async (p) => {
-      if (p) {
-        if (p.activeElements[elementId]) {
-          delete p.activeElements[elementId];
-        }
-
-        const activeElements = Object.keys(p.activeElements).length;
-
-        Logger.info("[mcs-media] Pipeline has a total of", activeElements, "active elements");
-        if (activeElements <= 0) {
-          await this._releasePipeline(room);
-        }
-      }
-    }
-
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.info("[mcs-media] Releasing endpoint", elementId, "from room", room);
-        const mediaElement = await this._getMediaElement(elementId);
-
-        if (type === 'RecorderEndpoint') {
-          await this._stopRecording(elementId);
-        }
-
-        if (mediaElement && typeof mediaElement.release === 'function') {
-          mediaElement.release(async (error) => {
-            if (error) {
-              return reject(this._handleError(error));
-            }
-            delete this._mediaElements[elementId];
-
-            cleanPipeline(pipeline);
-
-            return resolve();
-          });
-        }
-        else {
-          Logger.warn("[mcs-media] Media element", elementId, "could not be found to stop");
-
-          cleanPipeline(pipeline);
-
-          return resolve();
-        }
-      }
-      catch (err) {
-        cleanPipeline(pipeline);
-        this._handleError(err);
-        resolve();
-      }
-    });
-  }
-
-  addIceCandidate (elementId, candidate) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const mediaElement = await this._getMediaElement(elementId);
-
-        if (mediaElement  && candidate) {
-          mediaElement.addIceCandidate(candidate, (error) => {
-            if (error) {
-              return reject(this._handleError(error));
-            }
-            Logger.debug("[mcs-media] Added ICE candidate for => " + elementId);
-            return resolve();
-          });
-        }
-        else {
-          return reject(this._handleError(ERRORS[40101]));
-        }
-      }
-      catch (error) {
-        return reject(this._handleError(error));
-      }
-    });
-  }
-
-  gatherCandidates (elementId) {
-    Logger.info('[mcs-media] Gathering ICE candidates for ' + elementId);
-
-    return new Promise(async (resolve, reject) => {
-      try {
-        const mediaElement = await this._getMediaElement(elementId);
-        mediaElement.gatherCandidates((error) => {
-          if (error) {
-            return reject(this._handleError(error));
-          }
-          Logger.info('[mcs-media] Triggered ICE gathering for ' + elementId);
-          return resolve();
-        });
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  setInputBandwidth (elementId, min, max) {
-    let mediaElement = this._mediaElements[elementId];
-
-    if (mediaElement) {
-      mediaElement.setMinVideoRecvBandwidth(min);
-      mediaElement.setMaxVideoRecvBandwidth(max);
-    } else {
-      return ("[mcs-media] There is no element " + elementId);
-    }
-  }
-
-  setOutputBandwidth (elementId, min, max) {
-    let mediaElement = this._mediaElements[elementId];
-
-    if (mediaElement) {
-      mediaElement.setMinVideoSendBandwidth(min);
-      mediaElement.setMaxVideoSendBandwidth(max);
-    } else {
-      return ("[mcs-media] There is no element " + elementId );
-    }
-  }
-
-  setOutputBitrate (elementId, min, max) {
-    let mediaElement = this._mediaElements[elementId];
-
-    if (mediaElement) {
-      mediaElement.setMinOutputBitrate(min);
-      mediaElement.setMaxOutputBitrate(max);
-    } else {
-      return ("[mcs-media] There is no element " + elementId);
-    }
-  }
-
-  processOffer (elementId, sdpOffer) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const mediaElement = await this._getMediaElement(elementId);
-
-        if (mediaElement) {
-          mediaElement.processOffer(sdpOffer, (error, answer) => {
-            if (error) {
-              return reject(this._handleError(error));
-            }
-            return resolve(answer);
-          });
-        }
-        else {
-          return reject(this._handleError(ERRORS[40101]));
-        }
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  trackMediaState (elementId, type) {
-    switch (type) {
-      case C.MEDIA_TYPE.URI:
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.ENDOFSTREAM, elementId);
-    // TODO event type validator
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.CHANGED, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_IN, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_OUT, elementId);
-        break;
-
-      case C.MEDIA_TYPE.WEBRTC:
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.CHANGED, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_IN, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_OUT, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.ICE, elementId);
-        break;
-
-    // TODO event type validator
-      case C.MEDIA_TYPE.RTP:
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.CHANGED, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_IN, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_OUT, elementId);
-        break;
-
-      case C.MEDIA_TYPE.RECORDING:
-        this.addMediaEventListener(C.EVENT.RECORDING.STOPPED, elementId);
-        this.addMediaEventListener(C.EVENT.RECORDING.PAUSED, elementId);
-        this.addMediaEventListener(C.EVENT.RECORDING.STARTED. elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_IN, elementId);
-        this.addMediaEventListener(C.EVENT.MEDIA_STATE.FLOW_OUT, elementId);
-        break;
-
-      default: return;
-    }
-    return;
-  }
-
-  addMediaEventListener (eventTag, elementId) {
-    const mediaElement = this._mediaElements[elementId];
-    try {
-      if (mediaElement) {
-        Logger.debug('[mcs-media] Adding media state listener [' + eventTag + '] for ' + elementId);
-        mediaElement.on(eventTag, (event) => {
-          if (eventTag === C.EVENT.MEDIA_STATE.ICE) {
-            event.candidate = mediaServerClient.getComplexType('IceCandidate')(event.candidate);
-          }
-          this.emit(C.EVENT.MEDIA_STATE.MEDIA_EVENT+elementId , {eventTag, event});
-        });
-      }
-    }
-    catch (err) {
-      err = this._handleError(err);
-    }
-  }
-
-  notifyMediaState (elementId, eventTag, event) {
-    this.emit(C.MEDIA_STATE.MEDIA_EVENT , {elementId, eventTag, event});
-  }
-
-  _destroyElements () {
-    for (var pipeline in this._mediaPipelines) {
-      if (this._mediaPipelines.hasOwnProperty(pipeline)) {
-        delete this._mediaPipelines[pipeline];
-      }
-    }
-
-    for (var element in this._mediaElements) {
-      if (this._mediaElements.hasOwnProperty(element)) {
-        delete this._mediaElements[element];
-      }
-    }
-  }
-
-  _destroyMediaServer() {
-    delete this._mediaServer;
-  }
-
-  _handleError(err) {
-    let { message: oldMessage , code, stack } = err;
-    let message;
-
-    if (code && code >= C.ERROR.MIN_CODE && code <= C.ERROR.MAX_CODE) {
-      return err;
-    }
-
-    const error = ERRORS[code]? ERRORS[code].error : null;
-
-    if (error == null) {
-      switch (oldMessage) {
-        case "Request has timed out":
-          ({ code, message }  = C.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT);
-        break;
-
-        case "Connection error":
-          ({ code, message } = C.ERROR.CONNECTION_ERROR);
-        break;
-
-        default:
-          ({ code, message } = C.ERROR.MEDIA_SERVER_GENERIC_ERROR);
-      }
-    }
-    else {
-      ({ code, message } = error);
-    }
-
-    // Checking if the error needs to be wrapped into a JS Error instance
-    if (!isError(err)) {
-      err = new Error(message);
-    }
-
-    err.code = code;
-    err.message = message;
-    err.details = oldMessage;
-    err.stack = stack
-
-    Logger.debug('[mcs-media] Media Server returned an', err.code, err.message);
-    Logger.trace(err.stack);
-    return err;
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js
deleted file mode 100644
index 532fce7301653cc5a9dc7a64d3cbb312f33b69a2..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @classdesc
- * Message constants for the communication with BigBlueButton
- * @constructor
- */
-
-'use strict'
-
-exports.ALL = 'ALL'
-
-exports.STATUS = {}
-exports.STATUS.STARTED = "STARTED"
-exports.STATUS.STOPPED = "STOPPED"
-exports.STATUS.RUNNING = "RUNNING'"
-exports.STATUS.STARTING = "STARTING"
-exports.STATUS.STOPPING = "STOPPING"
-exports.STATUS.RESTARTING = "RESTARTING"
-
-exports.USERS = {}
-exports.USERS.SFU = "SFU"
-exports.USERS.MCU = "MCU"
-
-exports.MEDIA_TYPE = {}
-exports.MEDIA_TYPE.WEBRTC = "WebRtcEndpoint"
-exports.MEDIA_TYPE.RTP= "RtpEndpoint"
-exports.MEDIA_TYPE.URI = "PlayerEndpoint"
-exports.MEDIA_TYPE.RECORDING = "RecorderEndpoint";
-
-// Media server state changes
-exports.EVENT = {}
-exports.EVENT.MEDIA_SERVER_ONLINE = "MediaServerOnline"
-exports.EVENT.NEW_MEDIA_SESSION = "NewMediaSession"
-exports.EVENT.MEDIA_SESSION_STOPPED = "MediaSessionStopped"
-exports.EVENT.MEDIA_STATE = {};
-exports.EVENT.MEDIA_STATE.MEDIA_EVENT = "MediaEvent"
-exports.EVENT.MEDIA_STATE.CHANGED = "MediaStateChanged"
-exports.EVENT.MEDIA_STATE.FLOW_OUT = "MediaFlowOutStateChange"
-exports.EVENT.MEDIA_STATE.FLOW_IN = "MediaFlowInStateChange"
-exports.EVENT.MEDIA_STATE.ENDOFSTREAM = "EndOfStream"
-exports.EVENT.MEDIA_STATE.ICE = "OnIceCandidate"
-exports.EVENT.SERVER_STATE = "ServerState"
-exports.EVENT.ROOM_EMPTY = "RoomEmpty"
-
-exports.EVENT.RECORDING = {};
-exports.EVENT.RECORDING.STOPPED = 'Stopped';
-exports.EVENT.RECORDING.STARTED = 'Started';
-exports.EVENT.RECORDING.PAUSED = 'Paused';
-
-// Error codes
-exports.ERROR = {};
-exports.ERROR.MIN_CODE = 2000;
-exports.ERROR.MAX_CODE = 2999;
-exports.ERROR.CONNECTION_ERROR = { code: 2000, message: "MEDIA_SERVER_CONNECTION_ERROR" };
-exports.ERROR.MEDIA_SERVER_OFFLINE = { code: 2001, message: "MEDIA_SERVER_OFFLINE" };
-exports.ERROR.MEDIA_SERVER_NO_RESOURCES = { code: 2002, message: "MEDIA_SERVER_NO_RESOURCES" };
-exports.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT = { code: 2003, message: "MEDIA_SERVER_REQUEST_TIMEOUT" };
-exports.ERROR.MEDIA_SERVER_GENERIC_ERROR = { code: 2019, message: "MEDIA_SERVER_GENERIC_ERROR" };
-exports.ERROR.ICE_CANDIDATE_FAILED = { code: 2020, message: "ICE_ADD_CANDIDATE_FAILED" };
-exports.ERROR.ICE_GATHERING_FAILED = { code: 2021, message: "ICE_GATHERING_FAILED" };
-exports.ERROR.ICE_STATE_FAILED = { code: 2022, message: "ICE_STATE_FAILED" };
-
-exports.ERROR.ROOM_GENERIC_ERROR = { code: 2100, message: "ROOM_GENNERIC_ERROR" };
-exports.ERROR.ROOM_NOT_FOUND = { code: 2101, message: "ROOM_NOT_FOUND" };
-exports.ERROR.USER_GENERIC_ERROR = { code: 2110, message: "USER_GENERIC_ERROR" };
-exports.ERROR.USER_NOT_FOUND = { code: 2111, message: "USER_NOT_FOUND" };
-
-exports.ERROR.MEDIA_GENERIC_ERROR = { code: 2200, message: "MEDIA_GENERIC_ERROR" };
-exports.ERROR.MEDIA_NOT_FOUND = { code: 2201, message: "MEDIA_NOT_FOUND" };
-exports.ERROR.MEDIA_INVALID_SDP = { code: 2202, message: "MEDIA_INVALID_SDP" };
-exports.ERROR.MEDIA_NO_AVAILABLE_CODEC = { code: 2203, message: "MEDIA_NO_AVAILABLE_CODEC" };
-exports.ERROR.MEDIA_INVALID_TYPE = { code: 2204, message: "MEDIA_INVALID_TYPE" };
-exports.ERROR.MEDIA_INVALID_OPERATION = { code: 2205, message: "MEDIA_INVALID_OPERATION" };
-exports.ERROR.MEDIA_PROCESS_OFFER_FAILED = { code: 2206, message : "MEDIA_PROCESS_OFFER_FAILED" };
-exports.ERROR.MEDIA_PROCESS_ANSWER_FAILED = { code: 2207, message : "MEDIA_PROCESS_ANSWER_FAILED" };
-exports.ERROR.MEDIA_GENERIC_PROCESS_ERROR = { code: 2208, message: "MEDIA_GENERIC_PROCESS_ERROR" };
-exports.ERROR.MEDIA_ADAPTER_OBJECT_NOT_FOUND = { code: 2209, message: "MEDIA_ADAPTER_OBJECT_NOT_FOUND" };
-exports.ERROR.MEDIA_CONNECT_ERROR = { code: 2210, message: "MEDIA_CONNECT_ERROR" };
-
-
-// Freeswitch Adapter
-exports.FREESWITCH = {};
-exports.FREESWITCH.GLOBAL_AUDIO_PREFIX = "GLOBAL_AUDIO_";
-
-// RTP params
-exports.SDP = {};
-exports.SDP.PARAMS = "params"
-exports.SDP.MEDIA_DESCRIPTION = "media_description"
-exports.SDP.LOCAL_IP_ADDRESS = "local_ip_address"
-exports.SDP.LOCAL_VIDEO_PORT = "local_video_port"
-exports.SDP.DESTINATION_IP_ADDRESS = "destination_ip_address"
-exports.SDP.DESTINATION_VIDEO_PORT = "destination_video_port"
-exports.SDP.REMOTE_VIDEO_PORT = "remote_video_port"
-exports.SDP.CODEC_NAME = "codec_name"
-exports.SDP.CODEC_ID = "codec_id"
-exports.SDP.CODEC_RATE = "codec_rate"
-exports.SDP.RTP_PROFILE = "rtp_profile"
-exports.SDP.SEND_RECEIVE = "send_receive"
-exports.SDP.FRAME_RATE = "frame_rate"
-
-// Strings
-exports.STRING = {}
-exports.STRING.KURENTO = "Kurento"
-exports.STRING.FREESWITCH = "Freeswitch"
-exports.STRING.USER_AGENT = "MediaController"
-exports.STRING.DEFAULT_NAME = "default"
-exports.STRING.SIP_USER_AGENT = "SIP.js 0.7.8"
-exports.STRING.ANONYMOUS = "ANONYMOUS"
-exports.STRING.FS_USER_AGENT_STRING = "Freeswitch_User_Agent"
-exports.STRING.XML_MEDIA_FAST_UPDATE = '<?xml version=\"1.0\" encoding=\"utf-8\" ?>' +
-                                          '<media_control>' +
-                                            '<vc_primitive>' +
-                                              '<to_encoder>' +
-                                                '<picture_fast_update>' +
-                                                '</picture_fast_update>' +
-                                              '</to_encoder>' +
-                                            '</vc_primitive>' +
-                                          '</media_control>'
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js
deleted file mode 100644
index 1c3d5befeadcb0279532a83dc08e27d4b960d227..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js
+++ /dev/null
@@ -1,170 +0,0 @@
-'use strict'
-
-const config = require('config');
-const C = require('../constants/Constants');
-const util = require('util');
-const EventEmitter = require('events').EventEmitter;
-const MediaController = require('./MediaController.js');
-const Logger = require('../../../utils/Logger');
-
-let instance = null;
-
-module.exports = class MCSApiStub extends EventEmitter {
-  constructor() {
-    if(!instance) {
-      super();
-      this.emitter = this;
-      this._mediaController = new MediaController(this.emitter);
-      instance = this;
-    }
-
-    return instance;
-  }
-
-  async join (room, type, params) {
-    try {
-      const answer = await this._mediaController.join(room, type, params);
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'join', { room, type, params}));
-    }
-  }
-
-  async leave (room, user) {
-    try {
-      const answer = await this._mediaController.leave(room, user);
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'leave', { room, user }));
-    }
-  }
-
-  async publishnsubscribe (user, sourceId, sdp, params) {
-    try {
-      const answer = await this._mediaController.publishnsubscribe(user, sourceId, sdp, params);
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'publishnsubscribe', { user, sourceId, sdp, params }));
-    }
-  }
-
-  async publish (user, room,  type, params) {
-    try {
-      const answer = await this._mediaController.publish(user, room, type, params);
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'publish', { user, room, type, params }));
-    }
-  }
-
-  async unpublish (user, mediaId) {
-    try {
-      await this._mediaController.unpublish(mediaId);
-      return ;
-    }
-    catch (error) {
-      throw (this._handleError(error, 'unpublish', { user, mediaId }));
-    }
-  }
-
-  async subscribe (user, sourceId, type, params) {
-    try {
-      const answer = await this._mediaController.subscribe(user, sourceId, type, params);
-
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'subscribe', { user, sourceId, type, params }));
-    }
-  }
-
-  async unsubscribe (user, mediaId) {
-    try {
-      await this._mediaController.unsubscribe(user, mediaId);
-      return ;
-    }
-    catch (error) {
-      throw (this._handleError(error, 'unsubscribe', { user, mediaId }));
-    }
-  }
-
-  async startRecording(userId, mediaId, recordingPath) {
-    try {
-      const answer = await this._mediaController.startRecording(userId, mediaId, recordingPath);
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'startRecording', { userId, mediaId, recordingPath}));
-    }
-  }
-
-  async stopRecording(userId, sourceId, recId) {
-    try {
-      let answer = await this._mediaController.stopRecording(userId, sourceId, recId);
-      return (answer);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'stopRecording', { userId, sourceId, recId }));
-    }
-  }
-
-  async connect (source, sink, type) {
-    try {
-      await this._mediaController.connect(source, sink, type);
-      return ;
-    }
-    catch (error) {
-      throw (this._handleError(error, 'connect', { source, sink, type }));
-    }
-  }
-
-  async disconnect (source, sink, type) {
-    try {
-      await this._mediaController.disconnect(source, sink, type);
-      return ;
-    }
-    catch (error) {
-      throw (this._handleError(error, 'disconnect', { source, sink, type }));
-    }
-  }
-
-  async onEvent (eventName, mediaId) {
-    try {
-      const eventTag = this._mediaController.onEvent(eventName, mediaId);
-      this._mediaController.on(eventTag, (event) => {
-        this.emitter.emit(eventTag, event);
-      });
-
-      return (eventTag);
-    }
-    catch (error) {
-      throw (this._handleError(error, 'onEvent', { eventName, mediaId }));
-    }
-  }
-
-  async addIceCandidate (mediaId, candidate) {
-    try {
-      await this._mediaController.addIceCandidate(mediaId, candidate);
-      return ;
-    }
-    catch (error) {
-      throw (this._handleError(error, 'addIceCandidate', { mediaId, candidate }));
-    }
-  }
-
-  setStrategy (strategy) {
-    // TODO
-  }
-
-  _handleError (error, operation, params) {
-    const { code, message, details } = error;
-    const response = { type: 'error', code, message, details, operation, params };
-    Logger.error("[mcs-api] Reject operation", response.operation, "with", { error: response });
-
-    return response;
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js
deleted file mode 100644
index 8a8328a06615130d901f052fd20509187fb2f9d7..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js
+++ /dev/null
@@ -1,364 +0,0 @@
-'use strict'
-
-const config = require('config');
-const C = require('../constants/Constants');
-const Logger = require('../../../utils/Logger');
-// Model
-const SfuUser = require('../model/SfuUser');
-const Room = require('../model/Room.js');
-const { handleError } = require('../utils/util');
-const LOG_PREFIX = "[mcs-controller]";
-
-/* PUBLIC ELEMENTS */
-
-let instance = null;
-
-module.exports = class MediaController {
-  constructor(emitter) {
-    if (!instance) {
-      this.emitter = emitter;
-      this._rooms = {};
-      this._users = {};
-      this._mediaSessions = {};
-      instance = this;
-    }
-
-    return instance;
-  }
-
-  start (_kurentoClient, _kurentoToken, callback) {
-    // TODO
-    return callback(null);
-  }
-
-  stop (callback) {
-    // TODO
-  }
-
-  getRoom (roomId) {
-    return this._rooms[roomId];
-  }
-
-  async join (roomId, type, params) {
-    Logger.info("[mcs-controller] Join room => " + roomId + ' as ' + type);
-    try {
-      let session;
-      const room = await this.createRoomMCS(roomId);
-      const user = await this.createUserMCS(roomId, type, params);
-      room.setUser(user);
-
-      if (params.sdp) {
-        session = user.addSdp(params.sdp);
-      }
-      if (params.uri) {
-        session = user.addUri(params.sdp);
-      }
-
-      Logger.info("[mcs-controller] Resolving user " + user.id);
-      return Promise.resolve(user.id);
-    }
-    catch (err) {
-      return Promise.reject(this._handleError(err));
-    }
-  }
-
-  async leave (roomId, userId) {
-    try {
-      Logger.info("[mcs-controller] User => " + userId + " wants to leave ");
-      const room = this.getRoom(roomId);
-      const user = this.getUserMCS(userId);
-
-      if (!user || !room) {
-        return Promise.resolve();
-      }
-
-      const killedMedias = await user.leave();
-
-      killedMedias.forEach((mediaId) => {
-        delete this._mediaSessions[killedMedias[mediaId]];
-      });
-
-      room.destroyUser(user.id);
-      delete this._users[user.id];
-
-      return Promise.resolve();
-    }
-    catch (err) {
-      return Promise.reject(this._handleError(err));
-    }
-  }
-
-  publishnsubscribe (userId, sourceId, sdp, params = {}) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info("[mcs-controller] PublishAndSubscribe from user", userId, "to source", sourceId);
-      Logger.trace("[mcs-controler] PublishAndSubscribe descriptor is", params.descriptor);
-
-      try {
-        const type = params.type;
-        const user = this.getUserMCS(userId);
-        const userId = user.id;
-        const session = user.addSdp(sdp, type);
-        const sessionId = session.id;
-
-        this._mediaSessions[session.id] = session;
-
-        const answer = await user.startSession(session.id);
-        await user.connect(sourceId, session.id);
-
-        Logger.info("[mcs-controller] PublishAndSubscribe return a SDP session with ID", session.id);
-        resolve({userId, sessionId});
-        session.sessionStarted();
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  publish (userId, roomId, type, params = {}) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info("[mcs-controller] Publish from user", userId, "to room", roomId);
-      Logger.trace("[mcs-controler] Publish descriptor is", params.descriptor);
-
-      try {
-        const user = await this.getUserMCS(userId);
-
-        Logger.info("[mcs-controller] Fetched user", user.id);
-
-        switch (type) {
-          case C.MEDIA_TYPE.RTP:
-          case C.MEDIA_TYPE.WEBRTC:
-          case C.MEDIA_TYPE.URI:
-            const { session, answer } = await user.publish(params.descriptor, type, params);
-            this.addMediaSession(session);
-            resolve({ answer, sessionId: session.id });
-            session.sessionStarted();
-            break;
-
-          default:
-            return reject(this._handleError(C.ERROR.MEDIA_INVALID_TYPE));
-        }
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  addMediaSession (session) {
-    if (typeof this._mediaSessions[session.id] == 'undefined' ||
-        !this._mediaSessions[session.id]) {
-      this._mediaSessions[session.id] = {};
-    }
-
-    this._mediaSessions[session.id] = session;
-  }
-
-  subscribe (userId, sourceId, type, params = {}) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info("[mcs-controller] Subscribe from user", userId, "to source", sourceId);
-      Logger.trace("[mcs-controler] Subscribe descriptor is", params.descriptor);
-
-      try {
-        const user = await this.getUserMCS(userId);
-        const source = this.getMediaSession(sourceId);
-
-        Logger.info("[mcs-controller] Fetched user", user.id);
-
-        switch (type) {
-          case C.MEDIA_TYPE.RTP:
-          case C.MEDIA_TYPE.WEBRTC:
-          case C.MEDIA_TYPE.URI:
-            const  { session, answer } = await user.subscribe(params.descriptor, type, source, params);
-            this.addMediaSession(session);
-            resolve({answer, sessionId: session.id});
-            session.sessionStarted();
-            break;
-          default:
-            return reject(this._handleError(C.ERROR.MEDIA_INVALID_TYPE));
-        }
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  async unpublish (userId, mediaId) {
-    try {
-      const user = this.getUserMCS(userId);
-      const answer = await user.unpublish(mediaId);
-      delete this._mediaSessions[mediaId];
-      return Promise.resolve(answer);
-    }
-    catch (err) {
-      err = this._handleError(err);
-      return Promise.reject(this._handleError(err));
-    }
-  }
-
-  async unsubscribe (userId, mediaId) {
-    try {
-      const user = this.getUserMCS(userId);
-      const answer = await user.unsubscribe(mediaId);
-      delete this._mediaSessions[mediaId];
-      return Promise.resolve();
-    }
-    catch (err) {
-      return Promise.reject(this._handleError(err));
-    }
-  }
-
-  startRecording (userId, sourceId, recordingPath) {
-
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.info("[mcs-controller] startRecording ", sourceId);
-        const user = await this.getUserMCS(userId);
-        const sourceSession = this.getMediaSession(sourceId);
-
-        const session = await user.addRecording(recordingPath);
-        const answer = await user.startSession(session.id);
-        await sourceSession.connect(session._mediaElement);
-
-        this._mediaSessions[session.id] = session;
-
-        resolve(answer);
-        session.sessionStarted();
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  async stopRecording (userId, sourceId, recId) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info("[mcs-controller] Stopping recording session", recId);
-      try {
-        const user = await this.getUserMCS(userId);
-        const recSession = this.getMediaSession(recId);
-        const sourceSession = this.getMediaSession(sourceId);
-
-        const answer = await user.stopSession(recSession.id);
-        user.unsubscribe(recSession.id);
-        this._mediaSessions[recId] = null;
-        return resolve(answer);
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  connect (sourceId, sinkId, type) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info("[mcs-controller] Connect", sourceId, "to", sinkId, "with type", type);
-
-      try {
-        const sourceSession = this.getMediaSession(sourceId);
-        const sinkSession = this.getMediaSession(sinkId);
-
-        await sourceSession.connect(sinkSession._mediaElement, type);
-        return resolve();
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  disconnect (sourceId, sinkId, type) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.info("[mcs-controller] Disconnect", sourceId, "to", sinkId, "with type", type);
-        const sourceSession = this.getMediaSession(sourceId);
-        const sinkSession = this.getMediaSession(sinkId);
-
-        await sourceSession.disconnect(sinkSession._mediaElement, type);
-        return resolve();
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  addIceCandidate (mediaId, candidate) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const session = this.getMediaSession(mediaId);
-        await session.addIceCandidate(candidate);
-
-        return resolve();
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  /**
-   * Creates an empty {Room} room and indexes it
-   * @param {String} roomId
-   */
-  async createRoomMCS (roomId)  {
-    Logger.info("[mcs-controller] Creating new room with ID", roomId);
-
-    if (this._rooms[roomId] == null) {
-      this._rooms[roomId] = new Room(roomId, this.emitter);
-    }
-
-    return Promise.resolve(this._rooms[roomId]);
-  }
-
-  /**
-   * Creates an {User} of type @type
-   * @param {String} roomId
-   */
-  createUserMCS (roomId, type, params)  {
-    let user;
-    Logger.info("[mcs-controller] Creating a new", type, "user at room", roomId);
-
-    switch (type) {
-      case C.USERS.SFU:
-        user  = new SfuUser(roomId, type, this.emitter, params.userAgentString, params.descriptor);
-        break;
-      case C.USERS.MCU:
-        Logger.warn("[mcs-controller] createUserMCS MCU TODO");
-        break;
-      default:
-        Logger.warn("[mcs-controller] Unrecognized user type");
-    }
-
-    if(this._users[user.id] == null) {
-      this._users[user.id] = user;
-    }
-
-    return Promise.resolve(user);
-  }
-
-  getUserMCS (userId) {
-    const user = this._users[userId];
-
-    if (user == null) {
-      throw C.ERROR.USER_NOT_FOUND;
-    }
-
-    return user;
-  }
-
-  getMediaSession (mediaId) {
-    const media = this._mediaSessions[mediaId];
-
-    if (media == null) {
-        throw C.ERROR.MEDIA_NOT_FOUND;
-    }
-
-    return media;
-  }
-
-  _handleError (error) {
-    return handleError(LOG_PREFIX, error);
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/MediaSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/MediaSession.js
deleted file mode 100644
index 2d8f37ad82f5228da5ea93914f67781ac5a3be27..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/MediaSession.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * @classdesc
- * Model class for external devices
- */
-
-'use strict'
-
-const C = require('../constants/Constants');
-const rid = require('readable-id');
-const Kurento = require('../adapters/kurento/kurento');
-const Freeswitch = require('../adapters/freeswitch/freeswitch');
-const config = require('config');
-const kurentoUrl = config.get('kurentoUrl');
-const Logger = require('../../../utils/Logger');
-const { handleError } = require('../utils/util');
-const LOG_PREFIX = "[mcs-media-session]";
-
-module.exports = class MediaSession {
-  constructor (
-    emitter,
-    room,
-    type = 'WebRtcEndpoint',
-    options = {}
-  ) {
-    this.id = rid();
-    this.room = room;
-    this.emitter = emitter;
-    this._status = C.STATUS.STOPPED;
-    this._type = type;
-    this._mediaElement;
-    this.subscribedSessions = [];
-    this._options = options;
-    this._adapter = options.adapter? options.adapter : C.STRING.KURENTO;
-    this._name = options.name? options.name : C.STRING.DEFAULT_NAME;
-    this._MediaServer = MediaSession.getAdapter(this._adapter, emitter);
-    this.eventQueue = [];
-  }
-
-  async start () {
-    this._status = C.STATUS.STARTING;
-    try {
-      const client = await this._MediaServer.init();
-
-      this._mediaElement = await this._MediaServer.createMediaElement(this.room, this._type, this._options);
-
-      Logger.info("[mcs-media-session] New media session", this.id, "in room", this.room, "started with media server endpoint", this._mediaElement);
-
-      this._MediaServer.on(C.EVENT.MEDIA_STATE.MEDIA_EVENT+this._mediaElement, (event) => {
-        event.id = this.id;
-        if (this._status !== C.STATUS.STARTED) {
-          Logger.debug("[mcs-media-session] Media session", this.id, "queuing event", event);
-          this.eventQueue.push(event);
-        }
-        else {
-          this.emitter.emit(C.EVENT.MEDIA_STATE.MEDIA_EVENT+this.id, event);
-        }
-      });
-
-      this._MediaServer.trackMediaState(this._mediaElement, this._type);
-
-      this._MediaServer.on(C.ERROR.MEDIA_SERVER_OFFLINE, () => {
-          let event = {};
-          event.eventTag = C.ERROR.MEDIA_SERVER_OFFLINE;
-          event.id = this.id;
-          this.emitter.emit(C.EVENT.SERVER_STATE+this.id, event);
-      });
-
-      this._MediaServer.on(C.EVENT.MEDIA_SERVER_ONLINE, () => {
-          let event = {};
-          event.eventTag = C.EVENT.MEDIA_SERVER_ONLINE;
-          event.id = this.id;
-          this.emitter.emit(C.EVENT.SERVER_STATE+this.id);
-      });
-
-      return Promise.resolve(this._mediaElement);
-    }
-    catch (err) {
-      err = this._handleError(err);
-      return Promise.reject(err);
-    }
-  }
-
-  async stop () {
-    if (this._status === C.STATUS.STARTED) {
-      this._status = C.STATUS.STOPPING;
-      try {
-        await this._MediaServer.stop(this.room, this._type, this._mediaElement);
-        this._status = C.STATUS.STOPPED;
-        Logger.info("[mcs-media-session] Session", this.id, "stopped with status", this._status);
-        this.emitter.emit(C.EVENT.MEDIA_SESSION_STOPPED, this.id);
-        return Promise.resolve();
-      }
-      catch (err) {
-        err = this._handleError(err);
-        return Promise.reject(err);
-      }
-    } else {
-      return Promise.resolve();
-    }
-  }
-
-  async connect (sinkId, type = 'ALL') {
-    try {
-      Logger.info("[mcs-media-session] Connecting " + this._mediaElement + " => " + sinkId);
-      await this._MediaServer.connect(this._mediaElement, sinkId, type);
-      return Promise.resolve();
-    }
-    catch (err) {
-      err = this._handleError(err);
-      return Promise.reject(err);
-    }
-  }
-
-  async disconnect (sinkId, type = 'ALL') {
-    try {
-      Logger.info("[mcs-media-session] Dis-connecting " + this._mediaElement + " => " + sinkId);
-      await this._MediaServer.disconnect(this._mediaElement, sinkId, type);
-      return Promise.resolve();
-    }
-    catch (err) {
-      err = this._handleError(err);
-      return Promise.reject(err);
-    }
-  }
-
-  addMediaEventListener (type, mediaId) {
-    this._MediaServer.addMediaEventListener (type, mediaId);
-  }
-
-  sessionStarted () {
-    if (this._status === C.STATUS.STARTING) {
-      this._status = C.STATUS.STARTED;
-      // FIXME: ugly hack, gotta change the event model to a subscription-based
-      // one to remove this - prlanzarin
-      setTimeout(() => {
-        this._flushEventQueue();
-      }, 50);
-      Logger.debug("[mcs-media-session] Session", this.id, "successfully started");
-    }
-  }
-
-  _flushEventQueue () {
-    Logger.debug("[mcs-media-session] Flushing session", this.id, "events queue");
-    while (this.eventQueue.length) {
-      let event = this.eventQueue.shift();
-      this.emitter.emit(C.EVENT.MEDIA_STATE.MEDIA_EVENT+this.id, event);
-    }
-  }
-
-  static getAdapter (adapter, emitter) {
-    let obj = null;
-
-    Logger.info("[mcs-media-session] Session is using the", adapter, "adapter");
-
-    switch (adapter) {
-      case C.STRING.KURENTO:
-        obj = new Kurento(kurentoUrl, emitter);
-        break;
-      case C.STRING.FREESWITCH:
-        obj = new Freeswitch();
-        break;
-      default: Logger.warn("[mcs-media-session] Invalid adapter", this.adapter); }
-
-    return obj;
-  }
-
-  _handleError (error) {
-    this._status = C.STATUS.STOPPED;
-    return handleError(LOG_PREFIX, error);
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/RecordingSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/RecordingSession.js
deleted file mode 100644
index b358f70ec0a51c73c97267f2a5b42fa888a98d94..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/RecordingSession.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * @classdesc
- * Model class for Recording
- */
-
-'use strict'
-
-const config = require('config');
-const MediaSession = require('./MediaSession');
-
-module.exports = class RecordingSession extends MediaSession {
-  constructor(emitter, room, recordingPath) {
-    const uri = recordingPath;
-    const options = {
-      mediaProfile: config.get('recordingMediaProfile'),
-      uri: uri,
-      stopOnEndOfStream: true
-    };
-
-    super(emitter, room, 'RecorderEndpoint', options);
-    this.filename = uri;
-  }
-
-  async process () {
-    const answer = await this._MediaServer.startRecording(this._mediaElement);
-    return Promise.resolve({ recordingId: this.id, filename: this.filename, meetingId: this.room });
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/Room.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/Room.js
deleted file mode 100644
index ca8ae614a4f0ed983be97c0dcbae9bda83ae678d..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/Room.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * @classdesc
- * Model class for rooms
- */
-
-'use strict'
-
-const C = require('../constants/Constants');
-
-module.exports = class Room {
-  constructor(id, emitter) {
-    this._id = id;
-    this._users = {};
-    this._mcuUsers = {};
-    this.emitter = emitter;
-  }
-
-  getUser (id) {
-    return this._users[id];
-  }
-
-  setUser (user) {
-    this._users[user.id] = user;
-  }
-
-  destroyUser(userId) {
-    if (this._users[userId]) {
-      delete this._users[userId];
-      if (Object.keys(this._users).length <= 0) {
-        this.emitter.emit(C.EVENT.ROOM_EMPTY, this._id);
-      }
-    }
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
deleted file mode 100644
index e19813cb1b1aababed5d7eff9b2ab353b7d31c22..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * @classdesc
- * Model class for external devices
- */
-
-'use strict'
-
-const C = require('../constants/Constants');
-const SdpWrapper = require('../utils/SdpWrapper');
-const rid = require('readable-id');
-const MediaSession = require('./MediaSession');
-const config = require('config');
-const kurentoUrl = config.get('kurentoUrl');
-const kurentoIp = config.get('kurentoIp');
-const Logger = require('../../../utils/Logger');
-
-module.exports = class SdpSession extends MediaSession {
-  constructor(
-    emitter,
-    offer = null,
-    room,
-    type = 'WebRtcEndpoint',
-    options
-  ) {
-    super(emitter, room, type, options);
-    Logger.info("[mcs-sdp-session] New session with options", options);
-    // {SdpWrapper} SdpWrapper
-    this._offer;
-    this._answer;
-
-    if (offer) {
-      this.setOffer(offer);
-    }
-  }
-
-  setOffer (offer) {
-    if (offer) {
-      this._offer = new SdpWrapper(offer, this._type);
-    }
-  }
-
-  setAnswer (answer) {
-    if (answer) {
-      this._answer = new SdpWrapper(answer, this._type);
-    }
-  }
-
-  process () {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const answer = await this._MediaServer.processOffer(this._mediaElement,
-          this._offer.plainSdp,
-          { name: this._name }
-        );
-
-        this.setAnswer(answer);
-
-        // Checks if the media server was able to find a compatible media line
-        if (answer && !this._hasAvailableCodec()) {
-          return reject(this._handleError(C.ERROR.MEDIA_NO_AVAILABLE_CODEC));
-        }
-
-        const { targetBitrate } = this._options;
-
-        if (answer && targetBitrate && targetBitrate !== '0') {
-          this._answer.addBandwidth('video', targetBitrate);
-        }
-
-        if (this._type !== 'WebRtcEndpoint') {
-          this._offer.replaceServerIpv4(kurentoIp);
-          return resolve(this._answer? this._answer._plainSdp : null);
-        }
-
-        await this._MediaServer.gatherCandidates(this._mediaElement);
-        resolve(this._answer._plainSdp);
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  addIceCandidate (candidate) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        await this._MediaServer.addIceCandidate(this._mediaElement, candidate);
-        resolve();
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-    _hasAvailableCodec () {
-    return (this._offer.hasAvailableVideoCodec() && this._answer.hasAvailableVideoCodec()) ||
-      (this._offer.hasAvailableAudioCodec() && this._answer.hasAvailableAudioCodec());
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js
deleted file mode 100644
index 2d1f917a296e76ea77febbf2444aa5f38459ae26..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * @classdesc
- * Model class for external devices
- */
-
-'use strict'
-
-const User = require('./User');
-const C = require('../constants/Constants');
-const SdpWrapper = require('../utils/SdpWrapper');
-const SdpSession = require('../model/SdpSession');
-const RecordingSession = require('../model/RecordingSession');
-const UriSession = require('../model/UriSession');
-const Logger = require('../../../utils/Logger');
-const isError = require('../utils/util').isError;
-
-module.exports = class SfuUser extends User {
-  constructor(_roomId, type, emitter, userAgentString = C.STRING.ANONYMOUS, sdp = null, uri = null) {
-    super(_roomId);
-    // {SdpWrapper} SdpWrapper
-    this._sdp;
-    this._mediaSessions = {}
-    this.userAgentString;
-    this.emitter = emitter;
-    if (sdp) {
-      this.addSdp(sdp);
-    }
-    if (uri) {
-      this.addUri(uri);
-    }
-  }
-
-  // TODO switch from type to children UriSessions (RTSP|HTTP|etc)
-  async addUri (uri, type) {
-      const session = new UriSession(uri, type);
-      this.emitter.emit(C.EVENT.NEW_SESSION+this.id, session.id);
-
-      session.emitter.once(C.EVENT.MEDIA_SESSION_STOPPED, (sessId) => {
-        if (sessId === session.id) {
-          Logger.info("[mcs-sfu-user] URI session stopped.");
-          this._mediaSessions[sessId] = null;
-        }
-      });
-
-      this._mediaSessions[session.id] = session;
-
-      Logger.info("[mcs-sfu-user] Added new URI session", session.id, "to user", this.id);
-
-      return session;
-  }
-
-  addSdp (sdp, type, options) {
-    // TODO switch from type to children SdpSessions (WebRTC|SDP)
-    const session = new SdpSession(this.emitter, sdp, this.roomId, type, options);
-    session.emitter.on(C.EVENT.MEDIA_SESSION_STOPPED, (sessId) => {
-      if (sessId === session.id) {
-        Logger.info("[mcs-sfu-user] Session ", sessId, "stopped, cleaning it...");
-        this._mediaSessions[sessId] = null;
-      }
-    });
-
-    this._mediaSessions[session.id] = session;
-
-    Logger.info("[mcs-sfu-user] Added new SDP session", session.id, "to user", this.id);
-
-    return session;
-  }
-
-  addRecording (recordingPath) {
-    try {
-    const session = new RecordingSession(this.emitter, this.roomId, recordingPath);
-    this.emitter.emit(C.EVENT.NEW_SESSION+this.id, session.id);
-
-    session.emitter.once(C.EVENT.MEDIA_SESSION_STOPPED, (sessId) => {
-      if (sessId === session.id) {
-        Logger.info("[mcs-sfu-user] Recording session stopped.");
-        this._mediaSessions[sessId] = null;
-      }
-    });
-
-    this._mediaSessions[session.id] = session;
-    Logger.info("[mcs-sfu-user] Added new recording session", session.id, "to user", this.id);
-
-    return session;
-    }
-    catch (err) {
-      this._handleError(err);
-    }
-  }
-
-
-  startSession (sessionId) {
-    const session = this._mediaSessions[sessionId];
-    return new Promise(async (resolve, reject) => {
-      try {
-        const mediaElement = await session.start();
-        const answer = await session.process();
-        resolve(answer);
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  subscribe (sdp, type, source, params) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const session = this.addSdp(sdp, type, params);
-        const answer = await this.startSession(session.id);
-        await source.connect(session._mediaElement);
-        resolve({ session, answer });
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  publish (sdp, type, params) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const session = this.addSdp(sdp, type, params);
-        const answer = await this.startSession(session.id);
-        resolve({ session, answer });
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  unsubscribe (mediaId) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        await this.stopSession(mediaId);
-        resolve(mediaId);
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  unpublish (mediaId) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        await this.stopSession(mediaId);
-        resolve(mediaId);
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  stopSession (sessionId) {
-    const session = this._mediaSessions[sessionId];
-
-    return new Promise(async (resolve, reject) => {
-      try {
-        if (session) {
-          Logger.info("[mcs-sfu-user] Stopping session => " + sessionId);
-          await session.stop();
-          delete this._mediaSessions[sessionId];
-        }
-
-        return resolve();
-      }
-      catch (err) {
-        reject(this._handleError(err));
-      }
-    });
-  }
-
-  connect (sourceId, sinkId) {
-    const session = this._mediaSessions[sourceId];
-
-    return new Promise(async (resolve, reject) => {
-      try {
-        if (session == null) {
-          return reject(this._handleError(C.ERROR.MEDIA_NOT_FOUND));
-        }
-        Logger.info("[mcs-sfu-user] Connecting sessions " + sourceId + "=>" + sinkId);
-        await session.connect(sinkId);
-        return resolve();
-      }
-      catch (err) {
-        return reject(this._handleError(err));
-      }
-    });
-  }
-
-  async leave () {
-    const sessions = Object.keys(this._mediaSessions);
-    let stopProcedures = [];
-    Logger.info("[mcs-sfu-user] User sessions will be killed");
-
-    try {
-      for (let i = 0; i < sessions.length; i++) {
-        stopProcedures.push(this.stopSession(sessions[i]));
-      }
-
-      return Promise.all(stopProcedures);
-    }
-    catch (err) {
-      err = this._handleError(err);
-      Promise.reject(err);
-    }
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js
deleted file mode 100644
index 904d8fc7397b8c74cc12f487ad7f16bd31117c8a..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * @classdesc
- * Model class for external devices
- */
-
-'use strict'
-
-const C = require('../constants/Constants');
-const rid = require('readable-id');
-const EventEmitter = require('events').EventEmitter;
-const MediaSession = require('./MediaSession');
-const Logger = require('../../../utils/Logger');
-
-module.exports = class UriSession extends MediaSession {
-  constructor(uri = null) {
-    super();
-    this.id = rid();
-    this._status = C.STATUS.STOPPED;
-    this._uri;
-    if (uri) {
-      this.setUri(uri);
-    }
-  }
-
-  setUri (uri) {
-    this._uri = uri;
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/User.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/User.js
deleted file mode 100644
index bd5b993c9687e8928f83671eb32642f3798a32fb..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/User.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @classdesc
- * Model class for external devices
- */
-
-'use strict'
-
-const rid = require('readable-id');
-const User = require('./User');
-const C = require('../constants/Constants.js');
-const Logger = require('../../../utils/Logger');
-const { handleError } = require('../utils/util');
-const LOG_PREFIX = "[mcs-user]";
-
-module.exports = class User {
-  constructor(roomId, type, userAgentString = C.STRING.ANONYMOUS) {
-    this.roomId = roomId;
-    this.id = rid();
-    this.userAgentString = userAgentString;
-  }
-
-  _handleError (error) {
-    return handleError(LOG_PREFIX, error);
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
deleted file mode 100644
index a19912bdba9d2002543a2f01d5e57d050c1c6169..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
+++ /dev/null
@@ -1,295 +0,0 @@
-/**
- * @classdesc
- * Utils class for manipulating SDP
- */
-
-'use strict'
-
-var config = require('config');
-var transform = require('sdp-transform');
-
-module.exports = class SdpWrapper {
-  constructor(sdp) {
-    this._plainSdp = sdp;
-    this._jsonSdp = transform.parse(sdp);
-    this._mediaLines = {};
-    this._mediaCapabilities = {};
-    this._profileThreshold = "ffffff";
-    this.processSdp();
-  }
-
-  get plainSdp() {
-    return this._plainSdp;
-  }
-
-  get jsonSdp() {
-    return this._jsonSdp;
-  }
-
-  removeFmtp () {
-    return this._plainSdp.replace(/(a=fmtp:).*/g, '');
-  }
-
-  replaceServerIpv4 (ipv4) {
-    return this._plainSdp.replace(/(IP4\s[0-9.]*)/g, 'IP4 ' + ipv4);
-  }
-
-  hasAudio () {
-    return this._mediaCapabilities.hasAudio;
-  }
-
-  hasVideo () {
-    return this._mediaCapabilities.hasVideo;
-  }
-
-  hasMultipleVideo () {
-    return this._mediaCapabilities.hasMultipleVideo;
-  }
-
-  hasAvailableVideoCodec () {
-    return this._mediaCapabilities.hasAvailableVideoCodec;
-  }
-
-  hasAvailableAudioCodec () {
-    return this._mediaCapabilities.hasAvailableAudioCodec;
-  }
-
-  addBandwidth (type, bw) {
-    // Bandwidth format
-    // { type: 'TIAS or AS', limit: 2048000 }
-    for(var ml of this._jsonSdp.media) {
-      if(ml.type === type ) {
-        ml['bandwidth'] = [];
-        ml.bandwidth.push({ type: 'TIAS', limit: (bw >>> 0) * 1000 });
-        ml.bandwidth.push({ type: 'AS', limit: bw });
-      }
-    }
-
-    this._plainSdp = transform.write(this._jsonSdp);
-  }
-
-  /**
-   * Given a SDP, test if there is an audio description in it
-   * @return {boolean}    true if there is more than one video description, else false
-   */
-  _hasAudio () {
-    return /(m=audio)/i.test(this._plainSdp);
-  }
-
-  /**
-   * Given a SDP, test if there is a video description in it
-   * @return {boolean}    true if there is a video description, else false
-   */
-  _hasVideo () {
-    return /(m=video)/i.test(this._plainSdp);
-  }
-
-  /**
-   * Given a SDP, test if there is more than on video description
-   * @return {boolean}    true if there is more than one video description, else false
-   */
-  _hasMultipleVideo () {
-    return /(m=video)([\s\S]*\1){1,}/i.test(this._plainSdp);
-  }
-
-  /**
-   * Tests if the current SDP has an available and valid video codec
-   * @return {boolean} true if there is an RTP video session specified and active
-   */
-  _hasAvailableVideoCodec () {
-    return this._jsonSdp.media.some((ml) => {
-      let  { type, rtp, port } = ml;
-      return type === 'video' && rtp && rtp.length > 0 && port !== 0;
-    });
-  }
-
-  /**
-   * Tests if the current SDP has an available and valid audio codec
-   * @return {boolean} true if there is an RTP audio session specified and active
-   */
-  _hasAvailableAudioCodec () {
-    return this._jsonSdp.media.some((ml) => {
-      let  { type, rtp, port } = ml;
-      return type === 'audio' && rtp && rtp.length > 0 && port !== 0;
-    });
-  }
-
-  /**
-   * Given a SDP, return its Session Description
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     Session description (SDP until the first media line)
-   */
-  getSessionDescription (sdp) {
-    return sdp.match(/[\s\S]+?(?=m=audio|m=video)/i);
-  }
-
-  removeSessionDescription (sdp) {
-    return sdp.match(/(?=[\s\S]+?)(m=audio[\s\S]+|m=video[\s\S]+)/i)[1];
-  }
-
-  getVideoParameters (sdp) {
-    var res = transform.parse(sdp);
-    var params = {};
-    params.fmtp = "";
-    params.codecId = 96;
-    var pt = 0;
-    for(var ml of res.media) {
-      if(ml.type == 'video') {
-        if (typeof ml.fmtp[0] != 'undefined' && ml.fmtp) {
-          params.codecId = ml.fmtp[0].payload;
-          params.fmtp = ml.fmtp[0].config;
-          return params;
-        }
-      }
-    }
-    return params;
-  }
-
-  /**
-   * Given a SDP, return its Content Description
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     Content Description (SDP after first media description)
-   */
-  getContentDescription (sdp) {
-    var res = transform.parse(sdp);
-    res.media = res.media.filter(function (ml) { return ml.type == "video" });
-    var mangledSdp = transform.write(res);
-    if(typeof mangledSdp != undefined && mangledSdp && mangledSdp != "") {
-      return mangledSdp;
-    }
-    else
-      return sdp;
-  }
-
-  /**
-   * Given a SDP, return its first Media Description
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     Content Description (SDP after first media description)
-   */
-  getAudioDescription (sdp) {
-    var res = transform.parse(sdp);
-    res.media = res.media.filter(function (ml) { return ml.type == "audio" });
-    // Hack: Some devices (Snom, Pexip) send crypto with RTP/AVP
-    // That is forbidden according to RFC3711 and FreeSWITCH rebukes it
-    res = this.removeTransformCrypto(res);
-    var mangledSdp = transform.write(res);
-    this.getSessionDescription(mangledSdp);
-    if(typeof mangledSdp != undefined && mangledSdp && mangledSdp != "") {
-      return mangledSdp;
-    }
-    else {
-      return sdp;
-    }
-  }
-
-  /**
-   * Given a SDP, return its first Media Description
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     Content Description (SDP after first media description)
-   */
-  getMainDescription () {
-    var res = transform.parse(this._plainSdp);
-    // Filter should also carry && ml.invalid[0].value != 'content:slides';
-    // when content is enabled
-    res.media = res.media.filter(function (ml) { return ml.type == "video"}); //&& ml.invalid[0].value != 'content:slides'});
-    var mangledSdp = transform.write(res);
-    if (typeof mangledSdp != undefined && mangledSdp && mangledSdp != "") {
-      return mangledSdp;
-    }
-    else {
-      return sdp;
-    }
-  }
-
-  /**
-   * Given a JSON SDP, remove associated crypto 'a=' lines from media lines
-   * WARNING: HACK MADE FOR FreeSWITCH ~1.4 COMPATIBILITY
-   * @param  {Object} sdp The Session Descriptor JSON
-   * @return {Object}     JSON SDP without crypto lines
-   */
-  removeTransformCrypto (sdp) {
-    for(var ml of sdp.media) {
-      delete ml['crypto'];
-    }
-    return sdp;
-  }
-
-  removeHighQualityFmtps (sdp) {
-    let res = transform.parse(sdp);
-    let maxProfileLevel = config.get('kurento.maximum_profile_level_hex');
-    let pt = 0;
-    let idx = 0;
-    for(var ml of res.media) {
-      if(ml.type == 'video') {
-        for(var fmtp of ml.fmtp) {
-          let fmtpConfig = transform.parseParams(fmtp.config);
-          let profileId = fmtpConfig['profile-level-id'];
-          if(typeof profileId !== 'undefined' && parseInt(profileId, 16) > parseInt(maxProfileLevel, 16)) {
-            pt = fmtp.payload;
-            delete ml.fmtp[idx];
-            ml.rtp = ml.rtp.filter((rtp) => { return rtp.payload != pt});
-          }
-          else {
-            // Remove fmtp further specifications
-            //let configProfile = "profile-level-id="+profileId;
-            //fmtp.config = configProfile;
-          }
-          idx++;
-        }
-      }
-    }
-    var mangledSdp = transform.write(res);
-    return mangledSdp;
-  }
-
-  processSdp () {
-    let description = this._plainSdp;
-
-    description = description.toString().replace(/telephone-event/, "TELEPHONE-EVENT");
-
-    this._mediaCapabilities.hasVideo = this._hasVideo();
-    this._mediaCapabilities.hasAudio = this._hasAudio();
-    this._mediaCapabilities.hasContent = this._hasMultipleVideo();
-    this._mediaCapabilities.hasAvailableVideoCodec = this._hasAvailableVideoCodec();
-    this._mediaCapabilities.hasAvailableAudioCodec = this._hasAvailableAudioCodec();
-    this.sessionDescriptionHeader = this.getSessionDescription(description);
-    this.audioSdp =  this.getAudioDescription(description);
-    this.mainVideoSdp = this.getMainDescription(description);
-    this.contentVideoSdp = this.getContentDescription(description);
-
-    return;
-  }
-
-  /* DEVELOPMENT METHODS */
-  _disableMedia  (sdp) {
-    return sdp.replace(/(m=application\s)\d*/g, "$10");
-  };
-
-  /**
-   * Given a SDP, add Floor Control response
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     A new Session Descriptor with Floor Control
-   */
-  _addFloorControl (sdp) {
-    return sdp.replace(/a=inactive/i, 'a=sendrecv\r\na=floorctrl:c-only\r\na=setup:active\r\na=connection:new');
-  }
-
-  /**
-   * Given a SDP, add Floor Control response to reinvite
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     A new Session Descriptor with Floor Control Id
-   */
-  _addFloorId (sdp) {
-    sdp = sdp.replace(/(a=floorctrl:c-only)/i, '$1\r\na=floorid:1 m-stream:3');
-    return sdp.replace(/(m=video.*)([\s\S]*?m=video.*)([\s\S]*)/i, '$1\r\na=content:main\r\na=label:1$2\r\na=content:slides\r\na=label:3$3');
-  }
-
-  /**
-   * Given the string representation of a Session Descriptor, remove it's video
-   * @param  {string} sdp The Session Descriptor
-   * @return {string}     A new Session Descriptor without the video
-   */
-  _removeVideoSdp  (sdp) {
-    return sdp.replace(/(m=video[\s\S]+)/g,'');
-  };
-};
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/util.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/util.js
deleted file mode 100644
index c0be5773bb84c9d1086f4473250c0e0e5cc3c140..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/util.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- *  @classdesc
- *  Utils class for mcs-core
- *  @constructor
- *
- */
-
-const C = require('../constants/Constants');
-const Logger = require('../../../utils/Logger');
-
-exports.isError = (error) => {
-  return error && error.stack && error.message && typeof error.stack === 'string'
-    && typeof error.message === 'string';
-}
-
-exports.handleError = (logPrefix, error) => {
-  let { message, code, stack, data, details } = error;
-  if (code && code >= C.ERROR.MIN_CODE && code <= C.ERROR.MAX_CODE) {
-    return error;
-  }
-
-  if (code == null) {
-    ({ code, message } = C.ERROR.MEDIA_GENERIC_ERROR);
-  }
-  else {
-    ({ code, message } = error);
-  }
-
-  if (!this.isError(error)) {
-    error = new Error(message);
-  }
-
-  error.code = code;
-  error.message = message;
-  error.stack = stack
-
-  if (details) {
-    error.details = details;
-  }
-  else {
-    error.details = message;
-  }
-
-  Logger.debug(logPrefix, "Handling error", error.code, error.message);
-  Logger.trace(logPrefix, error.stack);
-
-  return error;
-}
diff --git a/labs/bbb-webrtc-sfu/lib/media-handler.js b/labs/bbb-webrtc-sfu/lib/media-handler.js
deleted file mode 100644
index e5c104d927da081c050e7906c2a9b042d38e9352..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/media-handler.js
+++ /dev/null
@@ -1,64 +0,0 @@
-var config = require('config');
-var Constants = require('./bbb/messages/Constants');
-
-module.exports.generateSdp = function(remote_ip_address, remote_video_port) {
-  return "v=0\r\n"
-    + "o=- 0 0 IN IP4 " + remote_ip_address + "\r\n"
-    + "s=Kurento-SCREENSHARE\r\n"
-    + "c=IN IP4 " + remote_ip_address + "\r\n"
-    + "t=0 0\r\n"
-    + "m=video " + remote_video_port + " RTP/AVPF 96\r\n"
-    + "a=rtpmap:96 H264/90000\r\n"
-    + "a=ftmp:96\r\n";
-}
-
-module.exports.generateVideoSdp = function (sourceIpAddress, sourceVideoPort) {
-    return "v=0\r\n"
-    + "o=- 0 0 IN IP4 " + sourceIpAddress + "\r\n"
-    + "s=Kurento-SCREENSHARE\r\n"
-    + 'm=video ' + sourceVideoPort + ' ' + this.videoConfiguration.rtpProfile + ' ' + this.videoConfiguration.codecId + '\r\n'
-    + 'a=' + this.videoConfiguration.sendReceive + '\r\n'
-    + 'c=IN IP4 ' + sourceIpAddress + '\r\n'
-    + 'a=rtpmap:' + this.videoConfiguration.codecId + ' ' + this.videoConfiguration.codecName + '/' + this.videoConfiguration.codecRate + '\r\n'
-    + 'a=fmtp:' + this.videoConfiguration.codecId + '\r\n'
-    + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' ccm fir \r\n'
-    + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' nack \r\n'
-    + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' nack pli \r\n'
-    + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' goog-remb \r\n';
-};
-
-module.exports.videoConfiguration = {
-    codecId: '96',
-    sendReceive: 'sendrecv',
-    rtpProfile: 'RTP/AVPF',
-    codecName: 'H264',
-    frameRate: '30.000000',
-    codecRate: '90000'
-};
-
-module.exports.generateStreamUrl = function (address, meeting, path) {
-  return "rtmp://" + address + "/video-broadcast/" + meeting + "/" + path;
-}
-
-module.exports.generateTranscoderParams = function (localIp, destIp, sendPort, recvPort, input, streamType, transcoderType, codec, callername, voiceConf) {
-  var rtpParams = {};
-  rtpParams[Constants.LOCAL_IP_ADDRESS] = localIp;
-  rtpParams[Constants.LOCAL_VIDEO_PORT] = sendPort;
-  rtpParams[Constants.DESTINATION_IP_ADDRESS] = destIp;
-  rtpParams[Constants.REMOTE_VIDEO_PORT] = recvPort;
-  rtpParams[Constants.INPUT] = input;
-  rtpParams[Constants.STREAM_TYPE] = streamType;
-  rtpParams[Constants.TRANSCODER_TYPE] = transcoderType;
-  rtpParams[Constants.TRANSCODER_CODEC] = codec;
-  rtpParams[Constants.CALLERNAME] = callername;
-  rtpParams[Constants.VOICE_CONF] = voiceConf;
-  return rtpParams;
-}
-
-module.exports.getPort = function (min_port, max_port) {
-  return Math.floor((Math.random() * (max_port - min_port + 1) + min_port));
-}
-
-module.exports.getVideoPort = function () {
-  return this.getPort(config.get('minVideoPort'), config.get('maxVideoPort'));
-}
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js
deleted file mode 100644
index 0b42746094435f241c632105be9d90ed77f91274..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-"use strict";
-
-const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
-const Screenshare = require('./screenshare');
-const BaseManager = require('../base/BaseManager');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const errors = require('../base/errors');
-
-module.exports = class ScreenshareManager extends BaseManager {
-  constructor (connectionChannel, additionalChannels, logPrefix) {
-    super(connectionChannel, additionalChannels, logPrefix);
-    this.sfuApp = C.SCREENSHARE_APP;
-    this.messageFactory(this._onMessage);
-    this._iceQueues = {};
-  }
-
-  async _onMessage(message) {
-    Logger.debug(this._logPrefix, 'Received message [' + message.id + '] from connection', message.connectionId);
-
-    const sessionId = message.voiceBridge;
-    const connectionId = message.connectionId;
-    const role = message.role;
-    const sdpOffer = message.sdpOffer
-    const callerName = message.callerName;
-    let iceQueue, session;
-
-    session = this._fetchSession(sessionId);
-    iceQueue = this._fetchIceQueue(sessionId);
-
-    switch (message.id) {
-      case 'start':
-        if (!session) {
-          session = new Screenshare(connectionId, this._bbbGW,
-            sessionId, connectionId, message.vh, message.vw,
-            message.internalMeetingId);
-          this._sessions[sessionId] = session;
-        }
-
-        // starts screenshare peer with role by sending sessionID, websocket and sdpoffer
-        try {
-          const sdpAnswer = await session.start(sessionId, connectionId, sdpOffer, callerName, role)
-          Logger.info(this._logPrefix, "Started peer", sessionId, " for connection", connectionId);
-
-          // Empty ice queue after starting session
-          if (iceQueue) {
-            let candidate;
-            while(candidate = iceQueue.pop()) {
-              session.onIceCandidate(candidate, role, callerName);
-            }
-          }
-
-          this._bbbGW.publish(JSON.stringify({
-            connectionId: connectionId,
-            type: C.SCREENSHARE_APP,
-            role: role,
-            id : 'startResponse',
-            response : 'accepted',
-            sdpAnswer : sdpAnswer
-          }), C.FROM_SCREENSHARE);
-
-          session.once(C.MEDIA_SERVER_OFFLINE, (event) => {
-            this._stopSession(sessionId);
-          });
-
-          // listen for presenter change to avoid inconsistent states on reconnection
-          if (role === C.SEND_ROLE) {
-            this._bbbGW.once(C.PRESENTER_ASSIGNED_2x+message.internalMeetingId, async (payload) => {
-              Logger.info(this._logPrefix, "Presenter changed, forcibly closing screensharing session at", message.internalMeetingId);
-              await this.closeSession(session, connectionId, role, sessionId);
-              this._bbbGW.publish(JSON.stringify({
-                connectionId: connectionId,
-                type: C.SCREENSHARE_APP,
-                id : 'close',
-              }), C.FROM_SCREENSHARE);
-            });
-          }
-
-          Logger.info(this._logPrefix, "Sending startResponse to peer", sessionId, "for connection", session._id);
-        }
-        catch (error) {
-          let errorMessage = this._handleError(this._logPrefix, connectionId, callerName, role, error);
-          this._bbbGW.publish(JSON.stringify({
-            ...errorMessage
-          }), C.FROM_SCREENSHARE);
-        }
-        break;
-
-      case 'stop':
-        Logger.info(this._logPrefix, 'Received stop message for session', sessionId, "at connection", connectionId);
-
-        if (session) {
-          session._stop(sessionId);
-        } else {
-          Logger.warn(this._logPrefix, "There was no screensharing session on stop for", sessionId);
-        }
-        break;
-
-      case 'iceCandidate':
-        if (session && session.constructor === Screenshare) {
-          session.onIceCandidate(message.candidate, role, callerName);
-        } else {
-          Logger.info(this._logPrefix, "Queueing ice candidate for later in screenshare", message.voiceBridge);
-          iceQueue.push(message.candidate);
-        }
-        break;
-
-      case 'close':
-        Logger.info(this._logPrefix, 'Connection ' + connectionId + ' closed');
-        this.closeSession(session, connectionId, role, sessionId);
-        break;
-
-      default:
-        const errorMessage = this._handleError(this._logPrefix, connectionId, null, null, errors.SFU_INVALID_REQUEST);
-        this._bbbGW.publish(JSON.stringify({
-          ...errorMessage,
-        }), C.FROM_SCREENSHARE);
-        break;
-    }
-  }
-
-  async closeSession (session, connectionId, role, sessionId) {
-    if (session && session.constructor == Screenshare) {
-      if (role === C.SEND_ROLE && session) {
-        Logger.info(this._logPrefix, "Stopping presenter " + sessionId);
-        await this._stopSession(sessionId);
-        return;
-      }
-      if (role === C.RECV_ROLE && session) {
-        Logger.info(this._logPrefix, "Stopping viewer " + sessionId);
-        await session.stopViewer(connectionId);
-      }
-    }
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js
deleted file mode 100644
index 7b871719ea5247563ebe1049b297535a651ebd96..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict';
-
-const ScreenshareManager = require('./ScreenshareManager');
-const BaseProcess = require('../base/BaseProcess');
-const C = require('../bbb/messages/Constants');
-
-const manager = new ScreenshareManager(C.TO_SCREENSHARE, [C.FROM_BBB_TRANSCODE_SYSTEM_CHAN, C.FROM_AKKA_APPS], C.SCREENSHARE_MANAGER_PREFIX);
-const newProcess = new BaseProcess(manager, C.SCREENSHARE_PROCESS_PREFIX);
-
-newProcess.start();
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
deleted file mode 100644
index 1c970224ee2b16c6450329d57966b2440cf38a3c..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-'use strict'
-
-const C = require('../bbb/messages/Constants');
-const MediaHandler = require('../media-handler');
-const Messaging = require('../bbb/messages/Messaging');
-const moment = require('moment');
-const h264_sdp = require('../h264-sdp');
-const now = moment();
-const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
-const Logger = require('../utils/Logger');
-const BaseProvider = require('../base/BaseProvider');
-const config = require('config');
-const kurentoIp = config.get('kurentoIp');
-const localIpAddress = config.get('localIpAddress');
-const FORCE_H264 = config.get('screenshare-force-h264');
-const PREFERRED_H264_PROFILE = config.get('screenshare-preferred-h264-profile');
-const SCREENSHARE_TARGET_BITRATE = config.get('screenshare-target-bitrate');
-const SHOULD_RECORD = config.get('recordScreenSharing');
-const KEYFRAME_INTERVAL = config.get('screenshareKeyframeInterval');
-const LOG_PREFIX = "[screenshare]";
-
-// Global MCS endpoints mapping. These hashes maps IDs generated by the mcs-core
-// lib to the ones generate in the ScreenshareManager
-var sharedScreens = {};
-var rtpEndpoints = {};
-
-module.exports = class Screenshare extends BaseProvider {
-  constructor(id, bbbgw, voiceBridge, userId, vh, vw, meetingId) {
-    super();
-    this.sfuApp = C.SCREENSHARE_APP;
-    this.mcs = new MCSApi();
-    this.mcsUserId;
-    this.userId = userId;
-    this._id = id;
-    this._BigBlueButtonGW = bbbgw;
-    this._presenterEndpoint = null;
-    this._ffmpegEndpoint = null;
-    this._voiceBridge = voiceBridge;
-    this._meetingId = meetingId;
-    this._streamUrl = "";
-    this._vw = vw;
-    this._vh = vh;
-    this._presenterCandidatesQueue = [];
-    this._viewersEndpoint = [];
-    this._viewersCandidatesQueue = [];
-    this._status = C.MEDIA_STOPPED;
-    this._rtmpBroadcastStarted = false;
-    this.recording = {};
-    this.isRecorded = false;
-    this._recordingSubPath = 'screenshare';
-
-    this._BigBlueButtonGW.on(C.RECORDING_STATUS_REPLY_MESSAGE_2x+meetingId, (payload) => {
-      Logger.info("[Screenshare] RecordingStatusReply ", payload.recorded);
-
-      if (payload.recorded) {
-        this.isRecorded = true;
-      }
-    });
-  }
-
-  async onIceCandidate (candidate, role, userId) {
-    Logger.debug(LOG_PREFIX, "onIceCandidate", role, userId, candidate);
-    switch (role) {
-      case C.SEND_ROLE:
-        if (this._presenterEndpoint) {
-          try {
-            await this.flushCandidatesQueue(this._presenterEndpoint, this._presenterCandidatesQueue);
-            await this.mcs.addIceCandidate(this._presenterEndpoint, candidate);
-          } catch (err) {
-            this._handleError(LOG_PREFIX, err, role, userId);
-          }
-        } else {
-          Logger.debug(LOG_PREFIX, "Pushing ICE candidate to presenter queue");
-          this._presenterCandidatesQueue.push(candidate);
-        }
-      case C.RECV_ROLE:
-        let endpoint = this._viewersEndpoint[userId];
-        if (endpoint) {
-          try {
-            await this.flushCandidatesQueue(endpoint, this._viewersCandidatesQueue[userId]);
-            await this.mcs.addIceCandidate(endpoint, candidate);
-          } catch (err) {
-            this._handleError(LOG_PREFIX, err, role, userId);
-          }
-        } else {
-          this._viewersCandidatesQueue[userId] = [];
-          Logger.debug(LOG_PREFIX, "Pushing ICE candidate to viewer queue", userId);
-          this._viewersCandidatesQueue[userId].push(candidate);
-        }
-        break;
-      default:
-        Logger.warn(LOG_PREFIX, "Unknown role", role);
-      }
-  }
-
-  flushCandidatesQueue (mediaId, queue) {
-    return new Promise((resolve, reject) => {
-      Logger.debug(LOG_PREFIX, "flushCandidatesQueue", queue);
-      if (mediaId) {
-        let iceProcedures = queue.map((candidate) => {
-          this.mcs.addIceCandidate(mediaId, candidate);
-        });
-
-        return Promise.all(iceProcedures).then(() => {
-          queue = [];
-          resolve();
-        }).catch((err) => {
-          Logger.error(LOG_PREFIX, "ICE candidate could not be added to media controller.", err);
-          reject(err);
-        });
-      }
-    });
-  }
-
-  mediaStateRtp (event) {
-    let msEvent = event.event;
-
-    switch (event.eventTag) {
-      case "MediaStateChanged":
-        break;
-
-      case "MediaFlowOutStateChange":
-        Logger.info('[screenshare]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session ',  event.id);
-        break;
-
-      case "MediaFlowInStateChange":
-        Logger.info('[screenshare]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session ',  event.id);
-        if (msEvent.state === 'FLOWING') {
-          this._onRtpMediaFlowing();
-        }
-        else {
-          this._onRtpMediaNotFlowing();
-        }
-        break;
-
-      default: Logger.warn(LOG_PREFIX, "Unrecognized event", event);
-    }
-  }
-
-  mediaStateWebRtc (event, id) {
-    let msEvent = event.event;
-
-    switch (event.eventTag) {
-      case "OnIceCandidate":
-        let candidate = msEvent.candidate;
-        Logger.debug(LOG_PREFIX, 'Received ICE candidate from mcs-core for media session', event.id, '=>', candidate, "for connection", id);
-
-        this._BigBlueButtonGW.publish(JSON.stringify({
-          connectionId: id,
-          type: C.SCREENSHARE_APP,
-          id : 'iceCandidate',
-          cameraId: this._id,
-          candidate : candidate
-        }), C.FROM_SCREENSHARE);
-
-        break;
-
-      case "MediaStateChanged":
-        break;
-
-      case "MediaFlowOutStateChange":
-      case "MediaFlowInStateChange":
-        Logger.info('[screenshare]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session',  event.id);
-        break;
-
-      default: Logger.warn(LOG_PREFIX, "Unrecognized event", event);
-    }
-  }
-
-  recordingState(event) {
-    const msEvent = event.event;
-    Logger.info('[Recording]', msEvent.type, '[', msEvent.state, ']', 'for recording session', event.id, 'for screenshare', this.streamName);
-  }
-
-  async startRecording() {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const recordingPath = this.getRecordingPath(this._meetingId, this._recordingSubPath, this._voiceBridge);
-        this.recording = await this.mcs.startRecording(this.mcsUserId, this._presenterEndpoint, recordingPath);
-        this.mcs.on('MediaEvent' + this.recording.recordingId, this.recordingState.bind(this));
-        this.sendStartShareEvent();
-        resolve(this.recording);
-      } catch (err) {
-        reject(this._handleError(LOG_PREFIX, err));
-      }
-    });
-  }
-
-  sendStartShareEvent () {
-    let shareEvent = Messaging.generateWebRTCShareEvent('StartWebRTCDesktopShareEvent', this.recording.meetingId, this.recording.filename);
-    this._BigBlueButtonGW.writeMeetingKey(this.recording.meetingId, shareEvent, function(error) {
-      Logger.warn(LOG_PREFIX, 'Error writing START share event error', error);
-    });
-  }
-
-  sendStopShareEvent () {
-    let shareEvent = Messaging.generateWebRTCShareEvent('StopWebRTCDesktopShareEvent', this.recording.meetingId, this.recording.filename);
-    this._BigBlueButtonGW.writeMeetingKey(this.recording.meetingId, shareEvent, function(error) {
-      Logger.warn(LOG_PREFIX, 'Error writing STOP share event error', error);
-    });
-  }
-
-  sendGetRecordingStatusRequestMessage(userId) {
-    let req = Messaging.generateRecordingStatusRequestMessage(this._meetingId, userId);
-
-    this._BigBlueButtonGW.publish(req, C.TO_AKKA_APPS);
-  }
-
-  start (sessionId, connectionId, sdpOffer, userId, role) {
-    return new Promise(async (resolve, reject) => {
-      this._status = C.MEDIA_STARTING;
-
-      // Forces H264 with a possible preferred profile
-      if (FORCE_H264) {
-        sdpOffer = h264_sdp.transform(sdpOffer, PREFERRED_H264_PROFILE);
-      }
-
-      // Start the recording process
-      if (SHOULD_RECORD && role === C.SEND_ROLE) {
-        this.sendGetRecordingStatusRequestMessage(userId);
-      }
-
-      Logger.info(LOG_PREFIX, "Starting session", this._voiceBridge + '-' + role);
-      if (!this.mcsUserId) {
-        try {
-          this.mcsUserId = await this.mcs.join(this._meetingId, 'SFU', {});
-          Logger.info(LOG_PREFIX, "MCS Join for", this._id, "returned", this.mcsUserId);
-
-        }
-        catch (error) {
-          Logger.error(LOG_PREFIX, "MCS Join returned error =>", error);
-          return reject(this._handleError(LOG_PREFIX, error, role, userId));
-        }
-      }
-
-      if (role === C.RECV_ROLE) {
-        try {
-          const sdpAnswer = await this._startViewer(connectionId, this._voiceBridge, sdpOffer, userId, this._presenterEndpoint)
-          return resolve(sdpAnswer);
-        }
-        catch (err) {
-          return reject(this._handleError(LOG_PREFIX, err, role, userId));
-        }
-      }
-
-      if (role === C.SEND_ROLE) {
-        try {
-          const sdpAnswer = await this._startPresenter(sdpOffer);
-          return resolve(sdpAnswer);
-        }
-        catch (err) {
-          return reject(this._handleError(LOG_PREFIX, err, role, userId));
-        }
-      }
-    });
-  }
-
-  _startPresenter (sdpOffer) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const retSource = await this.mcs.publish(this.mcsUserId, this._meetingId, 'WebRtcEndpoint', {descriptor: sdpOffer, targetBitrate: SCREENSHARE_TARGET_BITRATE });
-
-        this._presenterEndpoint = retSource.sessionId;
-        sharedScreens[this._voiceBridge] = this._presenterEndpoint;
-        let presenterSdpAnswer = retSource.answer;
-        await this.flushCandidatesQueue(this._presenterEndpoint, this._presenterCandidatesQueue);
-
-        this.mcs.on('MediaEvent' + this._presenterEndpoint, (event) => {
-          this.mediaStateWebRtc(event, this._id)
-        });
-
-        Logger.info(LOG_PREFIX, "MCS publish for user", this.mcsUserId, "returned", this._presenterEndpoint);
-
-        let sendVideoPort = MediaHandler.getVideoPort();
-        let rtpSdpOffer = MediaHandler.generateVideoSdp(localIpAddress, sendVideoPort);
-
-        const retRtp = await this.mcs.subscribe(this.mcsUserId, sharedScreens[this._voiceBridge], 'RtpEndpoint', { descriptor: rtpSdpOffer, keyframeInterval: KEYFRAME_INTERVAL});
-
-        this._ffmpegEndpoint = retRtp.sessionId;
-        rtpEndpoints[this._voiceBridge] = this._ffmpegEndpoint;
-
-        let recvVideoPort = retRtp.answer.match(/m=video\s(\d*)/)[1];
-        this._rtpParams = MediaHandler.generateTranscoderParams(kurentoIp, localIpAddress,
-          sendVideoPort, recvVideoPort, this._meetingId, "stream_type_video", C.RTP_TO_RTMP, "copy", this.userId, this._voiceBridge);
-
-        this.mcs.on('MediaEvent' + this._ffmpegEndpoint, this.mediaStateRtp.bind(this));
-
-        Logger.info(LOG_PREFIX, "MCS subscribe for user", this.mcsUserId, "returned", this._ffmpegEndpoint);
-
-        return resolve(presenterSdpAnswer);
-      }
-      catch (err) {
-        Logger.error(LOG_PREFIX, "MCS publish returned error =>", err);
-        return reject(this._handleError(LOG_PREFIX, err));
-      }
-      finally {
-        this.mcs.once('ServerState' + this._presenterEndpoint, this.serverState.bind(this));
-      }
-    });
-  }
-
-  _startViewer(connectionId, voiceBridge, sdpOffer, userId, presenterEndpoint) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info(LOG_PREFIX, "Starting viewer", userId, "for voiceBridge", this._voiceBridge);
-      let sdpAnswer;
-
-      this._viewersCandidatesQueue[userId] = [];
-
-      try {
-        const retSource = await this.mcs.subscribe(this.mcsUserId, sharedScreens[voiceBridge], 'WebRtcEndpoint', {descriptor: sdpOffer});
-
-        this._viewersEndpoint[userId] = retSource.sessionId;
-        sdpAnswer = retSource.answer;
-        await this.flushCandidatesQueue(this._viewersEndpoint[userId], this._viewersCandidatesQueue[userId]);
-
-        this.mcs.on('MediaEvent' + this._viewersEndpoint[userId], (event) => {
-          this.mediaStateWebRtc(event, connectionId);
-        });
-
-        Logger.info(LOG_PREFIX, "MCS subscribe returned for user", this.mcsUserId, "returned", this._viewersEndpoint[userId], "at userId", userId);
-        return resolve(sdpAnswer);
-      }
-      catch (err) {
-        Logger.error(LOG_PREFIX, "MCS publish returned error =>", err);
-        return reject(this._handleError(LOG_PREFIX, err));
-      }
-    });
-  }
-
-  stop () {
-    return new Promise(async (resolve, reject) => {
-      try {
-        if (this._status === C.MEDIA_STOPPED) {
-          return resolve();
-        }
-        Logger.info('[screnshare] Stopping and releasing endpoints for MCS user', this.mcsUserId);
-        await this._stopScreensharing();
-        this._status = C.MEDIA_STOPPED;
-
-        Logger.info(LOG_PREFIX, "Leaving mcs room");
-        await this.mcs.leave(this._meetingId, this.mcsUserId);
-        delete sharedScreens[this._presenterEndpoint];
-        this._candidatesQueue = null;
-        this._presenterEndpoint = null;
-        this._ffmpegEndpoint = null;
-        if (this.isRecorded) {
-          this.sendStopShareEvent();
-        }
-        return resolve();
-      }
-      catch (err) {
-        this._handleError(LOG_PREFIX, err);
-        Logger.error(LOG_PREFIX, 'MCS returned an error when trying to leave =>', err);
-        return resolve();
-      }
-    });
-  }
-
-  _stopScreensharing() {
-    return new Promise(async (resolve, reject) => {
-      try {
-        Logger.info(LOG_PREFIX, "Stopping screensharing with status", this._status);
-        const isTranscoderAvailable = await this._BigBlueButtonGW.isChannelAvailable(C.TO_BBB_TRANSCODE_SYSTEM_CHAN);
-        const strm = Messaging.generateStopTranscoderRequestMessage(this._meetingId, this._meetingId);
-
-
-        if (isTranscoderAvailable) {
-          // Interoperability: capturing 1.1 stop_transcoder_reply messages
-          this._BigBlueButtonGW.once(C.STOP_TRANSCODER_REPLY+this._meetingId, async (payload) => {
-            const meetingId = payload[C.MEETING_ID];
-            await this._stopRtmpBroadcast(meetingId);
-            return resolve();
-          });
-
-          // Capturing stop transcoder responses from the 2x model
-          this._BigBlueButtonGW.once(C.STOP_TRANSCODER_RESP_2x+this._meetingId, async (payload) => {
-            const meetingId = payload[C.MEETING_ID_2x];
-            await this._stopRtmpBroadcast(meetingId);
-            return resolve();
-          });
-
-          this._BigBlueButtonGW.publish(strm, C.TO_BBB_TRANSCODE_SYSTEM_CHAN, function(error) {});
-        }
-
-        // Either the transcoder is not available or screensharing couldn't be
-        // correctly started
-        if (this._status != C.MEDIA_STARTED || !isTranscoderAvailable) {
-          this._stopRtmpBroadcast(this._meetingId);
-          return resolve();
-        }
-      }
-      catch (err) {
-        this._handleError(LOG_PREFIX, err);
-        Logger.error(err);
-        resolve();
-      }
-    });
-  }
-
-  async _onRtpMediaFlowing() {
-    if (!this._rtmpBroadcastStarted) {
-      Logger.info(LOG_PREFIX, "RTP Media FLOWING for meeting", this._meetingId);
-      const isTranscoderAvailable = await this._BigBlueButtonGW.isChannelAvailable(C.TO_BBB_TRANSCODE_SYSTEM_CHAN);
-      const strm = Messaging.generateStartTranscoderRequestMessage(this._meetingId, this._meetingId, this._rtpParams);
-
-      // Checking if transcoder is avaiable; if so, transposes the stream to RTMP
-      if (isTranscoderAvailable) {
-        // Interoperability: capturing 1.1 start_transcoder_reply messages
-        this._BigBlueButtonGW.once(C.START_TRANSCODER_REPLY+this._meetingId, (payload) => {
-          let meetingId = payload[C.MEETING_ID];
-          let output = payload["params"].output;
-          this._startRtmpBroadcast(meetingId, output);
-        });
-
-        // Capturing stop transcoder responses from the 2x model
-        this._BigBlueButtonGW.once(C.START_TRANSCODER_RESP_2x+this._meetingId, (payload) => {
-          let meetingId = payload[C.MEETING_ID_2x];
-          let output = payload["params"].output;
-          this._startRtmpBroadcast(meetingId, output);
-        });
-
-        this._BigBlueButtonGW.publish(strm, C.TO_BBB_TRANSCODE_SYSTEM_CHAN, function(error) {});
-      } else {
-        // transcoder is not available, pure WebRTC environment
-        this._startRtmpBroadcast(this._meetingId);
-      }
-
-      if (this._status != C.MEDIA_STARTED) {
-        Logger.info(LOG_PREFIX, 'webRTC started flowing for meeting', this._meetingId);
-        if (this.isRecorded) {
-          this.startRecording();
-        }
-        this._status = C.MEDIA_STARTED;
-      }
-    }
-  };
-
-  _stopRtmpBroadcast (meetingId) {
-    return new Promise((resolve, reject) => {
-      Logger.info(LOG_PREFIX, "_stopRtmpBroadcast for meeting", meetingId);
-      let timestamp = now.format('hhmmss');
-      let dsrstom = Messaging.generateScreenshareRTMPBroadcastStoppedEvent2x(this._voiceBridge,
-        this._voiceBridge, this._streamUrl, this._vw, this._vh, timestamp);
-      this._BigBlueButtonGW.publish(dsrstom, C.FROM_VOICE_CONF_SYSTEM_CHAN);
-      resolve();
-    });
-  }
-
-  _startRtmpBroadcast (meetingId, output) {
-    Logger.info(LOG_PREFIX, "_startRtmpBroadcast for meeting", + meetingId);
-    let timestamp = now.format('hhmmss');
-    this._streamUrl = MediaHandler.generateStreamUrl(localIpAddress, meetingId, output);
-    let dsrbstam = Messaging.generateScreenshareRTMPBroadcastStartedEvent2x(this._voiceBridge,
-      this._voiceBridge, this._streamUrl, this._vw, this._vh, timestamp);
-
-    this._BigBlueButtonGW.publish(dsrbstam, C.FROM_VOICE_CONF_SYSTEM_CHAN, function(error) {});
-    this._rtmpBroadcastStarted = true;
-  }
-
-  _onRtpMediaNotFlowing() {
-    Logger.warn(LOG_PREFIX, "TODO RTP NOT_FLOWING");
-  }
-
-  async stopViewer(id) {
-    let viewer = this._viewersEndpoint[id];
-    Logger.info(LOG_PREFIX, 'Releasing endpoints for', viewer);
-
-    if (viewer) {
-      try {
-        await this.mcs.unsubscribe(this.mcsUserId, this.viewer);
-        this._viewersCandidatesQueue[id] = null;
-        this._viewersEndpoint[id] = null;
-        return;
-      }
-      catch (err) {
-        this._handleError(LOG_PREFIX, err);
-        Logger.error(LOG_PREFIX, 'MCS returned error when trying to unsubscribe', err);
-        return;
-      }
-    }
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/lib/utils/Logger.js b/labs/bbb-webrtc-sfu/lib/utils/Logger.js
deleted file mode 100644
index 51f9ccc863f51f4d00e1552215a275f4574e5718..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/utils/Logger.js
+++ /dev/null
@@ -1,48 +0,0 @@
-'use strict';
-
-const Winston = require('winston');
-const Logger = new Winston.Logger();
-const config = require('config');
-const path = require('path');
-Winston.transports.DailyRotateFile = require('winston-daily-rotate-file');
-
-const LOG_CONFIG = config.get('log') || {};
-const { level } = LOG_CONFIG;
-let filename = LOG_CONFIG.filename;
-
-Logger.configure({
-  levels: { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, trace: 5 },
-  colors: {
-    error: 'red',
-    warn: 'yellow',
-    info: 'green',
-    verbose: 'cyan',
-    debug: 'magenta',
-    trace: 'gray'
-  },
-});
-
-Logger.add(Winston.transports.Console, {
-  timestamp:true,
-  prettyPrint: false,
-  humanReadableUnhandledException: true,
-  colorize: true,
-  handleExceptions: false,
-  silent: false,
-  stringify: (obj) => JSON.stringify(obj),
-  level,
-});
-
-
-if (filename) {
-  Logger.add(Winston.transports.DailyRotateFile, {
-    filename,
-    prettyPrint: true,
-    datePattern: '.yyyy-dd-MM',
-    prepend: false,
-    stringify: (obj) => JSON.stringify(obj), // single lines
-    level,
-  });
-}
-
-module.exports = Logger;
diff --git a/labs/bbb-webrtc-sfu/lib/utils/Utils.js b/labs/bbb-webrtc-sfu/lib/utils/Utils.js
deleted file mode 100644
index 9faed84b89a4294062ac29c4e0d6a8b8181c46f8..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/utils/Utils.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- *  * @classdesc
- *   * Utils class for bbb-webrtc-sfu
- *    * @constructor
- *     */
-
-
-/*
- * hrTime
- * Gets monotonic system time in milliseconds
- */
-
-exports.hrTime = function () {
-  let t = process.hrtime();
-
-  return t[0]*1000 + parseInt(t[1]/1000000);
-}
diff --git a/labs/bbb-webrtc-sfu/lib/video/VideoManager.js b/labs/bbb-webrtc-sfu/lib/video/VideoManager.js
deleted file mode 100755
index b61d2c6f5c7a4e5887368b421d1043fc11ee242f..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/video/VideoManager.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-'use strict';
-
-const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
-const Video = require('./video');
-const BaseManager = require('../base/BaseManager');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const errors = require('../base/errors');
-
-module.exports = class VideoManager extends BaseManager {
-  constructor (connectionChannel, additionalChannels, logPrefix) {
-    super(connectionChannel, additionalChannels, logPrefix);
-    this.sfuApp = C.VIDEO_APP;
-    this.messageFactory(this._onMessage);
-  }
-
-  _findByIdAndRole (id, role) {
-    let sesh = null;
-    let keys = Object.keys(this._sessions);
-    keys.forEach((sessionId) => {
-      let session = this._sessions[sessionId];
-      if (sessionId === (session.connectionId + id + '-' + role)) {
-        sesh = session;
-      }
-    });
-    return sesh;
-  }
-
-  setStreamAsRecorded (id) {
-    let video = this._findByIdAndRole(id, 'share');
-
-    if (video) {
-      Logger.info("[VideoManager] Setting ", id, " as recorded");
-      video.setStreamAsRecorded();
-    } else {
-      Logger.warn("[VideoManager] Tried to set stream to recorded but ", id, " has no session!");
-    }
-  }
-
-  async _onMessage (_message) {
-    let message = _message;
-    let connectionId = message.connectionId;
-    let sessionId;
-    let video;
-    let role = message.role? message.role : 'any';
-    let cameraId = message.cameraId;
-    let shared = role === 'share' ? true : false;
-    let iceQueue;
-
-    Logger.debug(this._logPrefix, 'Received message =>', message);
-
-    if (!message.cameraId && message.id !== 'close') {
-      Logger.warn(this._logPrefix, 'Ignoring message with undefined.cameraId for session', sessionId);
-      return;
-    }
-
-    cameraId += '-' + role;
-
-    sessionId = connectionId + cameraId;
-
-    if (message.cameraId) {
-      video = this._fetchSession(sessionId);
-      iceQueue = this._fetchIceQueue(sessionId);
-    }
-
-    switch (message.id) {
-      case 'start':
-        Logger.info(this._logPrefix, 'Received message [' + message.id + '] from connection ' + sessionId);
-
-        if (video) {
-          await this._stopSession(sessionId);
-        }
-
-        video = new Video(this._bbbGW, message.meetingId, message.cameraId, shared, message.connectionId);
-
-        this._sessions[sessionId] = video;
-
-        try {
-          const sdpAnswer = await video.start(message.sdpOffer);
-
-          // Empty ice queue after starting video
-          this._flushIceQueue(video, iceQueue);
-
-          video.once(C.MEDIA_SERVER_OFFLINE, async (event) => {
-            const errorMessage = this._handleError(this._logPrefix, connectionId, message.cameraId, role, errors.MEDIA_SERVER_OFFLINE);
-            this._bbbGW.publish(JSON.stringify({
-              ...errorMessage,
-            }), C.FROM_VIDEO);
-          });
-
-          this._bbbGW.publish(JSON.stringify({
-            connectionId: connectionId,
-            type: 'video',
-            role: role,
-            id : 'startResponse',
-            cameraId: message.cameraId,
-            sdpAnswer : sdpAnswer
-          }), C.FROM_VIDEO);
-        }
-        catch (err) {
-          const errorMessage = this._handleError(this._logPrefix, connectionId, message.cameraId, role, err);
-          return this._bbbGW.publish(JSON.stringify({
-            ...errorMessage
-          }), C.FROM_VIDEO);
-        }
-        break;
-
-      case 'stop':
-        this._stopSession(sessionId);
-        break;
-
-      case 'pause':
-        if (video) {
-          video.pause(message.state);
-        }
-        break;
-
-      case 'onIceCandidate':
-        if (video && video.constructor === Video) {
-          video.onIceCandidate(message.candidate);
-        } else {
-          Logger.info(this._logPrefix, "Queueing ice candidate for later in video", cameraId);
-          iceQueue.push(message.candidate);
-        }
-        break;
-
-      case 'close':
-        Logger.info(this._logPrefix, "Closing sessions of connection", connectionId);
-        this._killConnectionSessions(connectionId);
-        break;
-
-      default:
-        const errorMessage = this._handleError(this._logPrefix, connectionId, null, null, errors.SFU_INVALID_REQUEST);
-        this._bbbGW.publish(JSON.stringify({
-          ...errorMessage,
-        }), C.FROM_VIDEO);
-        break;
-    }
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js b/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js
deleted file mode 100644
index 04b7f78b4a1762a04196a6b4468a6eacfaa4be20..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict';
-
-const VideoManager= require('./VideoManager');
-const BaseProcess = require('../base/BaseProcess');
-const C = require('../bbb/messages/Constants');
-
-const manager = new VideoManager(C.TO_VIDEO, [C.FROM_AKKA_APPS], C.VIDEO_MANAGER_PREFIX);
-const newProcess = new BaseProcess(manager, C.VIDEO_PROCESS_PREFIX);
-
-newProcess.start();
diff --git a/labs/bbb-webrtc-sfu/lib/video/video.js b/labs/bbb-webrtc-sfu/lib/video/video.js
deleted file mode 100644
index 81be7b83e160d0ba82c73d009e21cd4c58ba29d1..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/video/video.js
+++ /dev/null
@@ -1,332 +0,0 @@
-'use strict';
-
-const config = require('config');
-const kurentoUrl = config.get('kurentoUrl');
-const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
-const C = require('../bbb/messages/Constants');
-const Logger = require('../utils/Logger');
-const Messaging = require('../bbb/messages/Messaging');
-const h264_sdp = require('../h264-sdp');
-const PREFERRED_H264_PROFILE = config.get('webcam-preferred-h264-profile');
-const BaseProvider = require('../base/BaseProvider');
-const FORCE_H264 = config.get('webcam-force-h264');
-const WEBCAM_TARGET_BITRATE = config.get('webcam-target-bitrate');
-const SHOULD_RECORD = config.get('recordWebcams');
-const LOG_PREFIX = "[video]";
-
-let sharedWebcams = {};
-
-module.exports = class Video extends BaseProvider {
-  constructor(_bbbGW, _meetingId, _id, _shared, _connectionId) {
-    super();
-    this.sfuApp = C.VIDEO_APP;
-    this.mcs = new MCSApi();
-    this.bbbGW = _bbbGW;
-    this.id = _id;
-    this.connectionId = _connectionId;
-    this.meetingId = _meetingId;
-    this.shared = _shared;
-    this.role = this.shared? 'share' : 'viewer'
-    this.streamName = this.connectionId + this.id + "-" + this.role;
-    this.mediaId = null;
-    this.iceQueue = null;
-    this.status = C.MEDIA_STOPPED;
-    this.recording = {};
-    this.isRecorded = false;
-    this._recordingSubPath = 'recordings';
-    this._cameraProfile = 'medium';
-
-    this.candidatesQueue = [];
-    this.notFlowingTimeout = null;
-
-    this.bbbGW.once(C.RECORDING_STATUS_REPLY_MESSAGE_2x+this.meetingId, (payload) => {
-      Logger.info(LOG_PREFIX, "RecordingStatusReply userId:", payload.requestedBy, "recorded:", payload.recorded);
-
-      if (payload.requestedBy === this.id && payload.recorded) {
-        this.isRecorded = true;
-      }
-    });
-  }
-
-  _randomTimeout (low, high) {
-    return parseInt(Math.random() * (high - low) + low);
-  }
-
-  async onIceCandidate (_candidate) {
-    if (this.mediaId) {
-      try {
-        await this.flushCandidatesQueue();
-        await this.mcs.addIceCandidate(this.mediaId, _candidate);
-      }
-      catch (err)   {
-        this._handleError(LOG_PREFIX, err, this.role, this.id);
-        Logger.error(LOG_PREFIX, "ICE candidate could not be added to media controller.", err);
-      }
-    }
-    else {
-      this.candidatesQueue.push(_candidate);
-    }
-  };
-
-  async flushCandidatesQueue () {
-    return new Promise((resolve, reject) => {
-      if (this.mediaId) {
-        let iceProcedures = this.candidatesQueue.map((candidate) => {
-          this.mcs.addIceCandidate(this.mediaId, candidate);
-        });
-
-        return Promise.all(iceProcedures).then(() => {
-          this.candidatesQueue = [];
-          resolve();
-        }).catch((err) => {
-          Logger.error(LOG_PREFIX, "ICE candidate could not be added to media controller.", err);
-          reject(this._handleError(LOG_PREFIX, err, this.role, this.id));
-        });
-      }
-    });
-  }
-
-  mediaState (event) {
-    let msEvent = event.event;
-
-    switch (event.eventTag) {
-
-      case "OnIceCandidate":
-        let candidate = msEvent.candidate;
-        Logger.debug(LOG_PREFIX, "Sending ICE candidate to user", this.streamName, "with candidate", candidate);
-        this.bbbGW.publish(JSON.stringify({
-          connectionId: this.connectionId,
-          type: 'video',
-          role: this.role,
-          id : 'iceCandidate',
-          cameraId: this.id,
-          candidate: candidate
-        }), C.FROM_VIDEO);
-        break;
-
-      case "MediaStateChanged":
-        break;
-
-      case "MediaFlowOutStateChange":
-      case "MediaFlowInStateChange":
-        Logger.info(LOG_PREFIX, ' ' + msEvent.type + '[' + msEvent.state + ']' + ' for media session', event.id, "for video", this.streamName);
-
-        if (msEvent.state === 'NOT_FLOWING' && this.status !== C.MEDIA_PAUSED) {
-          Logger.warn(LOG_PREFIX, "Setting up a timeout for", this.streamName);
-          if (!this.notFlowingTimeout) {
-            this.notFlowingTimeout = setTimeout(() => {
-
-              if (this.shared) {
-                this.sendPlayStop();
-                this.status = C.MEDIA_STOPPED;
-                clearTimeout(this.notFlowingTimeout);
-                delete this.notFlowingTimeout;
-              }
-            }, config.get('mediaFlowTimeoutDuration') + this._randomTimeout(-2000, 2000));
-          }
-        }
-        else if (msEvent.state === 'FLOWING') {
-          if (this.notFlowingTimeout) {
-            Logger.warn(LOG_PREFIX, "Received a media flow before stopping", this.streamName);
-            clearTimeout(this.notFlowingTimeout);
-            delete this.notFlowingTimeout;
-          }
-          if (this.status !== C.MEDIA_STARTED) {
-
-            // Record the video stream if it's the original being shared
-            if (this.shouldRecord()) {
-              this.startRecording();
-            }
-
-            this.sendPlayStart();
-
-            this.status = C.MEDIA_STARTED;
-          }
-
-        }
-        break;
-
-      default: Logger.warn(LOG_PREFIX, "Unrecognized event", event);
-    }
-  }
-
-  sendPlayStart () {
-    this.bbbGW.publish(JSON.stringify({
-       connectionId: this.connectionId,
-       type: 'video',
-       role: this.role,
-       id : 'playStart',
-       cameraId: this.id,
-    }), C.FROM_VIDEO);
-  }
-
-  sendPlayStop () {
-    let userCamEvent =
-      Messaging.generateUserCamBroadcastStoppedEventMessage2x(this.meetingId, this.id, this.id);
-    this.bbbGW.publish(userCamEvent, function(error) {});
-
-    this.bbbGW.publish(JSON.stringify({
-      connectionId: this.connectionId,
-      type: 'video',
-      role: this.role,
-      id : 'playStop',
-      cameraId: this.id,
-    }), C.FROM_VIDEO);
-  }
-
-  sendGetRecordingStatusRequestMessage() {
-    let req = Messaging.generateRecordingStatusRequestMessage(this.meetingId, this.id);
-
-    this.bbbGW.publish(req, C.TO_AKKA_APPS);
-  }
-
-  shouldRecord () {
-    return this.isRecorded && this.shared;
-  }
-
-  async startRecording() {
-    return new Promise(async (resolve, reject) => {
-      try {
-        const recordingName = this._cameraProfile + '-' + this.id;
-        const recordingPath = this.getRecordingPath(this.meetingId, this._recordingSubPath, recordingName);
-        this.recording = await this.mcs.startRecording(this.userId, this.mediaId, recordingPath);
-        this.mcs.on('MediaEvent' + this.recording.recordingId, this.recordingState.bind(this));
-        this.sendStartShareEvent();
-        resolve(this.recording);
-      }
-      catch (err) {
-        Logger.error(LOG_PREFIX, "Error on start recording with message", err);
-        reject(this._handleError(LOG_PREFIX, err, this.role, this.id));
-      }
-    });
-  }
-
-  async stopRecording() {
-    await this.mcs.stopRecording(this.userId, this.mediaId, this.recording.recordingId);
-    this.sendStopShareEvent();
-    this.recording = {};
-  }
-
-  recordingState(event) {
-    const msEvent = event.event;
-    Logger.info('[Recording]', msEvent.type, '[', msEvent.state, ']', 'for recording session', event.id, 'for video', this.streamName);
-  }
-
-  start (sdpOffer) {
-    return new Promise(async (resolve, reject) => {
-      Logger.info(LOG_PREFIX, "Starting video instance for", this.streamName);
-
-      // Force H264
-      if (FORCE_H264) {
-        sdpOffer = h264_sdp.transform(sdpOffer, PREFERRED_H264_PROFILE);
-      }
-
-      // Start the recording process
-      if (SHOULD_RECORD && this.shared) {
-        this.sendGetRecordingStatusRequestMessage();
-      }
-
-      try {
-        this.userId = await this.mcs.join(this.meetingId, 'SFU', {});
-        Logger.info(LOG_PREFIX, "MCS join for", this.streamName, "returned", this.userId);
-        const sdpAnswer = await this._addMCSMedia(C.WEBRTC, sdpOffer);
-        this.mcs.on('MediaEvent' + this.mediaId, this.mediaState.bind(this));
-        this.mcs.on('ServerState' + this.mediaId, this.serverState.bind(this));
-        this.status = C.MEDIA_STARTING;
-        await this.flushCandidatesQueue();
-        Logger.info(LOG_PREFIX, "MCS call for user", this.userId, "returned", this.mediaId);
-        return resolve(sdpAnswer);
-      }
-      catch (err) {
-        reject(this._handleError(LOG_PREFIX, err, this.role, this.id));
-      }
-    });
-  }
-
-  _addMCSMedia (type, descriptor) {
-    return new Promise(async (resolve, reject) => {
-      try {
-        if (this.shared) {
-          let { answer, sessionId } = await this.mcs.publish(this.userId, this.meetingId, type, { descriptor, targetBitrate: WEBCAM_TARGET_BITRATE });
-          this.mediaId = sessionId;
-          sharedWebcams[this.id] = this.mediaId;
-          return resolve(answer);
-        }
-        else if (sharedWebcams[this.id]) {
-          let { answer, sessionId } = await this.mcs.subscribe(this.userId, sharedWebcams[this.id], C.WEBRTC, { descriptor });
-          this.mediaId = sessionId;
-          return resolve(answer);
-        }
-      }
-      catch (err) {
-        err = this._handleError(LOG_PREFIX, err, this.role, this.id)
-        reject(err);
-      }
-    });
-  }
-
-  async pause (state) {
-    const sourceId = sharedWebcams[this.id];
-    const sinkId = this.mediaId;
-
-    if (sourceId == null || sinkId == null) {
-      Logger.error(LOG_PREFIX, "Source or sink is null.");
-      return;
-    }
-
-    // We want to pause the stream
-    try {
-      if (state && (this.status !== C.MEDIA_STARTING || this.status !== C.MEDIA_PAUSED)) {
-        await this.mcs.disconnect(sourceId, sinkId, 'VIDEO');
-        this.status = C.MEDIA_PAUSED;
-      }
-      else if (!state && this.status === C.MEDIA_PAUSED) { //un-pause
-        await this.mcs.connect(sourceId, sinkId, 'VIDEO');
-        this.status = C.MEDIA_STARTED;
-      }
-    }
-    catch (err) {
-      this._handleError(LOG_PREFIX, err, this.role, this.id);
-    }
-  }
-
-  sendStartShareEvent() {
-    let shareCamEvent = Messaging.generateWebRTCShareEvent('StartWebRTCShareEvent', this.meetingId, this.recording.filename);
-    this.bbbGW.writeMeetingKey(this.meetingId, shareCamEvent, function(error) {});
-  }
-
-  sendStopShareEvent () {
-    let stopShareEvent =
-      Messaging.generateWebRTCShareEvent('StopWebRTCShareEvent', this.meetingId, this.recording.filename);
-    this.bbbGW.writeMeetingKey(this.meetingId, stopShareEvent, function(error) {});
-  }
-
-  async stop () {
-    return new Promise(async (resolve, reject) => {
-      Logger.info(LOG_PREFIX, 'Stopping video session', this.userId, 'at room', this.meetingId);
-
-      try {
-        await this.mcs.leave(this.meetingId, this.userId);
-
-        if (this.shouldRecord()) {
-          this.sendStopShareEvent();
-        }
-
-        if (this.shared) {
-          delete sharedWebcams[this.id];
-        }
-
-        if (this.notFlowingTimeout) {
-          clearTimeout(this.notFlowingTimeout);
-          delete this.notFlowingTimeout;
-        }
-
-        delete this._candidatesQueue;
-        resolve();
-      }
-      catch (err) {
-        reject(this._handleError(LOG_PREFIX, err, this.role, this.id));
-      }
-    });
-  }
-};
diff --git a/labs/bbb-webrtc-sfu/package-lock.json b/labs/bbb-webrtc-sfu/package-lock.json
deleted file mode 100644
index 667d138dcc4c024982bf66cb8ff9ac482ea1586c..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/package-lock.json
+++ /dev/null
@@ -1,443 +0,0 @@
-{
-  "name": "bbb-webrtc-sfu",
-  "version": "0.0.5",
-  "lockfileVersion": 1,
-  "requires": true,
-  "dependencies": {
-    "argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "requires": {
-        "sprintf-js": "1.0.3"
-      }
-    },
-    "asap": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-    },
-    "async": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz",
-      "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=",
-      "requires": {
-        "lodash": "4.17.10"
-      }
-    },
-    "async-limiter": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
-      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
-    },
-    "backoff": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.3.0.tgz",
-      "integrity": "sha1-7nx+OAk/kuRyhZ22NedlJFT8Ieo="
-    },
-    "bindings": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
-      "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
-    },
-    "bufferutil": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.2.1.tgz",
-      "integrity": "sha1-N75dNuHgZJIiHmjUdLGsWOUQy9c=",
-      "requires": {
-        "bindings": "1.2.1",
-        "nan": "2.10.0"
-      }
-    },
-    "colors": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
-      "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
-    },
-    "commander": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
-      "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E="
-    },
-    "config": {
-      "version": "1.30.0",
-      "resolved": "https://registry.npmjs.org/config/-/config-1.30.0.tgz",
-      "integrity": "sha1-HWCp81NIoTwXV5jThOgaWhbDum4=",
-      "requires": {
-        "json5": "0.4.0",
-        "os-homedir": "1.0.2"
-      }
-    },
-    "cycle": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
-      "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI="
-    },
-    "double-ended-queue": {
-      "version": "2.1.0-0",
-      "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
-      "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw="
-    },
-    "error-tojson": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/error-tojson/-/error-tojson-0.0.1.tgz",
-      "integrity": "sha1-p7GqlP/ADpB4wuuibiBL2Hzyy7k="
-    },
-    "es6-promise": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
-      "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ=="
-    },
-    "esprima": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
-      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
-    },
-    "extend": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
-      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
-    },
-    "eyes": {
-      "version": "0.1.8",
-      "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
-      "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A="
-    },
-    "inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-    },
-    "isbuffer": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/isbuffer/-/isbuffer-0.0.0.tgz",
-      "integrity": "sha1-OMFG2d9Si4v5sHAcPUPPEt8/w5s="
-    },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
-    },
-    "js-yaml": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
-      "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
-      "requires": {
-        "argparse": "1.0.10",
-        "esprima": "4.0.0"
-      }
-    },
-    "json5": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz",
-      "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0="
-    },
-    "kurento-client": {
-      "version": "git+https://github.com/mconf/kurento-client-js.git#09986b21db44fdc015706d7b01bece1728094d4c",
-      "requires": {
-        "async": "2.0.1",
-        "error-tojson": "0.0.1",
-        "es6-promise": "4.2.4",
-        "extend": "3.0.1",
-        "inherits": "2.0.3",
-        "kurento-client-core": "git+https://github.com/mconf/kurento-client-core-js.git#3bfcff9cb21430a4f451239100b4c306b9705757",
-        "kurento-client-elements": "git+https://github.com/mconf/kurento-client-elements-js.git#8db04d5a31c299c9c6bacdfbc8fb358ad1c80fbb",
-        "kurento-client-filters": "github:Kurento/kurento-client-filters-js#67d43d4fca03c6002015448973c3e6d82e14cb3c",
-        "kurento-jsonrpc": "github:Kurento/kurento-jsonrpc-js#1cdb36884ca8f096d21c335f28129a5449214e7b",
-        "minimist": "1.2.0",
-        "promise": "7.1.1",
-        "promisecallback": "0.0.4",
-        "reconnect-ws": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a"
-      },
-      "dependencies": {
-        "kurento-client-core": {
-          "version": "git+https://github.com/mconf/kurento-client-core-js.git#3bfcff9cb21430a4f451239100b4c306b9705757"
-        },
-        "kurento-client-elements": {
-          "version": "git+https://github.com/mconf/kurento-client-elements-js.git#8db04d5a31c299c9c6bacdfbc8fb358ad1c80fbb"
-        },
-        "kurento-client-filters": {
-          "version": "github:Kurento/kurento-client-filters-js#67d43d4fca03c6002015448973c3e6d82e14cb3c"
-        },
-        "kurento-jsonrpc": {
-          "version": "github:Kurento/kurento-jsonrpc-js#1cdb36884ca8f096d21c335f28129a5449214e7b",
-          "requires": {
-            "bufferutil": "1.2.1",
-            "inherits": "2.0.3",
-            "utf-8-validate": "1.2.2",
-            "ws": "1.1.5"
-          }
-        },
-        "reconnect-core": {
-          "version": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
-          "requires": {
-            "backoff": "2.3.0"
-          }
-        },
-        "reconnect-ws": {
-          "version": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a",
-          "requires": {
-            "reconnect-core": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
-            "websocket-stream": "0.5.1"
-          }
-        },
-        "ws": {
-          "version": "1.1.5",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
-          "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
-          "requires": {
-            "options": "0.0.6",
-            "ultron": "1.0.2"
-          }
-        }
-      }
-    },
-    "lodash": {
-      "version": "4.17.10",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
-      "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
-    },
-    "minimist": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
-    },
-    "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "requires": {
-        "minimist": "0.0.8"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
-        }
-      }
-    },
-    "moment": {
-      "version": "2.22.1",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz",
-      "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ=="
-    },
-    "nan": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
-      "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
-    },
-    "nanoid": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.0.1.tgz",
-      "integrity": "sha512-BXapDjcA0QjUPLBqcC5EcvwB8LMOY7zXf3UqDGp93R73PoMOfipmRVxpTogAhtqViE/pJzP9bS+jGK31rzkE2w=="
-    },
-    "options": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
-      "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
-    },
-    "os-homedir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
-    },
-    "promiscuous": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/promiscuous/-/promiscuous-0.6.0.tgz",
-      "integrity": "sha1-VAFM09Ysr+gx4zVJkMBf9beMiJI=",
-      "optional": true
-    },
-    "promise": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz",
-      "integrity": "sha1-SJZUxpJha4qlWwck+oCbt9tJxb8=",
-      "requires": {
-        "asap": "2.0.6"
-      }
-    },
-    "promisecallback": {
-      "version": "0.0.4",
-      "resolved": "https://registry.npmjs.org/promisecallback/-/promisecallback-0.0.4.tgz",
-      "integrity": "sha1-uTTxPATkQ2IrTWbeTkLqX2zmbnQ="
-    },
-    "readable-id": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/readable-id/-/readable-id-1.0.0.tgz",
-      "integrity": "sha512-RXwuv4YQNYByl+PpQVA4PR4H+aGTWOtpRx56LrxJ2Ypxf96u9WaIdKGOCqu7MPBt8iqQkYPQUk4KGbL55n78YQ==",
-      "requires": {
-        "nanoid": "1.0.1"
-      }
-    },
-    "redis": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
-      "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==",
-      "requires": {
-        "double-ended-queue": "2.1.0-0",
-        "redis-commands": "1.3.1",
-        "redis-parser": "2.6.0"
-      }
-    },
-    "redis-commands": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz",
-      "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs="
-    },
-    "redis-parser": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz",
-      "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs="
-    },
-    "safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
-    },
-    "sdp-transform": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.4.1.tgz",
-      "integrity": "sha512-dCReSJ6NtCW6goKkKBEHcIknBS1pKejnMw+S3p3jl0PALPFrbjbreCyQ+CABtFxl2GXD2/05+C2q2gZP23dUWQ=="
-    },
-    "sip.js": {
-      "version": "0.7.5",
-      "resolved": "https://registry.npmjs.org/sip.js/-/sip.js-0.7.5.tgz",
-      "integrity": "sha1-hqznBRWU+RtFUb24EgoWxEli06I=",
-      "requires": {
-        "promiscuous": "0.6.0",
-        "ws": "0.6.5"
-      },
-      "dependencies": {
-        "nan": {
-          "version": "1.4.3",
-          "resolved": "https://registry.npmjs.org/nan/-/nan-1.4.3.tgz",
-          "integrity": "sha1-xWtUBGmAY2lvWXQ1+RY8MSrqUAk="
-        },
-        "ws": {
-          "version": "0.6.5",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-0.6.5.tgz",
-          "integrity": "sha1-8AhEAByjk7ADaB/zKDjnKlYNr9Q=",
-          "requires": {
-            "nan": "1.4.3",
-            "options": "0.0.6",
-            "ultron": "1.0.2"
-          }
-        }
-      }
-    },
-    "sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
-    },
-    "stack-trace": {
-      "version": "0.0.10",
-      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
-      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
-    },
-    "through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
-    },
-    "tinycolor": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz",
-      "integrity": "sha1-MgtaUtg6u1l42Bo+iH1K77FaYWQ="
-    },
-    "ultron": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
-      "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
-    },
-    "utf-8-validate": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.2.2.tgz",
-      "integrity": "sha1-i7hxpHQeCFxwSHynrNvX1tNgKes=",
-      "requires": {
-        "bindings": "1.2.1",
-        "nan": "2.4.0"
-      },
-      "dependencies": {
-        "nan": {
-          "version": "2.4.0",
-          "resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz",
-          "integrity": "sha1-+zxZ1F/k7/4hXwuJD4rfbrMtIjI="
-        }
-      }
-    },
-    "websocket-stream": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-0.5.1.tgz",
-      "integrity": "sha1-YizR8FZvuEzgpNb4VFJvPcTXDkg=",
-      "requires": {
-        "isbuffer": "0.0.0",
-        "through": "2.3.8",
-        "ws": "0.4.32"
-      },
-      "dependencies": {
-        "nan": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz",
-          "integrity": "sha1-riT4hQgY1mL8q1rPfzuVv6oszzg="
-        },
-        "ws": {
-          "version": "0.4.32",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-0.4.32.tgz",
-          "integrity": "sha1-eHphVEFPPJntg8V3IVOyD+sM7DI=",
-          "requires": {
-            "commander": "2.1.0",
-            "nan": "1.0.0",
-            "options": "0.0.6",
-            "tinycolor": "0.0.1"
-          }
-        }
-      }
-    },
-    "winston": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.2.tgz",
-      "integrity": "sha512-4S/Ad4ZfSNl8OccCLxnJmNISWcm2joa6Q0YGDxlxMzH0fgSwWsjMt+SmlNwCqdpaPg3ev1HKkMBsIiXeSUwpbA==",
-      "requires": {
-        "async": "1.0.0",
-        "colors": "1.0.3",
-        "cycle": "1.0.3",
-        "eyes": "0.1.8",
-        "isstream": "0.1.2",
-        "stack-trace": "0.0.10"
-      },
-      "dependencies": {
-        "async": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
-          "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
-        }
-      }
-    },
-    "winston-daily-rotate-file": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-1.7.2.tgz",
-      "integrity": "sha1-ZQK/opeCT9mC2l5WR8dThXjS+aA=",
-      "requires": {
-        "mkdirp": "0.5.1"
-      }
-    },
-    "ws": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
-      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
-      "requires": {
-        "async-limiter": "1.0.0",
-        "safe-buffer": "5.1.2",
-        "ultron": "1.1.1"
-      },
-      "dependencies": {
-        "ultron": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
-          "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
-        }
-      }
-    }
-  }
-}
diff --git a/labs/bbb-webrtc-sfu/package.json b/labs/bbb-webrtc-sfu/package.json
deleted file mode 100644
index 18d8b264aef5958cc5bcff871f82061cf7b071bd..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "bbb-webrtc-sfu",
-  "version": "0.0.5",
-  "private": true,
-  "scripts": {
-    "start": "node server.js"
-  },
-  "dependencies": {
-    "config": "^1.30.0",
-    "js-yaml": "^3.11.0",
-    "kurento-client": "git+https://github.com/mconf/kurento-client-js.git#mconf",
-    "moment": "^2.22.1",
-    "readable-id": "^1.0.0",
-    "redis": "^2.8.0",
-    "sdp-transform": "^2.4.1",
-    "winston": "^2.4.2",
-    "winston-daily-rotate-file": "^1.7.2",
-    "ws": "^3.3.3",
-    "sip.js": "0.7.5"
-  },
-  "optionalDependencies": {}
-}
diff --git a/labs/bbb-webrtc-sfu/server.js b/labs/bbb-webrtc-sfu/server.js
deleted file mode 100755
index 0e04fad4c4dd03f72d06bd2864b229fb76ab1a20..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/server.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Lucas Fialho Zawacki
- * Paulo Renato Lanzarin
- * (C) Copyright 2017 Bigbluebutton
- *
- */
-
-'use strict';
-
-const ConnectionManager = require('./lib/connection-manager/ConnectionManager');
-const HttpServer = require('./lib/connection-manager/HttpServer');
-const server = new HttpServer();
-const WebsocketConnectionManager = require('./lib/connection-manager/WebsocketConnectionManager');
-const Logger = require('./lib/utils/Logger');
-const ProcessManager = require('./lib/ProcessManager.js');
-const PM = new ProcessManager();
-
-PM.start();
-
-const CM = new ConnectionManager(PM.screenshareProcess, PM.videoProcess);
-
-let websocketManager = new WebsocketConnectionManager(server.getServerObject(), '/bbb-webrtc-sfu');
-
-CM.setHttpServer(server);
-CM.addAdapter(websocketManager);
-
-CM.listen(() => {
-  Logger.info("[MainProcess] Server started");
-});