CCNxInterestReturnInterface *
ccnxInterestReturnInterface_GetInterface(const CCNxTlvDictionary *dictionary)
{
    assertTrue(ccnxTlvDictionary_IsInterestReturn(dictionary), "Expected an InterestReturn");

    CCNxInterestReturnInterface *impl = ccnxTlvDictionary_GetMessageInterface(dictionary);

    if (!impl) {
        // If we're here, we need to update the interface pointer. Break the const.
        // We're not changing data values, just initializing the Interface pointer.

        // Figure out what the typeInterface should be, based on the attributes we know.
        int schemaVersion = ccnxTlvDictionary_GetSchemaVersion(dictionary);

        switch (schemaVersion) {
            case CCNxTlvDictionary_SchemaVersion_V0:
                trapUnexpectedState("ccnxInterestReturnInterface_GetInterface() not implemented for V0");
            case CCNxTlvDictionary_SchemaVersion_V1:
                impl = &CCNxInterestReturnFacadeV1_Implementation;
                break;
            default:
                trapUnexpectedState("Unknown SchemaVersion encountered in ccnxInterestReturnInterface_GetInterface()");
                break;
        }

        if (impl) {
            ccnxTlvDictionary_SetMessageInterface((CCNxTlvDictionary *) dictionary, impl); // break the const.
        }
    }

    return impl;
}
static CCNxManifest *
_ccnxManifest_InternalCreate(const CCNxManifestInterface *impl, const CCNxName *name)
{
    CCNxManifest *result = NULL;

    if (impl->create != NULL) {
        result = impl->create(name);

        // And set the dictionary's interface pointer to the one we just used to create this.
        ccnxTlvDictionary_SetMessageInterface(result, impl);
    } else {
        trapNotImplemented("Manifest implementations must implement create()");
    }

    return result;
}
LONGBOW_TEST_CASE(Global, ccnxContentObjectInterface_GetInterface)
{
    CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie");

    CCNxContentObject *contentObjectV1 =
        ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation,
                                                   name,
                                                   CCNxPayloadType_DATA,
                                                   NULL);

    assertTrue(ccnxContentObjectInterface_GetInterface(contentObjectV1) == &CCNxContentObjectFacadeV1_Implementation,
               "Expected V1 Implementation");

    // Now unset the pointer and see if it gets derived properly.
    ccnxTlvDictionary_SetMessageInterface(contentObjectV1, NULL);
    assertTrue(ccnxContentObjectInterface_GetInterface(contentObjectV1) == &CCNxContentObjectFacadeV1_Implementation,
               "Expected V1 Implementation");


    ccnxName_Release(&name);
    ccnxContentObject_Release(&contentObjectV1);
}
CCNxContentObject *
ccnxContentObject_CreateWithImplAndPayload(const CCNxContentObjectInterface *impl,
                                           const CCNxName *contentName,
                                           const CCNxPayloadType payloadType,
                                           const PARCBuffer *payload)
{
    CCNxContentObject *result = NULL;

    if (impl->createWithNameAndPayload != NULL) {
        if (contentName == NULL) {
            result = impl->createWithPayload(payloadType, payload);
        } else {
            result = impl->createWithNameAndPayload(contentName, payloadType, payload);
        }

        // And set the dictionary's interface pointer to the one we just used to create this.
        ccnxTlvDictionary_SetMessageInterface(result, impl);
    } else {
        trapNotImplemented("ContentObject implementations must implement createWithNameAndPayload()");
    }

    return result;
}