# File lib/active_ldap/operations.rb, line 27
      def search(options={}, &block)
        validate_search_options(options)
        attr = options[:attribute]
        value = options[:value] || '*'
        filter = options[:filter]
        prefix = options[:prefix]
        classes = options[:classes]

        value = value.first if value.is_a?(Array) and value.first.size == 1

        _attr = nil
        _prefix = nil
        if attr.nil? or attr == dn_attribute
          _attr, value, _prefix = split_search_value(value)
        end
        attr ||= _attr || ensure_search_attribute
        prefix ||= _prefix
        filter ||= [attr, value]
        filter = [:and, filter, *object_class_filters(classes)]
        _base = options[:base] ? [options[:base]] : [prefix, base]
        _base = prepare_search_base(_base)
        if options.has_key?(:ldap_scope)
          logger.warning do
            _(":ldap_scope search option is deprecated. Use :scope instead.")
          end
          options[:scope] ||= options[:ldap_scope]
        end
        search_options = {
          :base => _base,
          :scope => options[:scope] || scope,
          :filter => filter,
          :limit => options[:limit],
          :attributes => options[:attributes],
          :sort_by => options[:sort_by] || sort_by,
          :order => options[:order] || order,
        }

        options[:connection] ||= connection
        options[:connection].search(search_options) do |dn, attrs|
          attributes = {}
          attrs.each do |key, value|
            normalized_attr, normalized_value =
              normalize_attribute_options(key, value)
            attributes[normalized_attr] ||= []
            attributes[normalized_attr].concat(normalized_value)
          end
          value = [dn, attributes]
          value = yield(value) if block_given?
          value
        end
      end