def underscorize(camelcased):
    """
    Takes a CamelCase string and returns a separated_with_underscores
    version of that name in all lower case.  If the name is already all in
    lower case and/or separated with underscores, then the returned string
    is identical to the original.  This function is used to take CStruct
    class names and determine the names of their handler methods.
    
    Here are some example conversions:
        underscorize("SomeStruct")   == "some_struct"
        underscorize("SSNLookup")    == "ssn_lookup"
        underscorize("RS485Adaptor") == "rs485_adaptor"
        underscorize("Rot13Encoded") == "rot13_encoded"
        underscorize("RequestQ")     == "request_q"
        underscorize("John316")      == "john316"
    """
    underscored, prev = "", ""
    for i,c in enumerate(camelcased):
        if (prev and not c.islower() and c != "_"
                 and (prev.islower() and not c.isdigit()
                      or c.isupper() and camelcased[i+1:i+2].islower())):
            underscored += "_"
        underscored += c.lower()
        prev = c
    return underscored