Parse the docstring into its components.

    :return: a dictionary of form
              {
                  "short_description": ...,
                  "long_description": ...,
                  "params": [{"name": ..., "doc": ...}, ...],
                  "vals": [{"name": ..., "doc": ...}, ...],
                  "return": ...
              }

def parse_docstring(docstring):
    """Parse the docstring into its components.

    :return: a dictionary of form
              {
                  "short_description": ...,
                  "long_description": ...,
                  "params": [{"name": ..., "doc": ...}, ...],
                  "vals": [{"name": ..., "doc": ...}, ...],
                  "return": ...
              }
    """

    short_description = long_description = return_str = ""
    args = []

    if docstring:
        docstring = trim(docstring.lstrip("\n"))

        lines = docstring.split("\n", 1)
        short_description = lines[0]

        if len(lines) > 1:
            long_description = lines[1].strip()

            params_return_desc = None

            match = PARAM_OR_RETURN_REGEX.search(long_description)
            if match:
                long_desc_end = match.start()
                params_return_desc = long_description[long_desc_end:].strip()
                long_description = long_description[:long_desc_end].rstrip()

            if params_return_desc:
                args = [
                    {"name": name, "doc": trim(doc), "field": field}
                    for field, name, doc in NEW_REGEX.findall(params_return_desc)
                ]
                match = RETURN_REGEX.search(params_return_desc)
                if match:
                    return_str = reindent(match.group("doc"))
    comments = {p['name']: p['doc'] for p in args}
    return {
        "short_description": short_description,
        "long_description": long_description,
        "args": args,
        "comments": comments,
        "return": return_str
    }