       categories[value].push user
   categories
 
+typoCache = {}
 getDomain = (user) ->
-  domain = user.emailLower.split('@')[1]
+  return null unless domain = user.emailLower.split('@')[1]
   return null if commonEmailDomainMap[domain]
+  typo = typoCache[domain]
+  return null if typo
+  return domain if typo is false
   typo = _.find commonEmailDomains, (commonDomain) -> stringScore(commonDomain, domain, 0.8) > 0.9
+  typoCache[domain] = Boolean(typo)
   return null if typo
   domain
+
+commonReferrersRegex = /(google|bing\.|yahoo|duckduckgo|jobs\.lever|code\.org|twitter|facebook|dollarclick|stumbleupon|vk\.com|playpcesor|reddit|lifehacker|favorite|bnext|freelance|taringa|blogthinkbig|graphism|inside\.com|korben|habrahabr|iplaysoft|geekbrains|playground|ycombinator|github\.com)/
+getReferrer = (user) ->
+  return null unless referrer = user.referrer?.toLowerCase().trim()
+  referrer = referrer.replace /^https?:\/\//, ''
+  return null if commonReferrersRegex.test referrer
+  return classCode if classCode = referrer.match(/\?_cc=(\S+)/)?[1]
+  return null if /codecombat/.test referrer
+  referrer
 
 # https://github.com/joshaven/string_score
 stringScore = (_a, word, fuzziness) ->

  for user in users
    if field is 'domain'
      value = getDomain user
    else
      value = user[field]
    continue unless value

      nameMatches.push schoolName: otherSchoolName, score: score
    nameMatches = (match.schoolName for match in (_.sortBy nameMatches, (match) -> -match.score))
    for match in nameMatches.slice(0, 10)
      reason = "Name"
      for otherUser in (userCategories.schoolName[match] ? []) when otherUser isnt target
        if existingSuggestion = _.find(suggestions, user: otherUser)
          existingSuggestion.reasons.push reason
        else
          suggestions.push schoolName: match, reasons: [reason], user: otherUser
  console.log '    Now checking domain', (new Date()) - t0
  if domain = getDomain target
    for otherUser in (userCategories.domain[domain] ? []) when otherUser isnt target
      reason = "Domain"
      if existingSuggestion = _.find(suggestions, user: otherUser)
        existingSuggestion.reasons.push reason
      else
        suggestions.push schoolName: otherUser.schoolName, reasons: [reason], user: otherUser
  console.log '    Now checking referrer', (new Date()) - t0
  if referrer = getReferrer target
    for otherUser in (userCategories.referrer[referrer] ? []) when otherUser isnt target
      reason = "Referrer"
      if existingSuggestion = _.find(suggestions, user: otherUser)
        existingSuggestion.reasons.push reason
      else
        suggestions.push schoolName: otherUser.schoolName, reasons: [reason], user: otherUser
  suggestions = _.sortBy suggestions, 'schoolName'
  suggestions = _.sortBy suggestions, (s) -> -s.reasons.length
  return suggestions

userCategories = {}
topGroups = {}
