diff --git a/app/lib/LevelBus.coffee b/app/lib/LevelBus.coffee
index 287110f98..18985716b 100644
--- a/app/lib/LevelBus.coffee
+++ b/app/lib/LevelBus.coffee
@@ -113,7 +113,6 @@ module.exports = class LevelBus extends Bus
     @changedSessionProperties.teamSpells = true
     @session.set({'teamSpells': @teamSpellMap})
     @saveSession()
-    console.log spellTeam, me.team, e.spell.spellKey
     if spellTeam is me.team
       @onSpellChanged e  # Save the new spell to the session, too.
 
diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee
index 8afc6577a..3d1aa8115 100644
--- a/app/lib/LevelLoader.coffee
+++ b/app/lib/LevelLoader.coffee
@@ -110,16 +110,19 @@ module.exports = class LevelLoader extends CocoClass
     @updateCompleted = true
 
   denormalizeSession: ->
-    return if @session.get 'levelName'
+    return if @sessionDenormalized
     patch =
       'levelName': @level.get('name')
       'levelID': @level.get('slug') or @level.id
     if me.id is @session.get 'creator'
       patch.creatorName = me.get('name')
-
-    @session.set key, value for key, value of patch
-    tempSession = new LevelSession _id: @session.id
-    tempSession.save(patch, {patch: true})
+    for key, value of patch
+      if @session.get(key) is value
+        delete patch[key]
+    unless _.isEmpty patch
+      @session.set key, value for key, value of patch
+      tempSession = new LevelSession _id: @session.id
+      tempSession.save(patch, {patch: true})
     @sessionDenormalized = true
 
   # World init
diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee
index cbaf95c4a..521e810c7 100644
--- a/app/lib/simulator/Simulator.coffee
+++ b/app/lib/simulator/Simulator.coffee
@@ -64,7 +64,7 @@ module.exports = class Simulator
 
   setupGoalManager: ->
     @god.goalManager = new GoalManager @world
-    @god.goalManager.goals = @fetchGoalsFromWorldNoteChain()
+    @god.goalManager.goals = @god.level.goals
     @god.goalManager.goalStates = @manuallyGenerateGoalStates()
 
   commenceSimulationAndSetupCallback: ->
@@ -108,17 +108,22 @@ module.exports = class Simulator
     taskResults =
       taskID: @task.getTaskID()
       receiptHandle: @task.getReceiptHandle()
+      originalSessionID: @task.getFirstSessionID()
+      originalSessionRank: -1
       calculationTime: 500
       sessions: []
 
     for session in @task.getSessions()
+
       sessionResult =
         sessionID: session.sessionID
         submitDate: session.submitDate
         creator: session.creator
         metrics:
           rank: @calculateSessionRank session.sessionID, simulationResults.goalStates, @task.generateTeamToSessionMap()
-
+      if session.sessionID is taskResults.originalSessionID
+        taskResults.originalSessionRank = sessionResult.metrics.rank
+        taskResults.originalSessionTeam = session.team
       taskResults.sessions.push sessionResult
 
     return taskResults
@@ -137,8 +142,6 @@ module.exports = class Simulator
     else
       return 1
 
-  fetchGoalsFromWorldNoteChain: -> return @god.goalManager.world.scripts[0].noteChain[0].goals.add
-
   manuallyGenerateGoalStates: ->
     goalStates =
       "destroy-humans":
@@ -190,7 +193,7 @@ module.exports = class Simulator
     spellKeyComponents[0] = _.string.slugify spellKeyComponents[0]
     spellKey = spellKeyComponents.join '/'
     spellKey
-    
+
 
   createSpellAndAssignName: (spellKey, spellName) ->
     @spells[spellKey] ?= {}
@@ -262,10 +265,10 @@ class SimulationTask
           fullSpellName = [thangName,spellName].join '/'
           if _.contains(teamSpells, fullSpellName)
             teamCode[fullSpellName]=spell
-            
+
       _.merge spellKeyToSourceMap, teamCode
       commonSpells = session.teamSpells["common"]
       _.merge spellKeyToSourceMap, _.pick(session.code, commonSpells) if commonSpells?
 
-    
+
     spellKeyToSourceMap
