diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 0e34e06db..6939d8080 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -9,9 +9,20 @@ LevelSession = require '../levels/sessions/LevelSession'
 Level = require '../levels/Level'
 log = require 'winston'
 sendwithus = require '../sendwithus'
-if config.isProduction or config.redis.host isnt "localhost"
+if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones
   lockManager = require '../commons/LockManager'
-  
+#TODO: Ask Nick about email unsubscriptions
+createMailTask = (req, res) -> #TODO: Ask Nick whether he thinks it is a good idea or not to hardcode the mail tasks
+  unless req.user?.isAdmin() then return errors.forbidden(res)
+  unless req.body.url and req.body.frequency then return errors.badInput(res)
+  console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
+  newMailTask = new MailTask {}
+  newMailTask.set("url",req.body.url)
+  newMailTask.set("frequency",req.body.frequency)
+  newMailTask.save (err) ->
+    if err? then return errors.serverError(res, err)
+    res.send("Created mail task!")
+    res.end()
 
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
@@ -22,28 +33,52 @@ module.exports.setup = (app) ->
   
 setupScheduledEmails = ->
   testForLockManager()
-  mailTaskMap = 
-    "test_mail_task": employerNewCandidatesAvailableTask
+  mailTaskMap = #TODO: Edit this to include additional emails
+    "test_mail_task": candidateUpdateProfileTask
     
-  MailTask.find({}).lean().exec (err, mailTasks) ->
+  MailTask.find({}).lean().exec (err, mailTasks) -> #TODO: Ask Nick whether or not to remove this
     if err? then throw "Failed to schedule mailTasks! #{err}"
     for mailTask in mailTasks
-      setInterval mailTaskMap[mailTask.url], mailTask.frequency*2
+      setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 #TODO: Have some random offset to prevent lock contention
       
 testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
   
 ### Candidate Update Reminder Task ###
-emailTimeRange = (timeRange, finalCallback) ->
+
+candidateUpdateProfileTask = ->
+  mailTaskName = "candidateUpdateProfileTask"
+  lockDurationMs = 20000 #TODO: Change these to something appropriate for the mail frequency (ideally longer than the task but shorter than frequency)
+  currentDate = new Date()
+  timeRanges = []
+  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
+    timeRanges.push
+      start: generateWeekOffset currentDate, weekPair[0]
+      end: generateWeekOffset currentDate, weekPair[1]
+      name: weekPair[2]
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
+    async.each timeRanges, emailTimeRange.bind({mailTaskName: mailTaskName}), (err) ->
+      if err
+        log.error "There was an error sending the candidate profile update reminder emails: #{err}"
+      else
+        log.info "Completed mail task #{mailTaskName}"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
+
+generateWeekOffset = (originalDate, numberOfWeeks) ->
+  return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString()
+
+emailTimeRange = (timeRange, emailTimeRangeCallback) ->
   waterfallContext =
     "timeRange": timeRange
     "mailTaskName": @mailTaskName
   async.waterfall [
     findAllCandidatesWithinTimeRange.bind(waterfallContext)
-    (unfilteredCandidates, cb) -> #now filter the candidates to see if they are eligible
-      async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), (filtered) -> cb null, filtered
-    (filteredCandidates, cb) -> #Now send emails to the eligible candidates and record.
+    (unfilteredCandidates, cb) -> 
+      async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), cb.bind(null, null)
+    (filteredCandidates, cb) ->
       async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb
-  ], finalCallback
+  ], emailTimeRangeCallback
   
 findAllCandidatesWithinTimeRange = (cb) ->
   findParameters =
@@ -61,8 +96,11 @@ candidateFilter = (candidate, sentEmailFilterCallback) ->
     "metadata.timeRangeName": @timeRange.name
     "metadata.updated": candidate.jobProfile.updated
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
-    if err? then return errors.serverError("Error fetching sent mail in email task")
-    sentEmailFilterCallback Boolean(sentMail.length)
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
+      sentEmailFilterCallback true
+    else
+      sentEmailFilterCallback Boolean(sentMail.length)
 
 findEmployersSignedUpAfterDate = (dateObject, cb) ->
   countParameters =
@@ -73,14 +111,18 @@ findEmployersSignedUpAfterDate = (dateObject, cb) ->
   
 sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
   findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) =>
