DECODE_JSON(ExpandedNodeId) {
    ALLOW_NULL;
    CHECK_OBJECT;

    /* Keep track over number of keys present, incremented if key found */
    u8 fieldCount = 0;
    
    /* ServerUri */
    UA_Boolean hasServerUri = false;
    size_t searchResultServerUri = 0;
    status ret = lookAheadForKey(UA_JSONKEY_SERVERURI, ctx, parseCtx, &searchResultServerUri);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->serverIndex = 0; 
    } else {
        hasServerUri = true;
    }
    
    /* NameSpace */
    UA_Boolean hasNamespace = false;
    UA_Boolean isNamespaceString = false;
    size_t searchResultNamespace = 0;
    ret = lookAheadForKey(UA_JSONKEY_NAMESPACE, ctx, parseCtx, &searchResultNamespace);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->namespaceUri = UA_STRING_NULL;
    } else {
        hasNamespace = true;
        jsmntok_t nsToken = parseCtx->tokenArray[searchResultNamespace];
        if(nsToken.type == JSMN_STRING)
            isNamespaceString = true;
    }

    DecodeEntry entries[4];
    ret = prepareDecodeNodeIdJson(&dst->nodeId, ctx, parseCtx, &fieldCount, entries);
    if(ret != UA_STATUSCODE_GOOD)
        return ret;

    if(hasNamespace) {
        entries[fieldCount].fieldName = UA_JSONKEY_NAMESPACE;
        if(isNamespaceString) {
            entries[fieldCount].fieldPointer = &dst->namespaceUri;
            entries[fieldCount].function = (decodeJsonSignature) String_decodeJson;
        } else {
            entries[fieldCount].fieldPointer = &dst->nodeId.namespaceIndex;
            entries[fieldCount].function = (decodeJsonSignature) UInt16_decodeJson;
        }
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++; 
    }
    
    if(hasServerUri) {
        entries[fieldCount].fieldName = UA_JSONKEY_SERVERURI;
        entries[fieldCount].fieldPointer = &dst->serverIndex;
        entries[fieldCount].function = (decodeJsonSignature) UInt32_decodeJson;
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++;  
    } else {
        dst->serverIndex = 0;
    }
    
    return decodeFields(ctx, parseCtx, entries, fieldCount, type);
}
DECODE_JSON(ExpandedNodeId) {
    ALLOW_NULL;
    CHECK_OBJECT;

     
    u8 fieldCount = 0;
    
     
    UA_Boolean hasServerUri = false;
    size_t searchResultServerUri = 0;
    status ret = lookAheadForKey(UA_JSONKEY_SERVERURI, ctx, parseCtx, &searchResultServerUri);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->serverIndex = 0; 
    } else {
        hasServerUri = true;
    }
    
     
    UA_Boolean hasNamespace = false;
    UA_Boolean isNamespaceString = false;
    size_t searchResultNamespace = 0;
    ret = lookAheadForKey(UA_JSONKEY_NAMESPACE, ctx, parseCtx, &searchResultNamespace);
    if(ret != UA_STATUSCODE_GOOD) {
        dst->namespaceUri = UA_STRING_NULL;
    } else {
        hasNamespace = true;
        jsmntok_t nsToken = parseCtx->tokenArray[searchResultNamespace];
        if(nsToken.type == JSMN_STRING)
            isNamespaceString = true;
    }

    DecodeEntry entries[4];
    ret = prepareDecodeNodeIdJson(&dst->nodeId, ctx, parseCtx, &fieldCount, entries);
    if(ret != UA_STATUSCODE_GOOD)
        return ret;

    if(hasNamespace) {
        entries[fieldCount].fieldName = UA_JSONKEY_NAMESPACE;
        if(isNamespaceString) {
            entries[fieldCount].fieldPointer = &dst->namespaceUri;
            entries[fieldCount].function = (decodeJsonSignature) String_decodeJson;
        } else {
            entries[fieldCount].fieldPointer = &dst->nodeId.namespaceIndex;
            entries[fieldCount].function = (decodeJsonSignature) UInt16_decodeJson;
        }
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++; 
    }
    
    if(hasServerUri) {
        entries[fieldCount].fieldName = UA_JSONKEY_SERVERURI;
        entries[fieldCount].fieldPointer = &dst->serverIndex;
        entries[fieldCount].function = (decodeJsonSignature) UInt32_decodeJson;
        entries[fieldCount].found = false;
        entries[fieldCount].type = NULL;
        fieldCount++;  
    } else {
        dst->serverIndex = 0;
    }
    
    return decodeFields(ctx, parseCtx, entries, fieldCount, type);
}