diff --git a/app/lib/surface/PointChooser.coffee b/app/lib/surface/PointChooser.coffee
index 470b10c5f..c55b1a134 100644
--- a/app/lib/surface/PointChooser.coffee
+++ b/app/lib/surface/PointChooser.coffee
@@ -5,6 +5,7 @@ module.exports = class PointChooser extends CocoClass
     super()
     @buildShape()
     @options.stage.addEventListener 'stagemousedown', @onMouseDown
+    @options.camera.dragDisabled = true
 
   destroy: ->
     @options.stage.removeEventListener 'stagemousedown', @onMouseDown
diff --git a/app/lib/surface/RegionChooser.coffee b/app/lib/surface/RegionChooser.coffee
index 14eb47035..d0dbdc82a 100644
--- a/app/lib/surface/RegionChooser.coffee
+++ b/app/lib/surface/RegionChooser.coffee
@@ -7,6 +7,7 @@ module.exports = class RegionChooser extends CocoClass
     @options.stage.addEventListener 'stagemousedown', @onMouseDown
     @options.stage.addEventListener 'stagemousemove', @onMouseMove
     @options.stage.addEventListener 'stagemouseup', @onMouseUp
+    @options.camera.dragDisabled = true
 
   destroy: ->
     @options.stage.removeEventListener 'stagemousedown', @onMouseDown
diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee
index b5adf175c..130d017b7 100644
--- a/app/lib/surface/SpriteBoss.coffee
+++ b/app/lib/surface/SpriteBoss.coffee
@@ -25,6 +25,7 @@ module.exports = class SpriteBoss extends CocoClass
 
   constructor: (@options) ->
     super()
+    @dragged = 0
     @options ?= {}
     @camera = @options.camera
     @surfaceLayer = @options.surfaceLayer
@@ -238,11 +239,12 @@ module.exports = class SpriteBoss extends CocoClass
     @selectThang e.thangID, e.spellName
 
   onCameraDragged: ->
-    @dragged = true
+    @dragged += 1
 
   onSpriteMouseUp: (e) ->
     return if key.shift and @options.choosing
-    return @dragged = false if @dragged
+    return @dragged = 0 if @dragged > 3
+    @dragged = 0
     sprite = if e.sprite?.thang?.isSelectable then e.sprite else null
     @selectSprite e, sprite
 
diff --git a/app/styles/play/level/modal/docs.sass b/app/styles/play/level/modal/docs.sass
new file mode 100644
index 000000000..3c25f0389
--- /dev/null
+++ b/app/styles/play/level/modal/docs.sass
@@ -0,0 +1,2 @@
+#docs-modal .modal-dialog
+  width: 800px
\ No newline at end of file
diff --git a/app/templates/admin.jade b/app/templates/admin.jade
index 43d6769c6..feb9d9347 100644
--- a/app/templates/admin.jade
+++ b/app/templates/admin.jade
@@ -2,6 +2,18 @@ extends /templates/base
 
 block content
   
+  h3 Espionage mode
+    h5 Please enter the email/username of the person you want to spy on
+    .form
+      .form-group
+        label.control-label Email 
+        input#user-email
+      .form-group
+        label.control-label Username 
+        input#user-username
+      
+    button.btn.btn-primary.btn-large#enter-espionage-mode 007
+  
   h3(data-i18n="admin.av_title") Admin Views
 
   h4(data-i18n="admin.av_entities_sub_title") Entities
diff --git a/app/templates/play/level/control_bar.jade b/app/templates/play/level/control_bar.jade
index 59d378bc8..1cc3af07d 100644
--- a/app/templates/play/level/control_bar.jade
+++ b/app/templates/play/level/control_bar.jade
@@ -1,12 +1,12 @@
 h4.home
   
-  a(href="/") 
+  a(href=homeLink || "/") 
     i.icon-home.icon-white
     span(data-i18n="play_level.home") Home
 
 h4.title #{worldName}
 
-button.btn.btn-xs.btn-inverse.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide
+button.btn.btn-xs.btn-success.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide
 
 if ladderGame
   button.btn.btn-xs.btn-inverse.banner#multiplayer-button(title="Leaderboard", data-i18n="play_level.leaderboard") Leaderboard
diff --git a/app/treema-ext.coffee b/app/treema-ext.coffee
index ec105749b..9112abaa6 100644
--- a/app/treema-ext.coffee
+++ b/app/treema-ext.coffee
@@ -38,12 +38,13 @@ class LiveEditingMarkup extends TreemaNode.nodeMap.ace
       url: InkBlob.url
       filename: InkBlob.filename
       mimetype: InkBlob.mimetype
