public static function compressMessageSet($messages, $force=false)
    {
        // given a comma delimited list of independent mid's,
        // compresses by grouping sequences together
        if (!is_array($messages)) {
            // if less than 255 bytes long, let's not bother
            if (!$force && strlen($messages) < 255) {
                return preg_match('/[^0-9:,*]/', $messages) ? 'INVALID' : $messages;
            }

            // see if it's already been compressed
            if (strpos($messages, ':') !== false) {
                return preg_match('/[^0-9:,*]/', $messages) ? 'INVALID' : $messages;
            }

            // separate, then sort
            $messages = explode(',', $messages);
        }

        sort($messages);

        $result = array();
        $start  = $prev = $messages[0];

        foreach ($messages as $id) {
            $incr = $id - $prev;
            if ($incr > 1) { // found a gap
                if ($start == $prev) {
                    $result[] = $prev; // push single id
                }
                else {
                    $result[] = $start . ':' . $prev; // push sequence as start_id:end_id
                }
                $start = $id; // start of new sequence
            }
            $prev = $id;
        }

        // handle the last sequence/id
        if ($start == $prev) {
            $result[] = $prev;
        }
        else {
            $result[] = $start.':'.$prev;
        }

        // return as comma separated string
        $result = implode(',', $result);

        return preg_match('/[^0-9:,*]/', $result) ? 'INVALID' : $result;
    }