BOOLEAN CopyArgument(_Out_ OVS_ARGUMENT* pDest, _In_ const OVS_ARGUMENT* pSource)
{
    OVS_CHECK(pDest);
    OVS_CHECK(pSource);

    pDest->type = pSource->type;
    pDest->length = pSource->length;
    pDest->isDisabled = pSource->isDisabled;
    pDest->isNested = pSource->isNested;
    pDest->freeData = pSource->freeData;

    if (pDest->length)
    {
        pDest->data = KZAlloc(pDest->length);
        if (!pDest->data)
        {
            return FALSE;
        }
    }

    if (IsArgTypeGroup(pDest->type))
    {
        if (!CopyArgumentGroup(pDest->data, pSource->data, /*args more*/0))
        {
            DestroyArgumentGroup(pDest->data);
        }
    }
    else
    {
        RtlCopyMemory(pDest->data, pSource->data, pDest->length);
    }

    return TRUE;
}
static BOOLEAN _CreateActionsArgsToList(const OVS_ARGUMENT_GROUP* pArgGroup, OVS_ARGUMENT_SLIST_ENTRY** ppArgList)
{
    BOOLEAN ok = TRUE;

    for (UINT i = 0; i < pArgGroup->count; ++i)
    {
        const OVS_ARGUMENT* pArg = pArgGroup->args + i;
        OVS_ARGTYPE argType = pArg->type;

        switch (argType)
        {
        case OVS_ARGTYPE_ACTION_SETINFO_GROUP:
        {
            OVS_ARGUMENT_GROUP* pSetGroup = NULL;
            OVS_ARGUMENT* pPacketInfoArg = NULL, *pSetArg = NULL;

            pPacketInfoArg = _CreateSetActionArg(pArg);
            if (!pPacketInfoArg)
            {
                return FALSE;
            }

            pSetGroup = KZAlloc(sizeof(OVS_ARGUMENT_GROUP));
            if (!pSetGroup)
            {
                return FALSE;
            }

            pSetGroup->args = pPacketInfoArg;
            pSetGroup->count = 1;
            pSetGroup->groupSize = pPacketInfoArg->length + OVS_ARGUMENT_HEADER_SIZE;

            pSetArg = KZAlloc(sizeof(OVS_ARGUMENT));
            pSetArg->data = pSetGroup;
            pSetArg->type = OVS_ARGTYPE_ACTION_SETINFO_GROUP;
            pSetArg->length = pSetGroup->groupSize + OVS_ARGUMENT_GROUP_HEADER_SIZE;

            if (!AppendArgumentToList(pSetArg, ppArgList))
            {
                return FALSE;
            }
        }
            break;

        case OVS_ARGTYPE_ACTION_SAMPLE_GROUP:
            ok = _SampleActionToList(pArg->data, ppArgList);
            if (!ok)
            {
                return FALSE;
            }

            break;

        case OVS_ARGTYPE_ACTION_UPCALL_GROUP:
        {
            OVS_ARGUMENT_GROUP* pUpcallGroup = NULL;
            OVS_ARGUMENT* pUpcallArg = NULL;
            BOOLEAN ok = TRUE;

            pUpcallGroup = KZAlloc(sizeof(OVS_ARGUMENT_GROUP));
            if (NULL == pUpcallGroup)
            {
                return FALSE;
            }

            ok = CopyArgumentGroup(pUpcallGroup, pArg->data, /*actionsToAdd*/0);
            if (!ok)
            {
                DestroyArgumentGroup(pUpcallGroup);
                return FALSE;
            }

            pUpcallArg = CreateArgumentFromGroup(argType, pUpcallGroup);

            if (!AppendArgumentToList(pUpcallArg, ppArgList))
            {
                return FALSE;
            }
        }
            break;

        default:
        {
            OVS_ARGUMENT* pDestArg = KAlloc(sizeof(OVS_ARGUMENT));
            if (!pDestArg)
            {
                return FALSE;
            }

            CopyArgument(pDestArg, pArg);

            if (!AppendArgumentToList(pDestArg, ppArgList))
            {
                return FALSE;
            }
        }
            break;
        }
    }

    return TRUE;
}