-      description: ''
-      createdFor: []
+      path: @settings.filePath
+
+    @uploadingPath = [@settings.filePath, InkBlob.filename].join('/')
     $.ajax('/file', { type: 'POST', data: body, success: @onFileUploaded })
 
   onFileUploaded: (e) =>
-    @editor.insert "![#{e.metadata.name}](/file/#{e._id})"
+    @editor.insert "![#{e.metadata.name}](/file/#{@uploadingPath})"
 
   onEditorChange: =>
     @saveChanges()
diff --git a/app/views/admin_view.coffee b/app/views/admin_view.coffee
index 941136574..e71c9acaf 100644
--- a/app/views/admin_view.coffee
+++ b/app/views/admin_view.coffee
@@ -1,6 +1,35 @@
+{backboneFailure, genericFailure} = require 'lib/errors'
 View = require 'views/kinds/RootView'
 template = require 'templates/admin'
+storage = require 'lib/storage'
 
 module.exports = class AdminView extends View
   id: "admin-view"
   template: template
+  
+  events:
+    'click #enter-espionage-mode': 'enterEspionageMode'
+    
+  enterEspionageMode: ->
+    userEmail = $("#user-email").val().toLowerCase()
+    username = $("#user-username").val().toLowerCase()
+    
+    userIdentifier = userEmail || username
+    postData =
+      usernameLower: username
+      emailLower: userEmail
+      
+    $.ajax
+      type: "POST",
+      url: "/auth/spy"
+      data: postData
+      success: @espionageSuccess
+      error: @espionageFailure
+    
+  espionageSuccess: (model) ->
+    storage.save('whoami',model)
+    window.location.reload()
+  espionageFailure: (jqxhr, status,error)->
+    console.log "There was an error entering espionage mode: #{error}"
+    
+    
\ No newline at end of file
diff --git a/app/views/editor/article/edit.coffee b/app/views/editor/article/edit.coffee
index f462afd40..05df5291d 100644
--- a/app/views/editor/article/edit.coffee
+++ b/app/views/editor/article/edit.coffee
@@ -35,6 +35,7 @@ module.exports = class ArticleEditView extends View
     data = $.extend(true, {}, @article.attributes)
     options =
       data: data
+      filePath: "db/thang.type/#{@article.get('original')}"
       schema: Article.schema.attributes
       callbacks:
         change: @pushChangesToPreview
diff --git a/app/views/play/level/control_bar_view.coffee b/app/views/play/level/control_bar_view.coffee
index 7c5b22d53..685452d81 100644
--- a/app/views/play/level/control_bar_view.coffee
+++ b/app/views/play/level/control_bar_view.coffee
@@ -47,12 +47,17 @@ module.exports = class ControlBarView extends View
     text += " (#{numPlayers})" if numPlayers > 1
     $('#multiplayer-button', @$el).text(text)
 
-  getRenderData: (context={}) ->
-    super context
-    context.worldName = @worldName
-    context.multiplayerEnabled = @session.get('multiplayer')
-    context.ladderGame = @ladderGame
-    context
+  getRenderData: (c={}) ->
+    super c
+    c.worldName = @worldName
+    c.multiplayerEnabled = @session.get('multiplayer')
+    c.ladderGame = @ladderGame
+    c.homeLink = "/"
+    levelID = @level.get('slug')
+    if levelID in ["project-dota", "brawlwood", "ladder-tutorial"]
+      levelID = 'project-dota' if levelID is 'ladder-tutorial'
+      c.homeLink = "/play/ladder/" + levelID
+    c
 
   showGuideModal: ->
     options = {docs: @level.get('documentation'), supermodel: @supermodel}
diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee
index 09059d20b..cc62fb047 100644
--- a/app/views/play/level/hud_view.coffee
+++ b/app/views/play/level/hud_view.coffee
@@ -270,7 +270,7 @@ module.exports = class HUDView extends View
     if prop is "rotation"
       return (val * 180 / Math.PI).toFixed(0) + "˚"
     if typeof val is 'number'
-      if Math.round(val) == val then return val.toFixed(0)  # int
+      if Math.round(val) == val or prop is 'gold' then return val.toFixed(0)  # int
       if -10 < val < 10 then return val.toFixed(2)
       if -100 < val < 100 then return val.toFixed(1)
       return val.toFixed(0)