+    if err?
+      log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}"
+      return sendEmailCallback err
     context =
       email_id: "tem_CtTLsKQufxrxoPMn7upKiL"
       recipient:
         address: candidate.email
         name: candidate.jobProfile.name
       email_data:
-        profile_updated: candidate.jobProfile.updated #format nicely
         new_company: employersAfterCount
+        company_name: "CodeCombat"
+        user_profile: "http://codecombat.com/account/profile/#{candidate._id}"
     log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})"
     newSentMail =
       mailTask: @mailTaskName
@@ -93,30 +135,22 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
       sendwithus.api.send context, (err, result) ->
         log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err
         sendEmailCallback null
-
-generateWeekOffset = (originalDate, numberOfWeeks) ->
-  return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString()
-
-candidateUpdateProfileTask = ->
-  mailTaskName = "candidateUpdateProfileTask"
-  lockDurationMs = 6000
-  currentDate = new Date()
-  timeRanges = []
-  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
-    timeRanges.push 
-      start: generateWeekOffset currentDate, weekPair[0]
-      end: generateWeekOffset currentDate, weekPair[1]
-      name: weekPair[2]
-  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-    if err? then return log.error "Error getting a task lock!"
-    async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) ->
-      if err then log.error JSON.stringify err else log.info "Sent candidate update reminders!"
-      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
-        
 ### End Candidate Update Reminder Task ###
 ### Internal Candidate Update Reminder Email ###
+internalCandidateUpdateTask = ->
+  mailTaskName = "internalCandidateUpdateTask"
+  lockDurationMs = 6000 #TODO: Change lock duration
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
+    emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
+      if err
+        log.error "There was an error sending the internal candidate update reminder.: #{err}"
+      else
+        log.info "Sent internal candidate update reminder email!"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
 
-emailInternalCandidateUpdateReminder = (cb) ->
+emailInternalCandidateUpdateReminder = (internalCandidateUpdateReminderCallback) ->
   currentTime = new Date()
   beginningOfUTCDay = new Date()
   beginningOfUTCDay.setUTCHours(0,0,0,0)
@@ -124,40 +158,43 @@ emailInternalCandidateUpdateReminder = (cb) ->
     "beginningOfUTCDay": beginningOfUTCDay
     "currentTime": currentTime
     "mailTaskName": @mailTaskName
-    
   async.waterfall [
     findNonApprovedCandidatesWhoUpdatedJobProfileToday.bind(asyncContext)
     (unfilteredCandidates, cb) ->
       async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null)
     (filteredCandidates, cb) ->
       async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb
-  ], cb
+  ], internalCandidateUpdateReminderCallback
     
 findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) ->
   findParameters = 
     "jobProfile.updated":
       $lte: @currentTime.toISOString()
       gt: @beginningOfUTCDay.toISOString()
-    "jobProfileApproved": false
+    "jobProfileApproved": false 
   User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb
   
 candidatesUpdatedTodayFilter = (candidate, cb) ->
   findParameters =
     "user": candidate._id
     "mailTask": @mailTaskName
-    "metadata.beginningOfUTCDay": @beginningOfUTCDay
+    "metadata.beginningOfUTCDay": @beginningOfUTCDay 
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
-    if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
-    cb Boolean(sentMail.length)
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
+      cb true
+    else
+      cb Boolean(sentMail.length)
     
 sendInternalCandidateUpdateReminder = (candidate, cb) ->
   context =
     email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE"
-    recipient:
+    recipient: 
       address: "team@codecombat.com" #Change to whatever email address is necessary
       name: "The CodeCombat Team"
+    email_data:
+      new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}"
   log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}"
-  
   newSentMail =
     mailTask: @mailTaskName
     user: candidate._id
@@ -169,20 +206,23 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
     sendwithus.api.send context, (err, result) ->
       log.error "Error sending interal candidate update email: #{err} with result #{result}" if err
       cb null
-  
-internalCandidateUpdateTask = ->
-  mailTaskName = "internalCandidateUpdateTask"
-  lockDurationMs = 6000
-  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-    if err? then return log.error "Error getting a task lock!"
-    emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
-      if err? then log.error "There was an error sending the internal candidate update reminder."
-      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
-### End Internal Candidate Update Reminder Email ###
-  
-### Employer New Candidates Available Email ###
 
