public function getUserByUsername($username, $baseDn = null, $scope = Ldap::SEARCH_SCOPE_SUB, $attributes = [])
    {
        $options = $this->config()->options;
        $option = isset($options['accountCanonicalForm']) ? $options['accountCanonicalForm'] : null;

        // will translate the username to username@foo.bar, username or foo\user depending on the
        // $options['accountCanonicalForm']
        $username = $this->ldap->getCanonicalAccountName($username, $option);
        switch ($option) {
            case Ldap::ACCTNAME_FORM_USERNAME: // traditional style usernames, e.g. alice
                $filter = sprintf('(&(objectClass=user)(samaccountname=%s))', AbstractFilter::escapeValue($username));
                break;
            case Ldap::ACCTNAME_FORM_BACKSLASH: // backslash style usernames, e.g. FOO\alice
                // @todo Not supported yet!
                throw new Exception('Backslash style not supported in LDAPGateway::getUserByUsername()!');
                break;
            case Ldap::ACCTNAME_FORM_PRINCIPAL: // principal style usernames, e.g. alice@foo.com
                $filter = sprintf(
                    '(&(objectClass=user)(userprincipalname=%s))',
                    AbstractFilter::escapeValue($username)
                );
                break;
            case Ldap::ACCTNAME_FORM_DN: // distinguished name, e.g. CN=someone,DC=example,DC=co,DC=nz
                // @todo Not supported yet!
                throw new Exception('DN style not supported in LDAPGateway::getUserByUsername()!');
                break;
            default: // default to principal style
                $filter = sprintf(
                    '(&(objectClass=user)(userprincipalname=%s))',
                    AbstractFilter::escapeValue($username)
                );
                break;
        }

        return $this->search($filter, $baseDn, $scope, $attributes);
    }