diff --git a/app/views/play/level/modal/docs_modal.coffee b/app/views/play/level/modal/docs_modal.coffee
index fc975b84a..c7b77a287 100644
--- a/app/views/play/level/modal/docs_modal.coffee
+++ b/app/views/play/level/modal/docs_modal.coffee
@@ -6,6 +6,7 @@ Article = require 'models/Article'
 
 module.exports = class DocsModal extends View
   template: template
+  id: 'docs-modal'
   
   shortcuts:
     'enter': 'hide'
diff --git a/app/views/play/level/tome/spell_debug_view.coffee b/app/views/play/level/tome/spell_debug_view.coffee
index f59b84501..5f4cfdd30 100644
--- a/app/views/play/level/tome/spell_debug_view.coffee
+++ b/app/views/play/level/tome/spell_debug_view.coffee
@@ -82,11 +82,20 @@ module.exports = class DebugView extends View
     else
       @$el.hide()
     if @variableChain?.length is 2
-      Backbone.Mediator.publish 'tome:spell-debug-property-hovered', property: @variableChain[1], owner: @variableChain[0]
+      clearTimeout @hoveredPropertyTimeout if @hoveredPropertyTimeout
+      @hoveredPropertyTimeout = _.delay @notifyPropertyHovered, 500
     else
-      Backbone.Mediator.publish 'tome:spell-debug-property-hovered', property: null
+      @notifyPropertyHovered()
     @updateMarker()
 
+  notifyPropertyHovered: =>
+    clearTimeout @hoveredPropertyTimeout if @hoveredPropertyTimeout
+    @hoveredPropertyTimeout = null
+    oldHoveredProperty = @hoveredProperty
+    @hoveredProperty = if @variableChain?.length is 2 then owner: @variableChain[0], property: @variableChain[1] else {}
+    unless _.isEqual oldHoveredProperty, @hoveredProperty
+      Backbone.Mediator.publish 'tome:spell-debug-property-hovered', @hoveredProperty
+
   updateMarker: ->
     if @marker
       @ace.getSession().removeMarker @marker
diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee
index 060db8630..e49b2d2b9 100644
--- a/app/views/play/level_view.coffee
+++ b/app/views/play/level_view.coffee
@@ -141,17 +141,13 @@ module.exports = class PlayLevelView extends View
 
     otherSession = @levelLoader.opponentSession
     opponentCode = otherSession?.get('submittedCode') or {}
-    console.log "otherSession", otherSession, "opponentSpells", opponentSpells
     myCode = @session.get('code') or {}
     for spell in opponentSpells
       [thang, spell] = spell.split '/'
       c = opponentCode[thang]?[spell]
-      console.log "Got opponent code", c, "for", spell, "and had my code", myCode[spell]
       myCode[thang] ?= {}
       if c then myCode[thang][spell] = c else delete myCode[thang][spell]
-    console.log "Going to set session code from", _.cloneDeep(myCode)
     @session.set('code', myCode)
-    console.log "Just set session code to", _.cloneDeep(@session.get('code'))
     if @session.get('multiplayer') and otherSession?
       # For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
       @session.set 'multiplayer', false
diff --git a/server/levels/sessions/level_session_schema.coffee b/server/levels/sessions/level_session_schema.coffee
index da97b8ce5..290422c10 100644
--- a/server/levels/sessions/level_session_schema.coffee
+++ b/server/levels/sessions/level_session_schema.coffee
@@ -139,6 +139,13 @@ _.extend LevelSessionSchema.properties,
 
   submittedCode:
     type: 'object'
+    
+  numberOfWinsAndTies:
+    type: 'number'
+    default: 0
+  numberOfLosses:
+    type: 'number'
+    default: 0
 
   matches:
     type: 'array'
diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee
index 4592ec74c..40a6b2f21 100644
--- a/server/queues/scoring.coffee
+++ b/server/queues/scoring.coffee
@@ -12,7 +12,7 @@ TaskLog = require './task/ScoringTask'
 bayes = new (require 'bayesian-battle')()
 
 scoringTaskQueue = undefined
-scoringTaskTimeoutInSeconds = 120
+scoringTaskTimeoutInSeconds = 180
 
 
 module.exports.setup = (app) -> connectToScoringQueue()
@@ -24,24 +24,27 @@ connectToScoringQueue = ->
       scoringTaskQueue = data
       log.info "Connected to scoring task queue!"
       
