def METHOD_NAME(val):
    # type: (Any) -> value_t
    if val is None:
        return value.Null
    elif isinstance(val, bool):
        return value.Bool(val)
    elif isinstance(val, int):
        return value.Int(val)
    elif isinstance(val, float):
        return value.Float(val)
    elif isinstance(val, str):
        return value.Str(val)
    elif isinstance(val, list):
        # Hack for converting back and forth
        is_shell_array = True
        shell_array = []  # type: List[str]
        typed_array = []  # type: List[value_t]
        for elem in val:
            if elem is None:
                shell_array.append(elem)
                typed_array.append(value.Null)
            elif isinstance(elem, str):
                shell_array.append(elem)
                typed_array.append(value.Str(elem))
            elif isinstance(elem, value_t):  # Does this happen?
                is_shell_array = False
                typed_array.append(elem)
            else:
                is_shell_array = False
                typed_array.append(METHOD_NAME(elem))
                #typed_array.append(elem)
        #if is_shell_array:
        #    return value.BashArray(shell_array)
        return value.List(typed_array)
    elif isinstance(val, xrange):
        # awkward, but should go away once everything is typed...
        l = list(val)
        if len(l) > 1:
            return value.Range(l[0], l[-1])
        # Empty range
        return value.Range(0, 0)
    elif isinstance(val, dict):
        is_shell_dict = True
        shell_dict = NewDict()  # type: Dict[str, str]
        typed_dict = NewDict()  # type: Dict[str, value_t]
        for k, v in val.items():
            if isinstance(v, str):
                shell_dict[k] = v
                typed_dict[k] = value.Str(v)
            elif isinstance(v, value_t):  # Does this happen?
                is_shell_dict = False
                typed_dict[k] = v
            else:
                is_shell_dict = False
                typed_dict[k] = METHOD_NAME(v)
                #typed_dict[k] = v
        if is_shell_dict:
            return value.BashAssoc(shell_dict)
        else:
            return value.Dict(typed_dict)
    elif isinstance(val, value.Eggex):
        return val  # passthrough
    elif isinstance(val, value.Block):
        return val  # passthrough
    elif isinstance(val, vm._Callable) or callable(val):
        return value.Func(val)
    else:
        raise error.Expr(
            'Trying to convert unexpected type to value_t: %r' % val,
            loc.Missing)