docs: def parse(query_string, unquote=True, normalized=False, encoding=DEFAULT_ENCODING):
      '''
      Main parse function
      @param query_string:
      @param unquote: unquote html query string ?
      @param encoding: An optional encoding used to decode the keys and values. Defaults to utf-8, which the W3C declares as a defaul in the W3C algorithm for encoding.
      @see http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
  
      @param normalized: parse number key in dict to proper list ?
      '''
      
      mydict = {}
      plist = []
      if query_string == "":
          return mydict
      
      if type(query_string) == bytes:
        query_string = query_string.decode()
      
      for element in query_string.split("&"):
          try:
              if unquote:
                  (var, val) = element.split("=")
                  if sys.version_info[0] == 2:
                    var = var.encode('ascii')
                    val = val.encode('ascii')
                  var = urllib.unquote_plus(var)
                  val = urllib.unquote_plus(val)
              else:
                  (var, val) = element.split("=")
          except ValueError:
              raise MalformedQueryStringError
          if encoding:
              var = var.decode(encoding)
              val = val.decode(encoding)
          plist.append(parser_helper(var, val))
      for di in plist:
          (k, v) = di.popitem()
          tempdict = mydict
          while k in tempdict and type(v) is dict:
              tempdict = tempdict[k]
              (k, v) = v.popitem()
          if k in tempdict and type(tempdict[k]).__name__ == 'list':
              tempdict[k].append(v)
          elif k in tempdict:
              tempdict[k] = [tempdict[k], v]
          else:
              tempdict[k] = v
  
      if normalized == True:
          return _normalize(mydict)
      return mydict