-module.exports.addPairwiseTaskToQueue = (req, res) ->
+module.exports.addPairwiseTaskToQueueFromRequest = (req, res) ->
   taskPair = req.body.sessions
-  #unless isUserAdmin req then return errors.forbidden res, "You do not have the permissions to submit that game to the leaderboard"
-  #fetch both sessions
+  addPairwiseTaskToQueue req.body.sessions (err, success) ->
+    if err? then return errors.serverError res, "There was an error adding pairwise tasks: #{err}"
+    sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
+    
+
+addPairwiseTaskToQueue = (taskPair, cb) ->
   LevelSession.findOne(_id:taskPair[0]).lean().exec (err, firstSession) =>
-    if err? then return errors.serverError res, "There was an error fetching the first session in the pair"
+    if err? then return cb err, false
     LevelSession.find(_id:taskPair[1]).exec (err, secondSession) =>
-      if err? then return errors.serverError res, "There was an error fetching the second session"
+      if err? then return cb err, false
       try
         taskPairs = generateTaskPairs(secondSession, firstSession)
       catch e
-        if e then return errors.serverError res, "There was an error generating the task pairs"
-      
-      sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
-        if taskPairError? then return errors.serverError res, "There was an error sending the task pairs to the queue"
+        if e then return cb e, false
 
-        sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
-  
+      sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
+        if taskPairError? then return cb taskPairError,false 
+        cb null, true
+        
 
 module.exports.createNewTask = (req, res) ->
   requestSessionID = req.body.session
@@ -56,8 +59,8 @@ module.exports.createNewTask = (req, res) ->
 
       updateSessionToSubmit sessionToSubmit, (err, data) ->
         if err? then return errors.serverError res, "There was an error updating the session"
-
-        fetchSessionsToRankAgainst (err, sessionsToRankAgainst) ->
+        opposingTeam = calculateOpposingTeam(sessionToSubmit.team)
+        fetchInitialSessionsToRankAgainst opposingTeam, (err, sessionsToRankAgainst) ->
           if err? then return errors.serverError res, "There was an error fetching the sessions to rank against"
 
           taskPairs = generateTaskPairs(sessionsToRankAgainst, sessionToSubmit)
@@ -114,9 +117,102 @@ module.exports.processTaskResult = (req, res) ->
 
           addMatchToSessions clientResponseObject, newScoresObject, (err, data) ->
             if err? then return errors.serverError res, "There was an error updating the sessions with the match! #{JSON.stringify err}"
-            console.log "Sending response object"
-            sendResponseObject req, res, {"message":"The scores were updated successfully!"}
+              
+            originalSessionID = clientResponseObject.originalSessionID
+            originalSessionTeam = clientResponseObject.originalSessionTeam
+            originalSessionRank = parseInt clientResponseObject.originalSessionRank
+            
+            determineIfSessionShouldContinueAndUpdateLog originalSessionID, originalSessionRank, (err, sessionShouldContinue) ->
+              if err? then return errors.serverError res, "There was an error determining if the session should continue, #{err}"
+                
+              if sessionShouldContinue
+                opposingTeam = calculateOpposingTeam(originalSessionTeam)
+                opponentID = _.pull(_.keys(newScoresObject), originalSessionID)
+                sessionNewScore = newScoresObject[originalSessionID].totalScore
+                opponentNewScore = newScoresObject[opponentID].totalScore
+                findNearestBetterSessionID sessionNewScore, opponentNewScore, opponentID ,opposingTeam, (err, opponentSessionID) ->
+                  if err? then return errors.serverError res, "There was an error finding the nearest sessionID!"
+                  unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"}
+                    
+                  addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) ->
+                    if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!"
+                    sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"}
+              else
+                console.log "Player lost, achieved rank #{originalSessionRank}"
+                sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"}
 
