def get_valid_handles(handle_list, tag_name_list):
    hnd_reg = CHandleRegistry.Instance()
    l2_obj_list = []
    l3_obj_list = []
    l2_handle_list = []
    l3_handle_list = []

    # Add object handles from the tag list to the handle list
    if len(tag_name_list) > 0:
        for obj in tag_utils.get_tagged_objects_from_string_names(tag_name_list):
            handle_list.append(obj.GetObjectHandle())

    # The L2 learning command only allows handles of type Port and StreamBlock
    # The L3 learning command only allows handles of type Port, StreamBlock, Host,
    # Router, and EmulatedDevice
    for hnd in handle_list:
        obj = hnd_reg.Find(hnd)
        if obj.IsTypeOf("Port") or obj.IsTypeOf("StreamBlock") or obj.IsTypeOf("Project"):
            l2_obj_list.append(obj)
            l3_obj_list.append(obj)
        elif obj.IsTypeOf("EmulatedDevice") or obj.IsTypeOf("Host") or obj.IsTypeOf("Router"):
            l3_obj_list.append(obj)
        elif obj.IsTypeOf("StmTemplateMix") or obj.IsTypeOf("StmTemplateConfig"):
                l2_obj_list.extend(dm_utils.get_class_objects([hnd], [],
                                                              ["Port",
                                                               "StreamBlock",
                                                               "Project"]))
                l3_obj_list.extend(dm_utils.get_class_objects([hnd], [],
                                                              ["Port",
                                                               "StreamBlock",
                                                               "Project",
                                                               "EmulatedDevice",
                                                               "Host",
                                                               "Router"]))

    for obj in dm_utils.sort_obj_list_by_handle(l2_obj_list):
        l2_handle_list.append(obj.GetObjectHandle())
    for obj in dm_utils.sort_obj_list_by_handle(l3_obj_list):
        l3_handle_list.append(obj.GetObjectHandle())
    return l2_handle_list, l3_handle_list
def test_sort_obj_list_by_handle(stc):
    ctor = CScriptableCreator()
    project = CStcSystem.Instance().GetObject("Project")
    dev1 = ctor.Create("EmulatedDevice", project)
    dev2 = ctor.Create("EmulatedDevice", project)
    res_val = dm_utils.sort_obj_list_by_handle([dev1, dev2, dev1, project])
    assert len(res_val) == 3
    assert res_val[0].GetObjectHandle() == project.GetObjectHandle()
    assert res_val[1].GetObjectHandle() == dev1.GetObjectHandle()
    assert res_val[2].GetObjectHandle() == dev2.GetObjectHandle()

    res_val = dm_utils.sort_obj_list_by_handle([project, dev2, dev1])
    assert len(res_val) == 3
    assert res_val[0].GetObjectHandle() == project.GetObjectHandle()
    assert res_val[1].GetObjectHandle() == dev1.GetObjectHandle()
    assert res_val[2].GetObjectHandle() == dev2.GetObjectHandle()

    res_val = dm_utils.sort_obj_list_by_handle([project, dev1, dev2])
    assert len(res_val) == 3
    assert res_val[0].GetObjectHandle() == project.GetObjectHandle()
    assert res_val[1].GetObjectHandle() == dev1.GetObjectHandle()
    assert res_val[2].GetObjectHandle() == dev2.GetObjectHandle()