docs: def defaultSerialize(obj, buf, lineLength):
      """
      Encode and fold obj and its children, write to buf or return a string.
      """
      outbuf = buf or six.StringIO()
  
      if isinstance(obj, Component):
          if obj.group is None:
              groupString = ''
          else:
              groupString = obj.group + '.'
          if obj.useBegin:
              foldOneLine(outbuf, "{0}BEGIN:{1}".format(groupString, obj.name),
                          lineLength)
          for child in obj.getSortedChildren():
              # validate is recursive, we only need to validate once
              child.serialize(outbuf, lineLength, validate=False)
          if obj.useBegin:
              foldOneLine(outbuf, "{0}END:{1}".format(groupString, obj.name),
                          lineLength)
  
      elif isinstance(obj, ContentLine):
          startedEncoded = obj.encoded
          if obj.behavior and not startedEncoded:
              obj.behavior.encode(obj)
  
          s = six.StringIO()
  
          if obj.group is not None:
              s.write(obj.group + '.')
          s.write(obj.name.upper())
          keys = sorted(obj.params.keys())
          for key in keys:
              paramstr = ','.join(dquoteEscape(p) for p in obj.params[key])
              s.write(";{0}={1}".format(key, paramstr))
          s.write(":{0}".format(str_(obj.value)))
          if obj.behavior and not startedEncoded:
              obj.behavior.decode(obj)
          foldOneLine(outbuf, s.getvalue(), lineLength)
  
      return buf or outbuf.getvalue()