+              
+determineIfSessionShouldContinueAndUpdateLog = (sessionID, sessionRank, cb) ->
+  queryParameters = 
+    _id: sessionID
+  
+  updateParameters = 
+    "$inc": {}
+  
+  if sessionRank is 0 
+    updateParameters["$inc"] = {numberOfWinsAndTies: 1}
+  else
+    updateParameters["$inc"] = {numberOfLosses: 1}
+ 
+  LevelSession.findOneAndUpdate queryParameters, updateParameters,{select: 'numberOfWinsAndTies numberOfLosses'}, (err, updatedSession) ->
+    if err? then return cb err, updatedSession
+    updatedSession = updatedSession.toObject()
+
+    totalNumberOfGamesPlayed = updatedSession.numberOfWinsAndTies + updatedSession.numberOfLosses
+    if totalNumberOfGamesPlayed < 5
+      console.log "Number of games played is less than 5, continuing..."
+      cb null, true
+    else if totalNumberOfGamesPlayed > 15
+      console.log "Too many games played, ending..."
+      cb null, false
+    else
+      ratio = (updatedSession.numberOfLosses - 5) / (totalNumberOfGamesPlayed)
+      if ratio > 0.66
+        cb null, false
+        console.log "Ratio(#{ratio}) is bad, ending simulation"
+      else
+        console.log "Ratio(#{ratio}) is good, so continuing simulations"
+        cb null, true
+      
+    
+findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, opponentSessionID, opposingTeam, cb) ->
+  queryParameters =
+    totalScore: 
+      $gt:opponentSessionTotalScore + 0.5
+    _id: 
+      $ne: opponentSessionID
+    levelID: "project-dota"
+    submitted: true
+    submittedCode:
+      $exists: true
+    team: opposingTeam
+    
+  limitNumber = 1
+
+  sortParameters =
+    totalScore: 1
+    
+  selectString = '_id totalScore'
+    
+  query = LevelSession.findOne(queryParameters)
+    .sort(sortParameters)
+    .limit(limitNumber)
+    .select(selectString)
+    .lean()
+  
+  console.log "Finding session with score near #{opponentSessionTotalScore}"
+  query.exec (err, session) ->
+    if err? then return cb err, session
+    unless session then return cb err, null
+    console.log "Found session with score #{session.totalScore}"
+    cb err, session._id
+
+calculateOpposingTeam = (sessionTeam) ->
+  teams = ['ogres','humans']
+  opposingTeams = _.pull teams, sessionTeam
+  return opposingTeams[0]
+  
+  
 validatePermissions = (req, sessionID, callback) ->
   if isUserAnonymous req then return callback null, false
   if isUserAdmin req then return callback null, true
@@ -177,15 +273,30 @@ updateSessionToSubmit = (sessionToUpdate, callback) ->
     meanStrength: 25
     standardDeviation: 25/3
     totalScore: 10
+    numberOfWinsAndTies: 0
+    numberOfLosses: 0
   LevelSession.update {_id: sessionToUpdate._id}, sessionUpdateObject, callback
 
-fetchSessionsToRankAgainst = (callback) ->
-  submittedSessionsQuery =
+fetchInitialSessionsToRankAgainst = (opposingTeam, callback) ->
+  console.log "Fetching sessions to rank against for opposing team #{opposingTeam}"
+  findParameters =
     levelID: "project-dota"
     submitted: true
     submittedCode:
       $exists: true
-  LevelSession.find submittedSessionsQuery, callback
+    team: opposingTeam
+  
+  sortParameters = 
+    totalScore: 1
+  
+  limitNumber = 1
+  
+  query = LevelSession.find(findParameters)
+    .sort(sortParameters)
+    .limit(limitNumber)
+  
+  
+  query.exec callback
 
 generateTaskPairs = (submittedSessions, sessionToScore) ->
   taskPairs = []
diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee
index e5d3f9367..2e6dbf72d 100644
--- a/server/routes/auth.coffee
+++ b/server/routes/auth.coffee
@@ -28,7 +28,30 @@ module.exports.setup = (app) ->
         return done(null, user)
       )
   ))
-
+  app.post '/auth/spy', (req, res, next) ->
+    if req?.user?.isAdmin()
+      
+      username = req.body.usernameLower
+      emailLower = req.body.emailLower
+      if emailLower
+        query = {"emailLower":emailLower}
+      else if username
+        query = {"nameLower":username}
+      else
+        return errors.badInput res, "You need to supply one of emailLower or username"
+        
+      User.findOne query, (err, user) ->
+        if err? then return errors.serverError res, "There was an error finding the specified user"
+        
+        unless user then return errors.badInput res, "The specified user couldn't be found"
+          
+        req.logIn user, (err) ->
+          if err? then return errors.serverError res, "There was an error logging in with the specified"
+          res.send(UserHandler.formatEntity(req, user))
+          return res.end()
+    else
+      return errors.unauthorized res, "You must be an admin to enter espionage mode"
+      
   app.post('/auth/login', (req, res, next) ->
     authentication.authenticate('local', (err, user, info) ->
       return next(err) if err