public static function authenticate($data, Form $form = null)
    {
        $service = Injector::inst()->get('LDAPService');
        $login = trim($data['Login']);
        if (Email::validEmailAddress($login)) {
            if (Config::inst()->get('LDAPAuthenticator', 'allow_email_login')!='yes') {
                $form->sessionMessage(
                    _t(
                        'LDAPAuthenticator.PLEASEUSEUSERNAME',
                        'Please enter your username instead of your email to log in.'
                    ),
                    'bad'
                );
                return;
            }

            $username = $service->getUsernameByEmail($login);

            // No user found with this email.
            if (!$username) {
                if (Config::inst()->get('LDAPAuthenticator', 'fallback_authenticator') === 'yes') {
                    $fallbackMember = self::fallback_authenticate($data, $form);
                    if ($fallbackMember) {
                        return $fallbackMember;
                    }
                }

                $form->sessionMessage(_t('LDAPAuthenticator.INVALIDCREDENTIALS', 'Invalid credentials'), 'bad');
                return;
            }
        } else {
            $username = $login;
        }

        $result = $service->authenticate($username, $data['Password']);
        $success = $result['success'] === true;
        if (!$success) {
            if (Config::inst()->get('LDAPAuthenticator', 'fallback_authenticator') === 'yes') {
                $fallbackMember = self::fallback_authenticate($data, $form);
                if ($fallbackMember) {
                    return $fallbackMember;
                }
            }

            if ($form) {
                $form->sessionMessage($result['message'], 'bad');
            }
            return;
        }

        $data = $service->getUserByUsername($result['identity']);
        if (!$data) {
            if ($form) {
                $form->sessionMessage(
                    _t('LDAPAuthenticator.PROBLEMFINDINGDATA', 'There was a problem retrieving your user data'),
                    'bad'
                );
            }
            return;
        }

        // LDAPMemberExtension::memberLoggedIn() will update any other AD attributes mapped to Member fields
        $member = Member::get()->filter('GUID', $data['objectguid'])->limit(1)->first();
        if (!($member && $member->exists())) {
            $member = new Member();
            $member->GUID = $data['objectguid'];
        }

        // Update the users from LDAP so we are sure that the email is correct.
        // This will also write the Member record.
        $service->updateMemberFromLDAP($member);

        Session::clear('BackURL');

        return $member;
    }