public function search($scope, $baseDn, $filter, $attributes = null)
    {
        switch ($scope) {
            case SearchInterface::SCOPE_BASE:
                $function = 'ldap_read';
                break;
            case SearchInterface::SCOPE_ONE:
                $function = 'ldap_list';
                break;
            case SearchInterface::SCOPE_ALL:
                $function = 'ldap_search';
                break;
            default:
                throw new SearchException(sprintf('Scope %s not supported', $scope));
        }

        $params = array($this->connection, $baseDn, $filter);
        if (is_array($attributes)) {
            $params[] = $attributes;
        }

        if (false === ($search = @call_user_func_array($function, $params))) {
            $code = @ldap_errno($this->connection);
            switch ($code) {

            case 32:
                throw new NoResultException('No result retrieved for the given search');
                break;
            case 4:
                throw new SizeLimitException(
                    'Size limit reached while performing the expected search'
                );
                break;
            case 87:
                throw new MalformedFilterException(
                    sprintf('Search for filter %s fails for a malformed filter', $filter)
                );
                break;
            default:
                throw new SearchException(
                    sprintf(
                        'Search on %s with filter %s failed. Ldap Error Code:%s - %s',
                        $baseDn,
                        $filter,
                        $code,
                        ldap_err2str($code)
                    )
                );
            }
        }

        return new Search($this->connection, $search);
    }