         # # user is member, check validity
         # # user is not member, and trying to access with invitationToken
         # both should succeed
-        loginHelper.fetchInvitationByCode invitationToken, queue, callback, (invitation_) ->
+        fetchInvitationByCode invitationToken, queue, callback, (invitation_) ->
           invitation = invitation_
 
       ->
-        loginHelper.fetchInvitationByData {
+        fetchInvitationByData {
           user, groupName, invitationToken
         }, queue, callback, (invitation_) -> invitation = invitation_
 

      callback null, response


  loginHelper =

    fetchSession : (options, queue, callback, fetchData) ->

      { clientId, username } = options

      # fetch session of the current requester
      JSession.fetchSession clientId, (err, { session: fetchedSession }) ->
        return callback err  if err

        session = fetchedSession
        unless session
          console.error "login: session not found #{username}"
          return callback new KodingError 'Couldn\'t restore your session!'

        fetchData session

        queue.next()

    validateLoginCredentials : (options, queue, callback, fetchData) ->

      { username, password, tfcode } = options

      # check credential validity
      JUser.one { username }, (err, user) ->
        return logAndReturnLoginError username, err.message, callback if err
        fetchData user

        # if user not found it means we dont know about given username
        unless user?
          return logAndReturnLoginError username, 'Unknown user name', callback

        # if password is autogenerated return error
        if user.getAt('passwordStatus') is 'needs reset'
          return logAndReturnLoginError username, \
            'You should reset your password in order to continue!', callback

        # check if provided password is correct
        unless user.checkPassword password
          return logAndReturnLoginError username, 'Access denied!', callback

        # check if user is using 2factor auth and provided key is ok
        if !!(user.getAt 'twofactorkey')

          unless tfcode
            return callback new KodingError \
              'TwoFactor auth Enabled', 'VERIFICATION_CODE_NEEDED'

          unless user.check2FactorAuth tfcode
            return logAndReturnLoginError username, 'Access denied!', callback

        # if everything is fine, just continue
        queue.next()

    fetchInvitationByCode : (invitationToken, queue, callback, fetchData) ->

      # if we dont have an invitation code, do not continue
      return queue.next()  unless invitationToken

      JInvitation = require '../invitation'
      JInvitation.byCode invitationToken, (err, invitation) ->
        return callback err  if err
        return callback new KodingError 'invitation is not valid'  unless invitation
        fetchData invitation
        queue.next()

    fetchInvitationByData : (options, queue, callback, fetchData) ->

      { user, groupName, invitationToken } = options
      # check if user has pending invitation
      return queue.next()  if invitationToken

      selector = { email: user.email, groupName }
      JInvitation = require '../invitation'
      JInvitation.one selector, {}, (err, invitation) ->
        fetchData invitation  if invitation
        queue.next()


  @login = (clientId, credentials, callback) ->

          queue.next()

      ->
        fetchSession {
          clientId, username
        }, queue, callback, (session_) ->
          session = session_
