This function takes a Tree and flattens it so that all subclasses instances
    are replaced by the their equations and symbols with name mangling
    of the instance name passed.
    :param root: The Tree to flatten
    :param class_name: The class that we want to create a flat model for
    :return: flat_class, a Class containing the flattened class

def flatten(root: ast.Tree, class_name: ast.ComponentRef) -> ast.Class:
    """
    This function takes a Tree and flattens it so that all subclasses instances
    are replaced by the their equations and symbols with name mangling
    of the instance name passed.
    :param root: The Tree to flatten
    :param class_name: The class that we want to create a flat model for
    :return: flat_class, a Class containing the flattened class
    """
    orig_class = root.find_class(class_name, copy=False)

    flat_class = flatten_class(orig_class)

    # expand connectors
    expand_connectors(flat_class)

    # add equations for state symbol values
    add_state_value_equations(flat_class)
    for func in flat_class.functions.values():
        add_variable_value_statements(func)

    # annotate states
    annotate_states(flat_class)

    # Put class in root
    root = ast.Tree()
    root.classes[orig_class.name] = flat_class

    # pull functions to the top level,
    # putting them prior to the model class so that they are visited
    # first by the tree walker.
    functions_and_classes = flat_class.functions
    flat_class.functions = OrderedDict()
    functions_and_classes.update(root.classes)
    root.classes = functions_and_classes

    return root