public synchronized static DiceHand translateToDiceHand(String rawMsg) {
        int totalMod = 0;
        ArrayList<Die> dice = new ArrayList<>();
        String rollee = "NO_ROLLEE_FOUND";
        
        String[] elements = rawMsg.split(ELEMENT_SEP);
        for (int m=0; m<elements.length; m++) {
            // expected format: IDENTIFIER (SIGN) VALUE(S)
            String[] tokens = elements[m].split(VAL_SEP);
            if (tokens.length == 0) {
                continue; // don't worry if it's empty
            }
            // process it based on the starting identifier
            if (tokens[0].equals(DICE_IDENTIFIER)) {
                boolean positive = tokens[1].equals("!");
                if (!positive) System.out.println("NEGATIVE DICE");
                dice.add(new Die(Integer.parseInt(tokens[2]), // size first
                        Integer.parseInt(tokens[3]), // then result
                        positive));
            } else if (tokens[0].equals(MOD_IDENTIFIER)) {
                totalMod += Integer.parseInt(tokens[1]);
            } else if (tokens[0].equals(ROLLEE_IDENTIFIER)) {
                rollee = tokens[1];
            }
        }
        
        return new DiceHand(rawMsg, rollee, totalMod, dice);
    }