diff --git a/chaos_monkey/monkey.py b/chaos_monkey/monkey.py
index be7184ad3..482211b81 100644
--- a/chaos_monkey/monkey.py
+++ b/chaos_monkey/monkey.py
@@ -162,6 +162,9 @@ class ChaosMonkey(object):
                             break
                         else:
                             LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__)
+                            ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__,
+                                                                     'exploiter': exploiter.__class__.__name__})
+
                     except Exception, exc:
                         LOG.error("Exception while attacking %s using %s: %s",
                                   machine, exploiter.__class__.__name__, exc)
@@ -169,7 +172,7 @@ class ChaosMonkey(object):
 
                 if successful_exploiter:
                     self._exploited_machines.add(machine)
-                    ControlClient.send_telemetry('exploit', {'machine': machine.__dict__,
+                    ControlClient.send_telemetry('exploit', {'result': True, 'machine': machine.__dict__,
                                                              'exploiter': successful_exploiter.__class__.__name__})
 
                     LOG.info("Successfully propagated to %s using %s",
diff --git a/monkey_business/readme.txt b/monkey_business/readme.txt
index 6f456df9e..b00d16469 100644
--- a/monkey_business/readme.txt
+++ b/monkey_business/readme.txt
@@ -1,4 +1,45 @@
-dependencies:
-sudo pip install pyVmomi
-sudo pip install celery
-sudo pip install -U celery[mongodb]
\ No newline at end of file
+How to install Monkey Business server:
+
+---------------- On Linux ----------------:
+1. Create the following directories:
+    sudo mkdir /var/monkey_business
+    sudo chmod 777 /var/monkey_business
+    mkdir -p /var/monkey_business/bin/mongodb
+    mkdir -p /var/monkey_business/db
+    mkdir -p /var/monkey_business/cc
+
+2. Install the following packages:
+	sudo pip install flask
+	sudo pip install Flask-Pymongo
+	sudo pip install Flask-Restful
+	sudo pip install python-dateutil
+	sudo pip install pyVmomi
+	sudo pip install celery
+	sudo pip install -U celery[mongodb]
+
+4. Download MongoDB and extract it to /var/monkey_business/bin/mongodb
+    for debian64 - https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-debian71-3.0.7.tgz
+    for ubuntu64 14.10 - https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1410-clang-3.0.7.tgz
+    find more at - https://www.mongodb.org/downloads#production
+	untar.gz with: tar -zxvf filename.tar.gz -C /var/monkey_business/bin/mongodb
+	(make sure the content of the mongo folder is in this directory, meaning this path exists:
+		/var/monkey_business/bin/mongodb/bin)
+
+5. install OpenSSL
+    sudo apt-get install openssl
+
+6. Generate SSL Certificate, Run create_certificate.sh (located under /linux)
+
+7. Copy monkey business server to /var/monkey_business:
+    cp -r [monkey_island_source]/cc /var/monkey_business/
+
+
+How to run:
+1. run run.sh
+   * This performs:
+   		DB startup:
+			/var/monkey_business/bin/mongodb/bin/mongod --dbpath db --fork --logpath db.log
+		Jobs worker startup:
+			nohup celery -A tasks_manager worker --loglevel=info
+		Main Web Server startup:
+			nohup python main.py
\ No newline at end of file
diff --git a/monkey_island/cc/admin/ui/index.html b/monkey_island/cc/admin/ui/index.html
index d1c79e1d5..c2a8eb2a1 100644
--- a/monkey_island/cc/admin/ui/index.html
+++ b/monkey_island/cc/admin/ui/index.html
@@ -83,8 +83,9 @@
                 </div>
                 <div id="info" class="panel-body panel-collapse collapse in">
                     <div>
-                        Num of Monkeys: <label id="infoNumOfMonkeys">0</label> (<label id="infoNumOfParents">0</label> by exploiting)<br/>
-                        Num of Hosts Detected: <label id="infoNumOfHosts">0</label><br/>
+                        Num of Monkeys: <label id="infoNumOfMonkeys">0</label> (<label id="infoNumOfParents">0</label> exploiting were done)<br/>
+                        Monkyes Alive: <label id="infoNumOfAlive">0</label><br/>
+                        Num of Hosts Not Exploited: <label id="infoNumOfHosts">0</label><br/>
                         Num of Tunnels Used: <label id="infoNumOfTunnels">0</label><br/>
                     </div>
                     <div>
@@ -132,7 +133,7 @@
                     </div>
                     <hr>
                     <div id="selectionInfo">
-                        <label>No selection</label>
+                        <label>Monkey not selected</label>
                     </div>
                     <hr>
                     <div class="panel panel-default">
@@ -188,6 +189,24 @@
         </div>
         <!-- /.Config section -->
 
+        <!-- Config section -->
+        <div class="col-lg-3 col-md-6 col-sm-6">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <a href="#reset" data-toggle="collapse">Reset Database</a>
+                </div>
+                <div id="reset" style="overflow: visible" class="panel-body panel-collapse collapse" aria-expanded="true">
+                    <span class="input-group-btn">
+                        <button id="btnResetDB" class="btn btn-default" type="button"
+                            onclick="resetDB()" style="margin-top:-4px">
+                                Reset Database
+                        </button>
+                    </span>
+                </div>
+            </div>
+        </div>
+        <!-- /.Config section -->
+
     </div>
 
 </body>
diff --git a/monkey_island/cc/admin/ui/js/monkeys-admin.js b/monkey_island/cc/admin/ui/js/monkeys-admin.js
index b98edc16a..c58b4f54e 100644
--- a/monkey_island/cc/admin/ui/js/monkeys-admin.js
+++ b/monkey_island/cc/admin/ui/js/monkeys-admin.js
@@ -62,12 +62,13 @@ function initAdmin() {
     nodes = [];
     edges = [];
 
+    createNodes();
     createEdges();
     createTunnels();
     createScanned();
 
     var data = {
-        nodes: createNodes(),
+        nodes: nodes,
         edges: edges
     };
 
@@ -196,8 +197,19 @@ function updateMonkeys() {
             else
             {
                 monkeys.push(new_monkeys[i]);
-                nodes.push(createMonkeyNode(new_monkeys[i]));
-                updateCounters();
+                var exiting_scan = undefined;
+                for (var j=0; j<new_monkeys[i].ip_addresses.length; j++) {
+                    exiting_scan = getScannedByIP(new_monkeys[i].ip_addresses[j]);
+                    if (exiting_scan != undefined) {
+                        break;
+                    }
+                }
+                if (exiting_scan == undefined) {
+                    nodes.push(createMonkeyNode(new_monkeys[i]));
+                }
+                else {
+                    convertScanNodeToMonkey(exiting_scan, new_monkeys[i]);
+                }
             }
         }
 
@@ -208,6 +220,7 @@ function updateMonkeys() {
             refreshDrawing();
         }
         createScanned();
+        updateCounters();
     });    
 }
 
@@ -238,9 +251,16 @@ function createMonkeyNode(monkey) {
     }
     img = ICONS_DIR + img + ICONS_EXT;
 
-    if (monkey.parent == monkey.guid) {
+    if (monkey.parent == null) {
         font = { color: 'red' };
     }
+    else {
+        for (var i=0; i<monkey.parent.length; i++) {
+            if (monkey.parent[i][1] == null) {
+                font = { color: 'red' };
+            }
+        }
+    }
 
     return {
             'id': monkey.id,
@@ -283,15 +303,52 @@ function createMachineNode(machine) {
         };
 }
 
+function convertScanNodeToMonkey(scanned, monkey) {
+    var monNode = createMonkeyNode(monkey);
+    nodes.push(monNode);
+
+    // move edges to new node
+    for (var i = 0; i < edges.length; i++) {
+        if (edges[i].to == scanned.id) {
+            edges[i].to = monNode.id;
+        }
+        if (edges[i].from == scanned.id) {
+            edges[i].from = monNode.id;
+        }
+    }
+    for (var i=0; i<scannedMachines.length; i++) {
+        if (scannedMachines[i].id == scanned.id) {
+            scannedMachines.splice(i, 1);
+            break;
+        }
+    }
+    for (var i=0; i<nodes.length; i++) {
+        if (nodes[i].id == scanned.id) {
+            nodes.splice(i, 1);
+            break;
+        }
+    }
+}
+
 function createEdges() {
     for (var i = 0; i < monkeys.length; i++) {
         var monkey = monkeys[i];
-        if(monkey.parent != monkey.guid) {
-            var parent = getMonkeyByGuid(monkey.parent);
 
-            if(parent && !edgeExists([parent.id, monkey.id, EDGE_TYPE_PARENT])) {
-                edges.push({from: parent.id, to: monkey.id, arrows:'middle', type: EDGE_TYPE_PARENT, color: EDGE_COLOR_PARENT});
-                numOfParentLinks++;
+        if (monkey.parent == null) { continue; };
+
+        for (var j=0; j<monkey.parent.length; j++) {
+            if(monkey.parent[j][0] != monkey.guid) {
+                var parent = getMonkeyByGuid(monkey.parent[j][0]);
+                var exploit = monkey.parent[j][1];
+
+                if(parent && !edgeExists([parent.id, monkey.id, EDGE_TYPE_PARENT])) {
+                    var title = "<center><b>" + exploit + "</b></center>From: " + parent.hostname + "<br/>To: " + monkey.hostname;
+                    edges.push({from: parent.id, to: monkey.id, arrows:'middle', type: EDGE_TYPE_PARENT, title: title, /*label: exploit, font: {color: 'red', size: 10, align: 'top'},*/ color: EDGE_COLOR_PARENT});
+                    if (removeEdge([parent.id, monkey.id, EDGE_TYPE_SCAN])) {
+                        numOfScanLinks--;
+                    }
+                    numOfParentLinks++;
+                }
             }
         }
     }
@@ -327,24 +384,20 @@ function createScanned() {
             var scan = scans[i];
             var monkey = getMonkeyByGuid(scan.monkey_guid);
 
-            //Check if we already exploited this machine from another PoV, if so no point in scanning.
-            if (null != getMonkeyByIP(scan.data.machine.ip_addr)) {
-                //if so, make sure we don't already have such a node
-                nodes = nodes.filter(function (node) {
-                    return (node.id != ip_addr);
-                });
-                continue;
-            }
+            // And check if we've already added this scanned machine
+            var machineNode = getMonkeyByIP(scan.data.machine.ip_addr);
 
-            //And check if we've already added this scanned machine
-            var machineNode = getScannedByIP(scan.data.machine.ip_addr)
             if (null == machineNode) {
-                machineNode = createMachineNode(scan.data.machine);
-                scannedMachines.push(machineNode);
-                nodes.push(machineNode);
+                machineNode = getScannedByIP(scan.data.machine.ip_addr);
+
+                if (null == machineNode) {
+                    machineNode = createMachineNode(scan.data.machine);
+                    scannedMachines.push(machineNode);
+                    nodes.push(machineNode);
+                }
             }
 
-            if(!edgeExists([monkey.id, machineNode.id, EDGE_TYPE_SCAN])) {
+            if(!edgeExists([monkey.id, machineNode.id, EDGE_TYPE_SCAN]) && !edgeExists([monkey.id, machineNode.id, EDGE_TYPE_PARENT])) {
                 edges.push({from: monkey.id, to: machineNode.id, arrows:'middle', type: EDGE_TYPE_SCAN, color: EDGE_COLOR_SCAN});
                 numOfScanLinks++;
             }
@@ -372,10 +425,34 @@ function buildMonkeyDescription(monkey) {
     }
     html +=
         "<label>Last Seen:</label> " + monkey.keepalive + "</br>" +
-        "<label>IP Address:</label></br>";
+        "<label>IP Address:</label><br/>";
 
+    html += "<ul>";
     for (var i = 0; i < monkey.ip_addresses.length; i++) {
-        html += monkey.ip_addresses[i] + "</br>"
+        html += "<li>" + monkey.ip_addresses[i];
+    }
+    html += "</ul>";
+
+
+    if (monkey.parent != null) {
+        html += "<label>Exploited by:</label><br/>"
+        html += "<ul>";
+        for (var i = 0; i < monkey.parent.length; i++) {
+            html += "<li>";
+            if (monkey.parent[i][0] == monkey.guid) {
+                html += "Manual Run<br/>";
+            }
+            else {
+                parent = getMonkeyByGuid(monkey.parent[i][0]);
+                if (!parent) { html += "Unknown Source"; continue; }
+
+                html +=  parent.hostname + " (";
+                if (monkey.parent[i][1] == null) {html += "Unknown"}
+                else {html += monkey.parent[i][1];}
+                html += ")";
+            }
+        }
+        html += "</ul>";
     }
 
     return html;
@@ -386,6 +463,11 @@ function updateCounters() {
     $('#infoNumOfHosts').html(scannedMachines.length);
     $('#infoNumOfParents').html(numOfParentLinks);
     $('#infoNumOfTunnels').html(numOfTunnelLinks);
+    var numOfAlive = monkeys.length;
+    for (var i=0;i<monkeys.length;i++) {
+        if (monkeys[i].dead) {numOfAlive--;}
+    }
+    $('#infoNumOfAlive').html(numOfAlive);
 }
 
 
@@ -451,22 +533,22 @@ function onDoubleClick(properties) {
  */
 function onSelect(properties) {
 
-    if (properties.nodes.length > 0) {
+    if ((properties.nodes.length > 0) && getMonkey(properties.nodes[0])){
         onNodeSelect(properties.nodes);
     }
     else
     {
-        var content = "<b>No selection</b>"
+        var content = "<b>Monkey not selected</b>"
         $("#selectionInfo").html(content);
         $('#monkey-config').hide()
         $('#btnConfigLoad, #btnConfigUpdate').hide();
         $('#monkey-enabled').hide();
         telemTable.clear();
         telemTable.draw();
-    }
 
-    if (properties.edges.length > 0) {
-        onEdgeSelect(properties.edges);
+        if (properties.edges.length > 0) {
+            onEdgeSelect(properties.edges);
+        }
     }
 
 }
@@ -483,33 +565,32 @@ function onNodeSelect(nodeId) {
     if (monkey) {
         htmlContent = buildMonkeyDescription(monkey);
         $("#monkeySearch").val(monkey.hostname);
+        $("#selectionInfo").html(htmlContent);
+        $('#monkey-config').show()
+        $('#btnConfigLoad, #btnConfigUpdate').show();
+
+        loadMonkeyConfig();
+
+        if (monkey.config.alive) {
+            $("[name='chboxMonkeyEnabled']").bootstrapSwitch('state', true, true);
+        }
+        else {
+            $("[name='chboxMonkeyEnabled']").bootstrapSwitch('state', false, true);
+        }
+        $('#monkey-enabled').show();
+
+        $.getJSON('/api/telemetry?monkey_guid=' + monkey.guid, function(json) {
+            telemTable.clear();
+            var telemetries = json.objects;
+
+            for (var i = 0; i < telemetries.length; i++) {
+                telemTable.row.add([telemetries[i].timestamp, telemetries[i].telem_type, JSON.stringify(telemetries[i].data)]);
+            }
+
+            telemTable.draw();
+        });
     }
 
-    $("#selectionInfo").html(htmlContent);
-    $('#monkey-config').show()
-    $('#btnConfigLoad, #btnConfigUpdate').show();
-
-    loadMonkeyConfig();
-
-    if (monkey.config.alive) {
-        $("[name='chboxMonkeyEnabled']").bootstrapSwitch('state', true);
-    }
-    else {
-        $("[name='chboxMonkeyEnabled']").bootstrapSwitch('state', false);
-    }
-    $('#monkey-enabled').show();
-
-    $.getJSON('/api/telemetry?monkey_guid=' + monkey.guid, function(json) {
-        telemTable.clear();
-        var telemetries = json.objects;
-
-        for (var i = 0; i < telemetries.length; i++) {
-            telemTable.row.add([telemetries[i].timestamp, telemetries[i].telem_type, JSON.stringify(telemetries[i].data)]);
-        } 
-
-        telemTable.draw();
-    });
-
     network.selectNodes([nodeId]);
 }
 
@@ -518,7 +599,32 @@ function onNodeSelect(nodeId) {
  */
 function onEdgeSelect(edge) {
     var edge = getEdge(edge);
+    var monkey = getMonkey(edge.from);
+    if (!monkey) {return;};
 
+    var target = undefined;
+    if (edge.type == 'scan') {
+        target = getScannedByIP(edge.to)
+    }
+    else {
+        target = getMonkey(edge.to)
+    }
+
+    $.getJSON(jsonFileTelemetry + '?monkey_guid=' + monkey.guid, function(json) {
+        telemTable.clear();
+        var telemetries = json.objects;
+
+        for (var i = 0; i < telemetries.length; i++) {
+            var telem = telemetries[i]
+            if (telem.telem_type == 'scan' || telem.telem_type == 'exploit') {
+                if (((edge.type == 'scan') && (telem.data.machine.ip_addr == target.id)) ||
+                    ((edge.type == 'parent') && (0 <= $.inArray(telem.data.machine.ip_addr, target.ip_addresses)))) {
+                    telemTable.row.add([telemetries[i].timestamp, telemetries[i].telem_type, JSON.stringify(telemetries[i].data)]);
+                  }
+                }
+            }
+        telemTable.draw();
+    });
 }
 
 function toggleMonkeyEnabled(event, state) {
@@ -694,8 +800,17 @@ function resetDB() {
             url : '/api?action=reset',
             type : 'GET',
             success : function(response, textStatus, jqXhr) {
-                console.log("DB was successfully reset!");
-                location.reload();
+                console.log(response);
+                if (response.status != 'OK') {
+                    BootstrapDialog.show({
+                        title: "Reset DB",
+                        message: "The following error occured: " + response.reason
+                    });
+                }
+                else {
+                    console.log("DB was successfully reset!");
+                    location.reload();
+                }
             },
             error : function(jqXHR, textStatus, errorThrown) {
                 // log the error to the console
@@ -728,24 +843,24 @@ function getMonkeyByGuid(guid) {
         if (monkeys[i].guid == guid) {
             return monkeys[i];
         }
-    }    
+    }
+    return null;
 }
 
 function getMonkeyByIP(ip) {
-        for (var i = 0; i < monkeys.length; i++) {
+    for (var i = 0; i < monkeys.length; i++) {
             var monkey = monkeys[i];
-            for (var j = 0; j< monkey.ip_addresses; j++) {
-                if (monkeys[i].ip == ip) {
-                    return monkeys[i];
+            for (var j = 0; j< monkey.ip_addresses.length; j++) {
+                if (monkey.ip_addresses[j] == ip) {
+                    return monkey;
                 }
             }
     }
     return null;
 }
 
-function getScannedByIP(ip)
-{
-        for (var i = 0; i < scannedMachines.length; i++) {
+function getScannedByIP(ip) {
+    for (var i = 0; i < scannedMachines.length; i++) {
             var machine = scannedMachines[i];
             if (machine.id == ip) {
                 return machine
@@ -801,13 +916,23 @@ function edgeExists(link) {
         var to = edges[i].to;
         var type = edges[i].type;
         if (from == link[0] && to == link[1] && type == link[2]) {
-            return true;
+            return edges[i];
         }
     }
 }
 
-
-
+function removeEdge(link) {
+    for (var i = 0; i < edges.length; i++) {
+        var from = edges[i].from;
+        var to = edges[i].to;
+        var type = edges[i].type;
+        if (from == link[0] && to == link[1] && type == link[2]) {
+            edges.splice(i, 1);
+            return true;
+        }
+    }
+    return false;
+}
 
 /**
  * Clears the value in the local storage
diff --git a/monkey_island/cc/main.py b/monkey_island/cc/main.py
index 97799c303..ea4c55b35 100644
--- a/monkey_island/cc/main.py
+++ b/monkey_island/cc/main.py
@@ -5,7 +5,7 @@ from flask.ext.pymongo import PyMongo
 from flask import make_response
 import bson.json_util
 import json
-from datetime import datetime
+from datetime import datetime, timedelta
 import dateutil.parser
 
 MONKEY_DOWNLOADS = [
@@ -50,6 +50,7 @@ mongo = PyMongo(app)
 
 class Monkey(restful.Resource):
     def get(self, guid=None, **kw):
+        update_dead_monkeys()  # refresh monkeys status
         if not guid:
             guid = request.args.get('guid')
         timestamp = request.args.get('timestamp')
@@ -59,7 +60,7 @@ class Monkey(restful.Resource):
         else:
             result = {'timestamp': datetime.now().isoformat()}
             find_filter = {}
-            if None != timestamp:
+            if timestamp is not None:
                 find_filter['modifytime'] = {'$gt': dateutil.parser.parse(timestamp)}
             result['objects'] = [x for x in mongo.db.monkey.find(find_filter)]
             return result
@@ -67,7 +68,7 @@ class Monkey(restful.Resource):
     def patch(self, guid):
         monkey_json = json.loads(request.data)
         update = {"$set": {'modifytime': datetime.now()}}
-        
+
         if monkey_json.has_key('keepalive'):
             update['$set']['keepalive'] = dateutil.parser.parse(monkey_json['keepalive'])
         else:
@@ -76,7 +77,7 @@ class Monkey(restful.Resource):
             update['$set']['config'] = monkey_json['config']
         if monkey_json.has_key('tunnel'):
             update['$set']['tunnel'] = monkey_json['tunnel']
-        
+
         return mongo.db.monkey.update({"guid": guid}, update, upsert=False)
 
     def post(self, **kw):
@@ -88,7 +89,7 @@ class Monkey(restful.Resource):
 
         monkey_json['modifytime'] = datetime.now()
 
-        # if new monkey, change config according to "new monkeys" config.
+        # if new monkey telem, change config according to "new monkeys" config.
         db_monkey = mongo.db.monkey.find_one({"guid": monkey_json["guid"]})
         if not db_monkey:
             new_config = mongo.db.config.find_one({'name': 'newconfig'}) or {}
@@ -99,18 +100,31 @@ class Monkey(restful.Resource):
             if db_config.has_key('current_server'):
                 del db_config['current_server']
             monkey_json.get('config', {}).update(db_config)
-            
-            if not monkey_json.has_key('parent') and db_monkey.get('parent'):
-                monkey_json['parent'] = db_monkey.get('parent')
 
         # try to find new monkey parent
         parent = monkey_json.get('parent')
-        if (not parent  or parent == monkey_json.get('guid')) and monkey_json.has_key('ip_addresses'):
+        parent_to_add = (monkey_json.get('guid'), None)  # default values in case of manual run
+        if parent and parent != monkey_json.get('guid'):  # current parent is known
             exploit_telem = [x for x in
-                             mongo.db.telemetry.find({'telem_type': {'$eq': 'exploit'}, 'data.machine.ip_addr':
-                                 {'$in': monkey_json['ip_addresses']}})]
+                             mongo.db.telemetry.find({'telem_type': {'$eq': 'exploit'}, 'data.result': {'$eq': True},
+                                                      'data.machine.ip_addr': {'$in': monkey_json['ip_addresses']},
+                                                      'monkey_guid': {'$eq': parent}})]
             if 1 == len(exploit_telem):
-                monkey_json['parent'] = exploit_telem[0].get('monkey_guid')                
+                parent_to_add = (exploit_telem[0].get('monkey_guid'), exploit_telem[0].get('data').get('exploiter'))
+            else:
+                parent_to_add = (parent, None)
+        elif (not parent or parent == monkey_json.get('guid')) and monkey_json.has_key('ip_addresses'):
+            exploit_telem = [x for x in
+                             mongo.db.telemetry.find({'telem_type': {'$eq': 'exploit'}, 'data.result': {'$eq': True},
+                                                      'data.machine.ip_addr': {'$in': monkey_json['ip_addresses']}})]
+
+            if 1 == len(exploit_telem):
+                parent_to_add = (exploit_telem[0].get('monkey_guid'), exploit_telem[0].get('data').get('exploiter'))
+
+        if not db_monkey:
+            monkey_json['parent'] = [parent_to_add]
+        else:
+            monkey_json['parent'] = db_monkey.get('parent') + [parent_to_add]
 
         return mongo.db.monkey.update({"guid": monkey_json["guid"]},
                                       {"$set": monkey_json},
@@ -122,7 +136,7 @@ class Telemetry(restful.Resource):
         monkey_guid = request.args.get('monkey_guid')
         telem_type = request.args.get('telem_type')
         timestamp = request.args.get('timestamp')
-        if "null" == timestamp: #special case to avoid ugly JS code...
+        if "null" == timestamp:  # special case to avoid ugly JS code...
             timestamp = None
 
         result = {'timestamp': datetime.now().isoformat()}
@@ -146,37 +160,26 @@ class Telemetry(restful.Resource):
 
         # update exploited monkeys parent
         try:
-            if telemetry_json.get('telem_type') == 'exploit':
-                update_parent = []
-                for monkey in mongo.db.monkey.find({"ip_addresses":
-                                                    {'$elemMatch':
-                                                    {'$eq': telemetry_json['data']['machine']['ip_addr']}}}):
-                    parent = monkey.get('parent')
-                    if parent == monkey.get('guid') or not parent:
-                        update_parent.append(monkey)
-                if 1 == len(update_parent):
-                    update_parent[0]['parent'] = telemetry_json['monkey_guid']
-                    mongo.db.monkey.update({"guid": update_parent[0]['guid']}, {"$set": update_parent[0]}, upsert=False)
-            elif telemetry_json.get('telem_type') == 'tunnel':
+            if telemetry_json.get('telem_type') == 'tunnel':
                 if telemetry_json['data']:
                     host = telemetry_json['data'].split(":")[-2].replace("//", "")
                     tunnel_host = mongo.db.monkey.find_one({"ip_addresses": host})
                     mongo.db.monkey.update({"guid": telemetry_json['monkey_guid']},
                                            {'$set': {'tunnel_guid': tunnel_host.get('guid')}},
-                                           upsert=True)
+                                           upsert=False)
                 else:
                     mongo.db.monkey.update({"guid": telemetry_json['monkey_guid']},
-                                           {'$unset': {'tunnel_guid':''}},
-                                           upsert=True)
+                                           {'$unset': {'tunnel_guid': ''}},
+                                           upsert=False)
             elif telemetry_json.get('telem_type') == 'state':
                 if telemetry_json['data']['done']:
                     mongo.db.monkey.update({"guid": telemetry_json['monkey_guid']},
                                            {'$set': {'dead': True}},
-                                           upsert=True)
+                                           upsert=False)
                 else:
                     mongo.db.monkey.update({"guid": telemetry_json['monkey_guid']},
                                            {'$set': {'dead': False}},
-                                           upsert=True)
+                                           upsert=False)
         except:
             pass
 
@@ -220,11 +223,24 @@ class MonkeyDownload(restful.Resource):
 
 
 class Root(restful.Resource):
-    def get(self):
-        return {
-            'status': 'OK',
-            'mongo': str(mongo.db),
-        }
+    def get(self, action=None):
+        if not action:
+            action = request.args.get('action')
+        if not action:
+            return {
+                'status': 'OK',
+                'mongo': str(mongo.db),
+            }
+        elif action=="reset":
+            mongo.db.config.drop()
+            mongo.db.monkey.drop()
+            mongo.db.telemetry.drop()
+            return {
+                'status': 'OK',
+            }
+        else:
+            return {'status': 'BAD',
+                    'reason': 'unknown action'}
 
 
 def normalize_obj(obj):
@@ -232,15 +248,15 @@ def normalize_obj(obj):
         obj['id'] = obj['_id']
         del obj['_id']
 
-    for key,value in obj.items():
+    for key, value in obj.items():
         if type(value) is bson.objectid.ObjectId:
             obj[key] = str(value)
         if type(value) is datetime:
-            obj[key] = str(value)            
+            obj[key] = str(value)
         if type(value) is dict:
             obj[key] = normalize_obj(value)
         if type(value) is list:
-            for i in range(0,len(value)):
+            for i in range(0, len(value)):
                 if type(value[i]) is dict:
                     value[i] = normalize_obj(value[i])
     return obj
@@ -253,10 +269,17 @@ def output_json(obj, code, headers=None):
     return resp
 
 
+def update_dead_monkeys():
+    mongo.db.monkey.update(
+        {'keepalive': {'$lte': datetime.now() - timedelta(minutes=10)}, 'dead': {'$ne': True}},
+        {'$set': {'dead': True, 'modifytime': datetime.now()}}, upsert=False)
+
+
 @app.route('/admin/<path:path>')
 def send_admin(path):
     return send_from_directory('admin/ui', path)
 
+
 DEFAULT_REPRESENTATIONS = {'application/json': output_json}
 api = restful.Api(app)
 api.representations = DEFAULT_REPRESENTATIONS