diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 26a5e8ed0..e7deb6707 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -1,5 +1,6 @@
 mail = require '../commons/mail'
 MailSent = require '../mail/sent/MailSent'
+UserRemark = require '../users/remarks/UserRemark'
 User = require '../users/User'
 async = require 'async'
 errors = require '../commons/errors'
@@ -28,6 +29,9 @@ setupScheduledEmails = ->
     ,
       taskFunction: employerNewCandidatesAvailableTask
       frequencyMs: 10 * 60 * 1000 #10 minutes
+    ,
+      taskFunction: unapprovedCandidateFinishProfileTask
+      frequencyMs: 10 * 60 * 1000
   ]
 
   for mailTask in mailTasks
@@ -35,7 +39,7 @@ setupScheduledEmails = ->
     
 testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
   
-### Candidate Update Reminder Task ###
+### Approved Candidate Update Reminder Task ###
 
 candidateUpdateProfileTask = ->
   mailTaskName = "candidateUpdateProfileTask"
@@ -132,7 +136,103 @@ 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
-### End Candidate Update Reminder Task ###
+### End Approved Candidate Update Reminder Task ###
+  
+### Unapproved Candidate Finish Reminder Task ###
+unapprovedCandidateFinishProfileTask = ->
+  mailTaskName = "unapprovedCandidateFinishProfileTask"
+  lockDurationMs = 2 * 60 * 1000
+  currentDate = new Date()
+  timeRanges = []
+  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, '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}: #{err}"
+    async.each timeRanges, emailUnapprovedCandidateTimeRange.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}"
+
+emailUnapprovedCandidateTimeRange = (timeRange, emailTimeRangeCallback) ->
+  waterfallContext =
+    "timeRange": timeRange
+    "mailTaskName": @mailTaskName
+  async.waterfall [
+    findAllUnapprovedCandidatesWithinTimeRange.bind(waterfallContext)
+    (unfilteredCandidates, cb) ->
+      async.reject unfilteredCandidates, ignoredCandidateFilter, cb.bind(null,null)
+    (unfilteredPotentialCandidates, cb) ->
+      async.reject unfilteredPotentialCandidates, unapprovedCandidateFilter.bind(waterfallContext), cb.bind(null, null)
+    (filteredCandidates, cb) ->
+      async.each filteredCandidates, sendReminderEmailToUnapprovedCandidate.bind(waterfallContext), cb
+  ], emailTimeRangeCallback
+
+findAllUnapprovedCandidatesWithinTimeRange = (cb) ->
+  findParameters =
+    "jobProfile":
+      $exists: true
+    "jobProfile.updated":
+      $gt: @timeRange.start
+      $lte: @timeRange.end
+    "jobProfileApproved": false
+  selection =  "_id email jobProfile.name jobProfile.updated emails"
+  User.find(findParameters).select(selection).lean().exec cb
+
+ignoredCandidateFilter = (candidate, cb) ->
+  findParameters = 
+    "user": candidate._id
+    "contactName": "Ignore"
+  UserRemark.count findParameters, (err, results) ->
+    if err? then return true
+    return cb Boolean(results.length)
+    
+unapprovedCandidateFilter = (candidate, sentEmailFilterCallback) ->
+  if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false
+    return sentEmailFilterCallback true
+  findParameters =
+    "user": candidate._id
+    "mailTask": @mailTaskName
+    "metadata.timeRangeName": @timeRange.name
+    "metadata.updated": candidate.jobProfile.updated
+  MailSent.find(findParameters).lean().exec (err, sentMail) ->
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
+      sentEmailFilterCallback true
+    else
+      sentEmailFilterCallback Boolean(sentMail.length)
+
+sendReminderEmailToUnapprovedCandidate = (candidate, sendEmailCallback) ->
+  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_RXyjzmc7S2HJH287pfoSPN"
+    recipient:
+      address: candidate.email
+      name: candidate.jobProfile.name
+    email_data:
+      user_profile: "http://codecombat.com/account/profile/#{candidate._id}"
+      recipient_address: encodeURIComponent(candidate.email)
+  log.info "Sending #{@timeRange.name} finish profile reminder to #{context.recipient.name}(#{context.recipient.address})"
+  newSentMail =
+    mailTask: @mailTaskName
+    user: candidate._id
+    metadata:
+      timeRangeName: @timeRange.name
+      updated: candidate.jobProfile.updated
+  MailSent.create newSentMail, (err) ->
+    if err? then return sendEmailCallback err
+    sendwithus.api.send context, (err, result) ->
+      log.error "Error sending candidate finish profile reminder email: #{err} with result #{result}" if err
+      sendEmailCallback null
+### End Unapproved Candidate Finish Reminder Task ###
+  
 ### Internal Candidate Update Reminder Email ###
 internalCandidateUpdateTask = ->
   mailTaskName = "internalCandidateUpdateTask"