def run(TargetObjectList, TargetObjectTagList, MixInfo, MixTagName, AutoExpandTemplateMix):
    # TODO: Add sample JSON

    plLogger = PLLogger.GetLogger("methodology")
    stc_sys = CStcSystem.Instance()
    project = stc_sys.GetObject("Project")
    this_cmd = get_this_cmd()
    ctor = CScriptableCreator()

    # Validate the input MixInfo against its schema
    res = json_utils.validate_json(MixInfo, this_cmd.Get('MixInfoJsonSchema'))
    if res != '':
        plLogger.LogError(res)
        this_cmd.Set("Status", res)
        return False

    # Validate the hierarchy against our current command list...
    msg = mix_utils.run_validate_hierarchy(this_cmd, [hierarchy()])
    if msg != '':
        err_str = 'Invalid Sequence: ' + msg
        plLogger.LogError(err_str)
        this_cmd.Set("Status", err_str)
        return False
    # Tag the commands in our command list according to our hierarchy information...
    tag_dict = mix_utils.run_tag_hierarchy(this_cmd, [hierarchy()])

    # Setup for property chaining / outputting the tag dictionary...
    this_cmd.Set('GroupCommandTagInfo', json.dumps(tag_dict))
    plLogger.LogInfo('GroupCommandTagInfo: ' + this_cmd.Get('GroupCommandTagInfo'))

    # Create the StmTemplateMix object...
    plLogger.LogInfo('Creating the route mix object...')
    mix = ctor.Create('StmTemplateMix', project)
    this_cmd.Set('StmTemplateMix', mix.GetObjectHandle())
    # If a MixTagName was specified, then tag the mix with it...
    if MixTagName:
        tag_utils.add_tag_to_object(mix, MixTagName)
    # Copy the entire MixInfo into StmTemplateMix object...
    mix.Set('MixInfo', MixInfo)

    # Load the MixInfo...
    err_str, mix_info = json_utils.load_json(MixInfo)
    if err_str != "":
        plLogger.LogError(err_str)
        this_cmd.Set("Status", err_str)
        return False

    # Directly configure all tagged commands in our hierarchy...
    plLogger.LogDebug('setting up commands in the group based on ' + str(tag_dict))

    plLogger.LogDebug('loading json from MixInfo: ' + str(MixInfo))
    num_rows = len(mix_info.get('components', []))
    plLogger.LogDebug('Number of Rows: ' + str(num_rows))

    # Pass table to configurator - this guy will configure other commands per iteration...
    conf_cmd = tag_utils.get_tagged_objects_from_string_names([tag_dict['rowConfigurator']])[0]
    conf_cmd.Set('StmTemplateMix', mix.GetObjectHandle())
    conf_cmd.Set('TagData', this_cmd.Get('GroupCommandTagInfo'))

    # Pass the StmTemplateMix to the CreateTemplateConfigCommand...
    ctc_cmd = tag_utils.get_tagged_objects_from_string_names([tag_dict['templateConfigurator']])[0]
    ctc_cmd.Set('StmTemplateMix', mix.GetObjectHandle())
    ctc_cmd.Set('AutoExpandTemplate', False)

    # Setup Row Iterator (pass in number of rows) - the While command's expression command...
    iter_cmd = tag_utils.get_tagged_objects_from_string_names([tag_dict['rowIterator']])[0]
    iter_cmd.Set('IterMode', 'STEP')
    iter_cmd.Set('StepVal', '1')
    iter_cmd.Set('ValueType', 'RANGE')
    iter_cmd.Set('MinVal', 0.0)
    iter_cmd.Set('MaxVal', (float(num_rows) - 1.0))

    return True
def test_tag_hierarchy(stc):
    hnd_reg = CHandleRegistry.Instance()
    ctor = CScriptableCreator()
    stc_sys = CStcSystem.Instance()
    assert stc_sys is not None
    sequencer = stc_sys.GetObject("Sequencer")

    # Create the parent command
    parent_cmd = ctor.Create(PKG + '.CreateTemplateMixCommand', sequencer)
    parent_cmd_list = parent_cmd.GetCollection('CommandList')
    assert len(parent_cmd_list) == 0

    # Call tag with empty tuples list - tag dict should be empty
    tag_dict = mix_utils.run_tag_hierarchy(parent_cmd, [])
    assert not tag_dict

    # Call create hierarchy with one child command
    mix_utils.init_create_hierarchy(parent_cmd, hierarchy_basic())

    # Call tag with empty tuples list - tag dict should be empty
    tag_dict = mix_utils.run_tag_hierarchy(parent_cmd, [])
    assert not tag_dict

    # Verify commands are not tagged

    # Get parent list
    parent_cmd_list = parent_cmd.GetCollection('CommandList')
    assert len(parent_cmd_list) == 1

    # Verify child command is not tagged
    child_cmd_hnd = parent_cmd_list[0]
    child_cmd = hnd_reg.Find(child_cmd_hnd)
    tag = child_cmd.GetObject('Tag', RelationType('UserTag'))
    assert not tag

    # Get child list
    child_cmd_list = child_cmd.GetCollection('CommandList')
    assert len(child_cmd_list) == 2

    # Check grandchild commands are not tagged
    grandchild_cmd_hnd = child_cmd_list[0]
    grandchild_cmd = hnd_reg.Find(grandchild_cmd_hnd)
    tag = grandchild_cmd.GetObject('Tag', RelationType('UserTag'))
    assert not tag
    grandchild_cmd_hnd = child_cmd_list[1]
    grandchild_cmd = hnd_reg.Find(grandchild_cmd_hnd)
    tag = grandchild_cmd.GetObject('Tag', RelationType('UserTag'))
    assert not tag

    # Call tag with tuples list - tag dict should be populated
    tag_dict = mix_utils.run_tag_hierarchy(parent_cmd, [hierarchy_basic()])
    assert tag_dict

    # Verify tag_dict is correct
    assert tag_dict
    assert 'spirent.methodology.iterationgroupcommand.' in tag_dict['iterationGroup']
    assert 'spirent.methodology.iteratorconfigmixparamscommand.' in tag_dict['rowConfigurator']
    assert 'spirent.methodology.createtemplateconfigcommand.' in tag_dict['templateConfigurator']

    # Verify commands are tagged

    # Get parent list
    parent_cmd_list = parent_cmd.GetCollection('CommandList')
    assert len(parent_cmd_list) == 1

    # Verify child command is tagged
    child_cmd_hnd = parent_cmd_list[0]
    child_cmd = hnd_reg.Find(child_cmd_hnd)
    tag = child_cmd.GetObject('Tag', RelationType('UserTag'))
    assert tag
    assert 'spirent.methodology.iterationgroupcommand.' in tag.Get('Name')

    # Get child list
    child_cmd_list = child_cmd.GetCollection('CommandList')
    assert len(child_cmd_list) == 2

    # Check grandchild commands are tagged
    grandchild_cmd_hnd = child_cmd_list[0]
    grandchild_cmd = hnd_reg.Find(grandchild_cmd_hnd)
    tag = grandchild_cmd.GetObject('Tag', RelationType('UserTag'))
    assert tag
    assert 'spirent.methodology.iteratorconfigmixparamscommand.' in tag.Get('Name')
    grandchild_cmd_hnd = child_cmd_list[1]
    grandchild_cmd = hnd_reg.Find(grandchild_cmd_hnd)
    tag = grandchild_cmd.GetObject('Tag', RelationType('UserTag'))
    assert tag
    assert 'spirent.methodology.createtemplateconfigcommand.' in tag.Get('Name')