import collections
import re
import urllib
import urlparse


class QueryString(unicode):

    def __repr__(self):
        return 'QueryString(%r)' % (unicode(self),)

    @property
    def list(self):
        result = []
        if not self:
            # Empty string => empty list.
            return result

        name_value_pairs = re.split(r'[\&\;]', self)
        for name_value_pair in name_value_pairs:
            # Split the pair string into a naive, encoded (name, value) pair.
            name_value = name_value_pair.split('=', 1)
            # 'param=' => ('param', None)
            if len(name_value) == 1:
                name, value = name_value + [None]
            # 'param=value' => ('param', 'value')
            # 'param=' => ('param', '')
            else:
                name, value = name_value

            name = qs_decode(name)
            if value is not None:
                value = qs_decode(value)

            result.append((name, value))
        return result

    @property
    def dict(self):
        return dict(self.list)

    @property
    def multi_dict(self):
        result = collections.defaultdict(list)
        for name, value in self.list:
            result[name].append(value)
        return dict(result)

    def add_param(self, name, value):
        if value is None:
            parameter = qs_encode(name)
        elif not isinstance(value, basestring):
            # value is a list or tuple
            parameter = '&'.join([qs_encode(name) + '=' + qs_encode(val) for val in value])
        else:
            parameter = qs_encode(name) + '=' + qs_encode(value)
        if self:
            return type(self)(self + '&' + parameter)
        return type(self)(parameter)

    def add_params(self, *args, **kwargs):
        params_list = get_params_list(*args, **kwargs)
        new = self
        for name, value in params_list:
            new = new.add_param(name, value)
        return new

    def del_param(self, name):
        params = [(n, v) for n, v in self.list if n != name]
        qs = type(self)('')
        for param in params:
            qs = qs.add_param(*param)
        return qs

    def set_param(self, name, value):
        return self.del_param(name).add_param(name, value)

    def set_params(self, *args, **kwargs):
        params_list = get_params_list(*args, **kwargs)
        new = self
        for name, value in params_list:
            new = new.set_param(name, value)
        return new

    def del_params(self, params):
        deleted = set(params)
        params = [(name, value) for name, value in self.list
                  if name not in deleted]
        qs = type(self)('')
        for param in params:
            qs = qs.add_param(*param)
        return qs


qs_encode = lambda s: urllib.quote(s.encode('utf-8'))
qs_decode = lambda s: urllib.unquote(str(s).replace('+', ' ')).decode('utf-8')


def get_params_list(*args, **kwargs):
    """Turn dict-like arguments into an ordered list of pairs."""
    params = []
    if args:
        if len(args) > 1:
            raise TypeError("Expected at most 1 arguments, got 2")
        arg = args[0]
        if hasattr(arg, 'items'):
            params.extend(arg.items())
        else:
            params.extend(list(arg))
    if kwargs:
        params.extend(kwargs.items())
    return params

@@ -1402,16 +1402,47 @@
 estring)
+ and hasattr(value, '__iter__')
 :%0A      

Make sure new condition only passes lists/tuples