       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"

    
testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
  
### Candidate Update Reminder Task ###

candidateUpdateProfileTask = ->
  mailTaskName = "candidateUpdateProfileTask"

    ,
      taskFunction: employerNewCandidatesAvailableTask
      frequencyMs: 10 * 60 * 1000 #10 minutes
    ,
      taskFunction: unapprovedCandidateFinishProfileTask
      frequencyMs: 10 * 60 * 1000
  ]

  for mailTask in mailTasks
