docs: def clazz(clazz, parent_clazz, description, link, params_string, init_super_args=None):
      """
      Live template for pycharm:
  
      y = clazz(clazz="$clazz$", parent_clazz="%parent$", description="$desc$", link="$lnk$", params_string="$first_param$")
      """
      init_description_w_tabs  = description.strip().replace("\n", "\n\t\t")
      clazz_description_w_tabs = description.strip().replace("\n", "\n\t")
      imports = [[], []]
      args = []
      args2 = []
      kwargs = []
      kwargs2 = []
      asserts = []
      str_args = ""
      str_kwargs = ""
      to_array1 = []
      to_array2 = []
      from_array1 = []
      from_array2 = []
      param_strings = params_string.split("\n")
      for param in param_strings:
          assert_commands, assert_comments, param_name, param_type, table, non_buildin_type, param_name_input = parse_param_types(param)
          param_description = table[2].strip()
          param_needed = not param_description.startswith("Optional.")
          asserts.append("")
          if param_needed:
              args.append(param_name)
              str_args += '\n\n\t\t:param {key}: {descr}\n\t\t:type  {key}: {type}'.format(key=param_name, descr=param_description, type=get_type_path(param_type))
              if assert_commands:
                  asserts.append("assert({var} is not None)".format(var=param_name))
                  asserts.append("assert({ass})".format(ass=" or ".join(assert_commands)) + (("  # {comment}".format(comment=", ".join(assert_comments))) if assert_comments else ""))
              if non_buildin_type:
                  to_array1.append('array["{var}"] = self.{var}.to_array()'.format(var=param_name))
                  from_array1.append("data['{var}'] = {type}.from_array(array.get('{array_key}'))".format(var=param_name, array_key=param_name_input, type=non_buildin_type))
              else:
                  to_array1.append('array["{var}"] = self.{var}'.format(var=param_name))
                  from_array2.append("data['{var}'] = array.get('{array_key}')  # type {type}".format(var=param_name, array_key=param_name_input, type=non_buildin_type))
              # end if non_buildin_type
          else:
              kwargs.append("{param_name}=None".format(param_name=param_name))
              str_kwargs += '\n\n\t\t:keyword {key}: {descr}\n\t\t:type    {key}: {type}'.format(key=param_name, descr=param_description, type=param_type)
              if assert_commands:
                  asserts.append("assert({var} is None or {ass})".format(var=param_name, ass=" or ".join(assert_commands)) + (("  # {comment}".format(comment=", ".join(assert_comments))) if assert_comments else ""))
              to_array2.append('if self.{var} is not None:'.format(var=param_name))
              if non_buildin_type:
                  to_array2.append('\tarray["{var}"] = self.{var}.to_array()'.format(var=param_name))
                  from_array2.append("data['{var}'] = {type}.from_array(array.get('{array_key}'))".format(var=param_name, array_key=param_name_input, type=non_buildin_type))
              else:
                  to_array2.append('\tarray["{var}"] = self.{var}'.format(var=param_name))
                  from_array2.append("data['{var}'] = array.get('{array_key}')  # type {type}".format(var=param_name, array_key=param_name_input, type=non_buildin_type))
          # end if non_buildin_type
          asserts.append("self.{param_name} = {param_name}".format(param_name=param_name))
      param_description = ""
      if len(str_args)>0:
          param_description += '\n\t\tParameters:'
          param_description += str_args
      if len(str_kwargs)>0:
          param_description += '\n\n\n\t\tOptional keyword parameters:'
          param_description += str_kwargs
      args.extend(kwargs)
      to_array = ["array = super({clazz}, self).to_array()".format(clazz=clazz)]
      to_array.extend(to_array1)
      to_array.extend(to_array2)
      from_array = ["data = super({clazz}).from_array(array)".format(clazz=clazz)]
      from_array.extend(from_array1)
      from_array.extend(from_array2)
      from_array.append("return {clazz}(**data)".format(clazz=clazz))
      result = 'class {clazz}({parent_clazz}):\n' \
               '\t"""\n' \
               '\t{clazz_description_w_tabs}\n' \
               '\n' \
               '\t{link}\n' \
               '\t"""\n' \
               '\tdef __init__(self, {params}):\n' \
               '\t\t"""\n' \
               '\t\t{init_description_w_tabs}\n' \
               '\n' \
               '\t\t{link}\n' \
               '\n' \
               '{param_description}\n' \
               '\t\t"""\n' \
               '\t\tsuper({clazz}, self).__init__({init_super_args})\n' \
               '\t\t{asserts_with_tabs}\n' \
               '\t# end def __init__\n' \
               '\n' \
               '\tdef to_array(self):\n' \
               '\t\t{to_array_with_tabs}\n' \
               '\t\treturn array\n' \
               '\t# end def to_array\n' \
               '\n' \
               '\t@staticmethod\n' \
               '\tdef from_array(array):\n' \
               '\t\tif array is None:\n' \
               '\t\t\treturn None\n' \
               '\t\t# end if\n' \
               '\t\t{from_array_with_tabs}\n' \
               '\t# end def from_array\n' \
               '# end class {clazz}\n'.format(
          clazz=clazz, parent_clazz=parent_clazz, params=", ".join(args), param_description = param_description,
          clazz_description_w_tabs=clazz_description_w_tabs, init_description_w_tabs=init_description_w_tabs, link=link,
          asserts_with_tabs="\n\t\t".join(asserts), to_array_with_tabs="\n\t\t".join(to_array),
          from_array_with_tabs="\n\t\t".join(from_array),
          init_super_args=(", ".join(init_super_args) if init_super_args else "")
      )
      result = result.replace("\t", "    ")
      return result