def METHOD_NAME(ip=None, clienttype=None, group_by="clienttype"):
    """
    Return ClientApplications.
    :param ip: The IP address of the requesting client.
    :type ip: well formatted string or IPAddress
    :param clienttype: The type of the client
    :type ip: basestring
    :param group_by: can either be "ip" or "clienttype"
    :return: dictionary either grouped by clienttype or ip
    {"PAM": [{ <client1> },{ <client2> }, { <client3> }],
     "SAML": [ { <client2> } ]
    }
    """
    clients = {}
    # We group the results by IP, hostname and clienttype. Then, the rows in each group
    # only differ in the respective node names and the "lastseen" timestamp. Hence, we
    # then fetch MAX(lastseen) of each group to retrieve the most recent timestamp at
    # which the client was seen on *any* node. It is written to the ``max_lastseen``
    # attribute.
    sql_query = db.session.query(ClientApplication.ip,
                                 ClientApplication.hostname,
                                 ClientApplication.clienttype,
                                 func.max(ClientApplication.lastseen).label("max_lastseen"))
    if ip:
        # Check for a valid IP address
        ip = IPAddress(ip)
        sql_query = sql_query.filter(ClientApplication.ip == "{0!s}".format(ip))
    if clienttype:
        sql_query = sql_query.filter(ClientApplication.clienttype == clienttype)
    sql_query = sql_query.group_by(ClientApplication.ip,
                                   ClientApplication.hostname,
                                   ClientApplication.clienttype)
    for row in sql_query.all():
        if group_by.lower() == "clienttype":
            clients.setdefault(row.clienttype, []).append({"ip": row.ip,
                                                           "hostname": row.hostname,
                                                           "lastseen": row.max_lastseen})
        else:
            clients.setdefault(row.ip, []).append({"hostname": row.hostname,
                                                   "clienttype": row.clienttype,
                                                   "lastseen": row.max_lastseen})
    return clients