class AuthzHelper {

    public static boolean checkRoleMemberValidity(List<RoleMember> roleMembers, final String member,
                                                  GroupMembersFetcher groupMembersFetcher) {

        // we need to make sure that both the user is not expired
        // and not disabled by the system. the members can also
        // include groups so that means even if we get a response
        // from one group that is expired, we can't just stop
        // and need to check the other groups as well.
        // For efficiency reasons we'll process groups at the
        // end so in case we get a match in a role there is no
        // need to look at the groups at all

        List<RoleMember> groupMembers = new ArrayList<>();
        for (RoleMember memberInfo: roleMembers) {
            if (memberInfo.getPrincipalType() != null && memberInfo.getPrincipalType() == Principal.Type.GROUP.getValue()) {
                groupMembers.add(memberInfo);
            }
        }

        // first only process regular members

        boolean isMember = false;
        long currentTime = System.currentTimeMillis();
        for (RoleMember memberInfo: roleMembers) {
            if (memberInfo.getPrincipalType() != null && memberInfo.getPrincipalType() == Principal.Type.GROUP.getValue()) {
                continue;
            }
            final String memberName = memberInfo.getMemberName();
            if (memberNameMatch(memberName, member)) {
                isMember = !isMemberDisabled(memberInfo.getSystemDisabled()) && !isMemberExpired(memberInfo.getExpiration(), currentTime);
                break;
            }
        }

        // if we have a match or no group members then we're done

        if (isMember || groupMembers.isEmpty()) {
            return isMember;
        }

        // now let's process our groups

        for (RoleMember memberInfo : groupMembers) {

            // if the group is expired there is no need to check

            if (isMemberExpired(memberInfo.getExpiration(), currentTime)) {
                continue;
            }
            isMember = isMemberOfGroup(groupMembersFetcher.getGroupMembers(memberInfo.getMemberName()), member);
            if (isMember) {
                break;
            }
        }
        return isMember;
    }

}