-emailEmployerNewCandidatesAvailableEmail = (cb) ->
+### End Internal Candidate Update Reminder Email ###
+### Employer New Candidates Available Email ###
+employerNewCandidatesAvailableTask = ->
+  mailTaskName = "employerNewCandidatesAvailableTask"
+  lockDurationMs = 6000 #TODO: Update this lock duration
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "There was an error getting a task lock!"
+    emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) ->
+      if err
+        log.error "There was an error completing the new candidates available task: #{err}"
+      else
+        log.info "Completed the employer new candidates available task!"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
+
+emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallback) ->
   currentTime = new Date()
   asyncContext = 
     "currentTime": currentTime
@@ -192,22 +232,20 @@ emailEmployerNewCandidatesAvailableEmail = (cb) ->
     findAllEmployers
     makeEmployerNamesEasilyAccessible
     (allEmployers, cb) ->
-      console.log "Found #{allEmployers.length} employers to email about new candidates available"
       async.reject allEmployers, employersEmailedDigestMoreThanWeekAgoFilter.bind(asyncContext), cb.bind(null,null)
     (employersToEmail, cb) ->
       async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb
-  ], cb
+  ], emailEmployerNewCandidatesAvailableCallback
       
 findAllEmployers = (cb) ->
   findParameters = 
     "employerAt":
-      $exists: true
+      $exists: true 
     permissions: "employer"
   selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated"
   User.find(findParameters).select(selection).lean().exec cb
   
 makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
-  #Make names easily accessible
   for employer, index in allEmployers
     if employer.signedEmployerAgreement?.data?.firstName
       employer.name = employer.signedEmployerAgreement.data.firstName + " " + employer.signedEmployerAgreement.data.lastName
@@ -222,15 +260,16 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
     "sent":
       $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) 
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
-    if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
-    cb Boolean(sentMail.length)
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and employer #employer._id}!"
+      cb true
+    else
+      cb Boolean(sentMail.length)
 
 sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
-  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated
+  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated 
   countParameters =
     "jobProfileApproved": true
-    "jobProfile": 
-      $exists: true
     $or: [
         jobProfileApprovedDate: 
           $gt: lastLoginDate.toISOString()
@@ -246,12 +285,12 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
       email_id: "tem_CCcHKr95Nvu5bT7c7iHCtm"
       recipient:
         address: employer.email
-        name: employer.name
       email_data:
         new_candidates: numberOfCandidatesSinceLogin
         employer_company_name: employer.employerAt
         company_name: "CodeCombat"
-    
+    if employer.name
+      context.recipient.name = employer.name
     log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})"
     newSentMail =
       mailTask: @mailTaskName
@@ -262,17 +301,6 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
         log.error "Error sending employer candidates available email: #{err} with result #{result}" if err
         cb null
 
-employerNewCandidatesAvailableTask = ->
-  #initialize featuredDate to job profile updated
-  mailTaskName = "employerNewCandidatesAvailableTask"
-  lockDurationMs = 6000
-  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-    if err? then return log.error "There was an error getting a task lock!"
-    emailEmployerNewCandidatesAvailableEmail.apply {"mailTaskName":mailTaskName}, (err) ->
-      if err? then return log.error "There was an error performing the #{mailTaskName} email task."
-      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
-
-
 ### End Employer New Candidates Available Email ###
 
 ### New Recruit Leaderboard Email ###
@@ -313,17 +341,7 @@ isRequestFromDesignatedCronHandler = (req, res) ->
     return false
   return true
 
-createMailTask = (req, res) ->
-  #unless req.user?.isAdmin() then return errors.forbidden(res)
-  unless req.body.url and req.body.frequency then return errors.badInput(res)
-  console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
-  newMailTask = new MailTask {}
-  newMailTask.set("url",req.body.url)
-  newMailTask.set("frequency",req.body.frequency)
-  newMailTask.save (err) ->
-    if err? then return errors.serverError(res, err)
-    res.send("Created mail task!")
-    res.end()
+
   
 handleLadderUpdate = (req, res) ->
   log.info('Going to see about sending ladder update emails.')