def form(title, fields, methods, data, icon=None, id=None, **context):
    """
    Used by user to edit some data.

    If user presses the button <method>, the appropriate method <method> will be called at AdminController.
    Values from the methods will be passed to the <method>'s arguments.

    Typical approach:

    [
        a.form("Edit user", fields={
            "username": a.field("Username", "text", "primary", "non-empty"),
            "age": a.field("Age", "text", "primary", "number")
        }, methods={
            "update": a.method("Update", "primary")
        }, data=data)
    ]

    After user action, the method update(username, action) will be called.
    To fill-up this form, method get() should return {"username": "John", "age": 21}

    :param title: Title of the form.
    :param fields: Dict of fields, each key represents field ID
    :param methods: Dict of method buttons, each key represents form method
    :param data: (dict) Data passed to this field will be used by fields to fill-up the form.
    :param icon: (optional) Form icon
    :param id: (optional) An ID for API usage
    :param context: (optional) Context may be used by fields.
    """
    f = {}

    for field_id, _field in fields.items():
        f[field_id] = {"value": data.get(field_id, None)}
        f[field_id].update(_field)

    result = {
        "class": "form",
        "title": title,
        "fields": f,
        "icon": icon,
        "methods": {method_id: _method for method_id, _method in methods.items()},
        "context": context
    }

    if id:
        result["id"] = id

    return result