/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *    Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
 *    Copyright 2014-2017 (c) Florian Palm
 *    Copyright 2015-2016 (c) Sten Grüner
 *    Copyright 2015-2016 (c) Chris Iatrou
 *    Copyright 2015-2016 (c) Oleksiy Vasylyev
 *    Copyright 2017 (c) Julian Grothoff
 *    Copyright 2016 (c) LEvertz
 *    Copyright 2016 (c) Lorenz Haas
 *    Copyright 2017 (c) frax2222
 *    Copyright 2017-2018 (c) Stefan Profanter, fortiss GmbH
 *    Copyright 2017 (c) Christian von Arnim
 *    Copyright 2017 (c) Henrik Norrman
 */

#include "ua_server_internal.h"
#include "ua_services.h"

#define UA_LOG_NODEID_WRAP(NODEID, LOG) {   \
    UA_String nodeIdStr = UA_STRING_NULL;   \
    UA_NodeId_toString(NODEID, &nodeIdStr); \
    LOG;                                    \
    UA_String_deleteMembers(&nodeIdStr);    \
}

/*********************/
/* Edit Node Context */
/*********************/

UA_StatusCode
UA_Server_getNodeContext(UA_Server *server, UA_NodeId nodeId,
                         void **nodeContext) {
    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &nodeId);
    if(!node)
        return UA_STATUSCODE_BADNODEIDUNKNOWN;
    *nodeContext = node->context;
    UA_Nodestore_releaseNode(server->nsCtx, node);
    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
setDeconstructedNode(UA_Server *server, UA_Session *session,
                     UA_Node *node, void *context) {
    node->constructed = false;
    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
setConstructedNodeContext(UA_Server *server, UA_Session *session,
                          UA_Node *node, void *context) {
    node->context = context;
    node->constructed = true;
    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
editNodeContext(UA_Server *server, UA_Session* session,
                UA_Node* node, void *context) {
    node->context = context;
    return UA_STATUSCODE_GOOD;
}

UA_StatusCode
UA_Server_setNodeContext(UA_Server *server, UA_NodeId nodeId,
                         void *nodeContext) {
    return UA_Server_editNode(server, &server->adminSession, &nodeId,
                              (UA_EditNodeCallback)editNodeContext, nodeContext);
}

/**********************/
/* Consistency Checks */
/**********************/

#define UA_PARENT_REFERENCES_COUNT 2

const UA_NodeId parentReferences[UA_PARENT_REFERENCES_COUNT] = {
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}},
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT}}
};

/* Check if the requested parent node exists, has the right node class and is
 * referenced with an allowed (hierarchical) reference type. For "type" nodes,
 * only hasSubType references are allowed. */
static UA_StatusCode
checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeClass,
                     const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId) {
    /* Objects do not need a parent (e.g. mandatory/optional modellingrules) */
    /* Also, there are some variables which do not have parents, e.g. EnumStrings, EnumValues */
    if((nodeClass == UA_NODECLASS_OBJECT || nodeClass == UA_NODECLASS_VARIABLE) &&
       UA_NodeId_isNull(parentNodeId) && UA_NodeId_isNull(referenceTypeId))
        return UA_STATUSCODE_GOOD;

    /* See if the parent exists */
    const UA_Node *parent = UA_Nodestore_getNode(server->nsCtx, parentNodeId);
    if(!parent) {
        UA_LOG_NODEID_WRAP(parentNodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Parent node %.*s not found",
                            (int)nodeIdStr.length, nodeIdStr.data));
        return UA_STATUSCODE_BADPARENTNODEIDINVALID;
    }

    UA_NodeClass parentNodeClass = parent->nodeClass;
    UA_Nodestore_releaseNode(server->nsCtx, parent);

    /* Check the referencetype exists */
    const UA_ReferenceTypeNode *referenceType = (const UA_ReferenceTypeNode*)
        UA_Nodestore_getNode(server->nsCtx, referenceTypeId);
    if(!referenceType) {
        UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: Reference type %.*s to the parent not found",
                           (int)nodeIdStr.length, nodeIdStr.data));
        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
    }

    /* Check if the referencetype is a reference type node */
    if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
        UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: Reference type %.*s to the parent is not a ReferenceTypeNode",
                           (int)nodeIdStr.length, nodeIdStr.data));
        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)referenceType);
        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
    }

    UA_Boolean referenceTypeIsAbstract = referenceType->isAbstract;
    UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)referenceType);
    /* Check that the reference type is not abstract */
    if(referenceTypeIsAbstract == true) {
        UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: Abstract reference type %.*s to the parent not allowed",
                           (int)nodeIdStr.length, nodeIdStr.data));
        return UA_STATUSCODE_BADREFERENCENOTALLOWED;
    }

    /* Check hassubtype relation for type nodes */
    if(nodeClass == UA_NODECLASS_DATATYPE ||
       nodeClass == UA_NODECLASS_VARIABLETYPE ||
       nodeClass == UA_NODECLASS_OBJECTTYPE ||
       nodeClass == UA_NODECLASS_REFERENCETYPE) {
        /* type needs hassubtype reference to the supertype */
        if(!UA_NodeId_equal(referenceTypeId, &subtypeId)) {
            UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Type nodes need to have a HasSubType "
                                "reference to the parent");
            return UA_STATUSCODE_BADREFERENCENOTALLOWED;
        }
        /* supertype needs to be of the same node type  */
        if(parentNodeClass != nodeClass) {
            UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Type nodes needs to be of the same node "
                                "type as their parent");
            return UA_STATUSCODE_BADPARENTNODEIDINVALID;
        }
        return UA_STATUSCODE_GOOD;
    }

    /* Test if the referencetype is hierarchical */
    if(!isNodeInTree(server->nsCtx, referenceTypeId,
                     &hierarchicalReferences, &subtypeId, 1)) {
        UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Reference type to the parent is not hierarchical");
        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
    }

    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
typeCheckVariableNode(UA_Server *server, UA_Session *session,
                      const UA_VariableNode *node,
                      const UA_VariableTypeNode *vt) {
    /* The value might come from a datasource, so we perform a
     * regular read. */
    UA_DataValue value;
    UA_DataValue_init(&value);
    UA_StatusCode retval = readValueAttribute(server, session, node, &value);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    UA_NodeId baseDataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);

    /* Check the datatype against the vt */
    /* If the node does not have any value and the dataType is BaseDataType,
     * then it's also fine. This is the default for empty nodes. */
    if(!compatibleDataType(server, &node->dataType, &vt->dataType, false) &&
       (value.hasValue || !UA_NodeId_equal(&node->dataType, &baseDataType))) {
        UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                              "AddNodes: The value of %.*s is incompatible with "
                              "the datatype of the VariableType",
                              (int)nodeIdStr.length, nodeIdStr.data));
        UA_DataValue_deleteMembers(&value);
        return UA_STATUSCODE_BADTYPEMISMATCH;
    }

    /* Check valueRank against array dimensions */
    if(!compatibleValueRankArrayDimensions(server, session, node->valueRank,
                                           node->arrayDimensionsSize)) {
        UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: The value rank of %.*s is incomatible "
                           "with its array dimensions", (int)nodeIdStr.length, nodeIdStr.data));
        UA_DataValue_deleteMembers(&value);
        return UA_STATUSCODE_BADTYPEMISMATCH;
    }

    /* Check valueRank against the vt */
    if(!compatibleValueRanks(node->valueRank, vt->valueRank)) {
        UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: The value rank of %.*s is incomatible "
                           "with the value rank of the VariableType",
                           (int)nodeIdStr.length, nodeIdStr.data));
        UA_DataValue_deleteMembers(&value);
        return UA_STATUSCODE_BADTYPEMISMATCH;
    }

    /* Check array dimensions against the vt */
    if(!compatibleArrayDimensions(vt->arrayDimensionsSize, vt->arrayDimensions,
                                  node->arrayDimensionsSize, node->arrayDimensions)) {
        UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: The array dimensions of %.*s are "
                           "incomatible with the array dimensions of the VariableType",
                           (int)nodeIdStr.length, nodeIdStr.data));
        UA_DataValue_deleteMembers(&value);
        return UA_STATUSCODE_BADTYPEMISMATCH;
    }

    /* Typecheck the value */
    if(value.hasValue && value.value.data) {
        /* If the type-check failed write the same value again. The
         * write-service tries to convert to the correct type... */
        if(!compatibleValue(server, session, &node->dataType, node->valueRank,
                            node->arrayDimensionsSize, node->arrayDimensions,
                            &value.value, NULL)) {
            retval = writeWithWriteValue(server, &node->nodeId, UA_ATTRIBUTEID_VALUE, &UA_TYPES[UA_TYPES_VARIANT], &value.value);
        }

        UA_DataValue_deleteMembers(&value);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                               "AddNodes: The value of of %.*s is incomatible with the "
                               "variable definition", (int)nodeIdStr.length, nodeIdStr.data));
        }
    }

    return retval;
}

/********************/
/* Instantiate Node */
/********************/

static const UA_NodeId baseDataVariableType =
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_BASEDATAVARIABLETYPE}};
static const UA_NodeId baseObjectType =
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_BASEOBJECTTYPE}};
static const UA_NodeId hasTypeDefinition =
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASTYPEDEFINITION}};

/* Use attributes from the variable type wherever required. Reload the node if
 * changes were made. */
static UA_StatusCode
useVariableTypeAttributes(UA_Server *server, UA_Session *session,
                          const UA_VariableNode **node_ptr,
                          const UA_VariableTypeNode *vt) {
    const UA_VariableNode *node = *node_ptr;
    UA_Boolean modified = false;

    /* If no value is set, see if the vt provides one and copy it. This needs to
     * be done before copying the datatype from the vt, as setting the datatype
     * triggers a typecheck. */
    UA_DataValue orig;
    UA_DataValue_init(&orig);
    UA_StatusCode retval = readValueAttribute(server, session, node, &orig);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    if(orig.value.type) {
        /* A value is present */
        UA_DataValue_deleteMembers(&orig);
    } else {
        UA_LOG_DEBUG_SESSION(&server->config.logger, session,
                             "AddNodes: No value given; Copy the value "
                             "from the TypeDefinition");
        UA_WriteValue v;
        UA_WriteValue_init(&v);
        retval = readValueAttribute(server, session, (const UA_VariableNode*)vt, &v.value);
        if(retval == UA_STATUSCODE_GOOD && v.value.hasValue) {
            v.nodeId = node->nodeId;
            v.attributeId = UA_ATTRIBUTEID_VALUE;
            retval = writeWithSession(server, session, &v);
            modified = true;
        }
        UA_DataValue_deleteMembers(&v.value);
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
    }

    /* If no datatype is given, use the datatype of the vt */
    if(UA_NodeId_isNull(&node->dataType)) {
        UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: "
                            "No datatype given; Copy the datatype attribute "
                            "from the TypeDefinition");
        UA_WriteValue v;
        UA_WriteValue_init(&v);
        v.nodeId = node->nodeId;
        v.attributeId = UA_ATTRIBUTEID_DATATYPE;
        v.value.hasValue = true;
        UA_Variant_setScalar(&v.value.value, (void*)(uintptr_t)&vt->dataType,
                             &UA_TYPES[UA_TYPES_NODEID]);
        retval = writeWithSession(server, session, &v);
        modified = true;
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
    }

    /* Use the ArrayDimensions of the vt */
    if(node->arrayDimensionsSize == 0 && vt->arrayDimensionsSize > 0) {
        UA_WriteValue v;
        UA_WriteValue_init(&v);
        v.nodeId = node->nodeId;
        v.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
        v.value.hasValue = true;
        UA_Variant_setArray(&v.value.value, vt->arrayDimensions,
                            vt->arrayDimensionsSize, &UA_TYPES[UA_TYPES_UINT32]);
        retval = writeWithSession(server, session, &v);
        modified = true;
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
    }

    /* If the node was modified, update the pointer to the new version */
    if(modified) {
        const UA_VariableNode *updated = (const UA_VariableNode*)
            UA_Nodestore_getNode(server->nsCtx, &node->nodeId);

        if(!updated)
            return UA_STATUSCODE_BADINTERNALERROR;

        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)node);
        *node_ptr = updated;
    }

    return UA_STATUSCODE_GOOD;
}

/* Search for an instance of "browseName" in node searchInstance. Used during
 * copyChildNodes to find overwritable/mergable nodes. Does not touch
 * outInstanceNodeId if no child is found. */
static UA_StatusCode
findChildByBrowsename(UA_Server *server, UA_Session *session,
                      const UA_NodeId *searchInstance,
                      const UA_QualifiedName *browseName,
                      UA_NodeId *outInstanceNodeId) {
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = *searchInstance;
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES);
    bd.includeSubtypes = true;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
    bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD;
    bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME;

    UA_BrowseResult br;
    UA_BrowseResult_init(&br);
    UA_UInt32 maxrefs = 0;
    Operation_Browse(server, session, &maxrefs, &bd, &br);
    if(br.statusCode != UA_STATUSCODE_GOOD)
        return br.statusCode;

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    for(size_t i = 0; i < br.referencesSize; ++i) {
        UA_ReferenceDescription *rd = &br.references[i];
        if(rd->browseName.namespaceIndex == browseName->namespaceIndex &&
           UA_String_equal(&rd->browseName.name, &browseName->name)) {
            retval = UA_NodeId_copy(&rd->nodeId.nodeId, outInstanceNodeId);
            break;
        }
    }

    UA_BrowseResult_deleteMembers(&br);
    return retval;
}

static const UA_NodeId mandatoryId =
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_MODELLINGRULE_MANDATORY}};
static const UA_NodeId hasModellingRuleId =
    {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASMODELLINGRULE}};

static UA_Boolean
isMandatoryChild(UA_Server *server, UA_Session *session,
                 const UA_NodeId *childNodeId) {
    /* Get the child */
    const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, childNodeId);
    if(!child)
        return false;

    /* Look for the reference making the child mandatory */
    for(size_t i = 0; i < child->referencesSize; ++i) {
        UA_NodeReferenceKind *refs = &child->references[i];
        if(!UA_NodeId_equal(&hasModellingRuleId, &refs->referenceTypeId))
            continue;
        if(refs->isInverse)
            continue;
        for(size_t j = 0; j < refs->targetIdsSize; ++j) {
            if(UA_NodeId_equal(&mandatoryId, &refs->targetIds[j].nodeId)) {
                UA_Nodestore_releaseNode(server->nsCtx, child);
                return true;
            }
        }
    }

    UA_Nodestore_releaseNode(server->nsCtx, child);
    return false;
}

static UA_StatusCode
copyAllChildren(UA_Server *server, UA_Session *session,
                const UA_NodeId *source, const UA_NodeId *destination);

static UA_StatusCode
recursiveTypeCheckAddChildren(UA_Server *server, UA_Session *session,
                              const UA_Node **node, const UA_Node *type);

static void
Operation_addReference(UA_Server *server, UA_Session *session, void *context,
                       const UA_AddReferencesItem *item, UA_StatusCode *retval);

static UA_StatusCode
copyChild(UA_Server *server, UA_Session *session, const UA_NodeId *destinationNodeId,
          const UA_ReferenceDescription *rd) {
    /* Is there an existing child with the browsename? */
    UA_NodeId existingChild = UA_NODEID_NULL;
    UA_StatusCode retval = findChildByBrowsename(server, session, destinationNodeId,
                                                 &rd->browseName, &existingChild);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    /* Have a child with that browseName. Deep-copy missing members. */
    if(!UA_NodeId_isNull(&existingChild)) {
        if(rd->nodeClass == UA_NODECLASS_VARIABLE ||
           rd->nodeClass == UA_NODECLASS_OBJECT)
            retval = copyAllChildren(server, session, &rd->nodeId.nodeId, &existingChild);
        UA_NodeId_deleteMembers(&existingChild);
        return retval;
    }

    /* Is the child mandatory? If not, ask callback whether child should be instantiated.
     * If not, skip. */
    if(!isMandatoryChild(server, session, &rd->nodeId.nodeId)) {
        if(!server->config.nodeLifecycle.createOptionalChild)
            return UA_STATUSCODE_GOOD;

        UA_UNLOCK(server->serviceMutex);
        retval = server->config.nodeLifecycle.createOptionalChild(server,
                                                                 &session->sessionId,
                                                                 session->sessionHandle,
                                                                 &rd->nodeId.nodeId,
                                                                 destinationNodeId,
                                                                 &rd->referenceTypeId);
        UA_LOCK(server->serviceMutex);
        if(retval == UA_FALSE) {
            return UA_STATUSCODE_GOOD;
        }
    }

    /* Child is a method -> create a reference */
    if(rd->nodeClass == UA_NODECLASS_METHOD) {
        UA_AddReferencesItem newItem;
        UA_AddReferencesItem_init(&newItem);
        newItem.sourceNodeId = *destinationNodeId;
        newItem.referenceTypeId = rd->referenceTypeId;
        newItem.isForward = true;
        newItem.targetNodeId = rd->nodeId;
        newItem.targetNodeClass = UA_NODECLASS_METHOD;
        Operation_addReference(server, session, NULL, &newItem, &retval);
        return retval;
    }

    /* Child is a variable or object */
    if(rd->nodeClass == UA_NODECLASS_VARIABLE ||
       rd->nodeClass == UA_NODECLASS_OBJECT) {
        /* Make a copy of the node */
        UA_Node *node;
        retval = UA_Nodestore_getNodeCopy(server->nsCtx, &rd->nodeId.nodeId, &node);
        if(retval != UA_STATUSCODE_GOOD)
            return retval;

        /* Remove the context of the copied node */
        node->context = NULL;
        node->constructed = false;

        /* Reset the NodeId (random numeric id will be assigned in the nodestore) */
        UA_NodeId_deleteMembers(&node->nodeId);
        node->nodeId.namespaceIndex = destinationNodeId->namespaceIndex;

        if (server->config.nodeLifecycle.generateChildNodeId) {
            UA_UNLOCK(server->serviceMutex);
            retval = server->config.nodeLifecycle.generateChildNodeId(server,
                                                                      &session->sessionId, session->sessionHandle,
                                                                      &rd->nodeId.nodeId,
                                                                      destinationNodeId,
                                                                      &rd->referenceTypeId,
                                                                      &node->nodeId);
            UA_LOCK(server->serviceMutex);
            if(retval != UA_STATUSCODE_GOOD) {
                UA_Nodestore_deleteNode(server->nsCtx, node);
                return retval;
            }
        }


        /* Remove references, they are re-created from scratch in addnode_finish */
        /* TODO: Be more clever in removing references that are re-added during
         * addnode_finish. That way, we can call addnode_finish also on children that were
         * manually added by the user during addnode_begin and addnode_finish. */
        /* For now we keep all the modelling rule references and delete all others */
        UA_NodeId modellingRuleReferenceId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE);
        UA_Node_deleteReferencesSubset(node, 1, &modellingRuleReferenceId);

        /* Add the node to the nodestore */
        UA_NodeId newNodeId;
        retval = UA_Nodestore_insertNode(server->nsCtx, node, &newNodeId);
        if(retval != UA_STATUSCODE_GOOD)
            return retval;

        /* Add the node references */
        retval = AddNode_addRefs(server, session, &newNodeId, destinationNodeId,
                                 &rd->referenceTypeId, &rd->typeDefinition.nodeId);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_Nodestore_removeNode(server->nsCtx, &newNodeId);
            return retval;
        }

        /* For the new child, recursively copy the members of the original. No
         * typechecking is performed here. Assuming that the original is
         * consistent. */
        retval = copyAllChildren(server, session, &rd->nodeId.nodeId, &newNodeId);
    }

    return retval;
}

/* Copy any children of Node sourceNodeId to another node destinationNodeId. */
static UA_StatusCode
copyAllChildren(UA_Server *server, UA_Session *session,
                const UA_NodeId *source, const UA_NodeId *destination) {
    /* Browse to get all children of the source */
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = *source;
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES);
    bd.includeSubtypes = true;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
    bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD;
    bd.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS |
        UA_BROWSERESULTMASK_BROWSENAME | UA_BROWSERESULTMASK_TYPEDEFINITION;

    UA_BrowseResult br;
    UA_BrowseResult_init(&br);
    UA_UInt32 maxrefs = 0;
    Operation_Browse(server, session, &maxrefs, &bd, &br);
    if(br.statusCode != UA_STATUSCODE_GOOD)
        return br.statusCode;

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    for(size_t i = 0; i < br.referencesSize; ++i) {
        UA_ReferenceDescription *rd = &br.references[i];
        retval = copyChild(server, session, destination, rd);
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
    }

    UA_BrowseResult_deleteMembers(&br);
    return retval;
}

static UA_StatusCode
addTypeChildren(UA_Server *server, UA_Session *session,
                const UA_Node *node, const UA_Node *type) {
    /* Get the hierarchy of the type and all its supertypes */
    UA_NodeId *hierarchy = NULL;
    size_t hierarchySize = 0;
    UA_StatusCode retval = getParentTypeAndInterfaceHierarchy(server, &type->nodeId,
                                                              &hierarchy, &hierarchySize);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;
    UA_assert(hierarchySize < 1000);

    /* Copy members of the type and supertypes (and instantiate them) */
    for(size_t i = 0; i < hierarchySize; ++i) {
        retval = copyAllChildren(server, session, &hierarchy[i], &node->nodeId);
        if(retval != UA_STATUSCODE_GOOD)
            break;
    }

    UA_Array_delete(hierarchy, hierarchySize, &UA_TYPES[UA_TYPES_NODEID]);
    return retval;
}

static UA_StatusCode
addRef(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
       const UA_NodeId *referenceTypeId, const UA_NodeId *parentNodeId,
       UA_Boolean forward) {
    UA_AddReferencesItem ref_item;
    UA_AddReferencesItem_init(&ref_item);
    ref_item.sourceNodeId = *nodeId;
    ref_item.referenceTypeId = *referenceTypeId;
    ref_item.isForward = forward;
    ref_item.targetNodeId.nodeId = *parentNodeId;

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    Operation_addReference(server, session, NULL, &ref_item, &retval);
    return retval;
}

/************/
/* Add Node */
/************/

static const UA_NodeId hasSubtype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}};

UA_StatusCode
AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
                const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
                const UA_NodeId *typeDefinitionId) {
    /* Get the node */
    const UA_Node *type = NULL;
    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId);
    if(!node)
        return UA_STATUSCODE_BADNODEIDUNKNOWN;

    /* Use the typeDefinition as parent for type-nodes */
    if(node->nodeClass == UA_NODECLASS_VARIABLETYPE ||
       node->nodeClass == UA_NODECLASS_OBJECTTYPE ||
       node->nodeClass == UA_NODECLASS_REFERENCETYPE ||
       node->nodeClass == UA_NODECLASS_DATATYPE) {
        if(UA_NodeId_equal(referenceTypeId, &UA_NODEID_NULL))
            referenceTypeId = &hasSubtype;
        const UA_Node *parentNode = UA_Nodestore_getNode(server->nsCtx, parentNodeId);
        if(parentNode) {
            if(parentNode->nodeClass == node->nodeClass)
                typeDefinitionId = parentNodeId;
            UA_Nodestore_releaseNode(server->nsCtx, parentNode);
        }
    }

    /* Check parent reference. Objects may have no parent. */
    UA_StatusCode retval = checkParentReference(server, session, node->nodeClass,
                                                parentNodeId, referenceTypeId);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: The parent reference for %.*s is invalid "
                            "with status code %s",
                            (int)nodeIdStr.length, nodeIdStr.data,
                            UA_StatusCode_name(retval)));
        goto cleanup;
    }

    /* Replace empty typeDefinition with the most permissive default */
    if((node->nodeClass == UA_NODECLASS_VARIABLE ||
        node->nodeClass == UA_NODECLASS_OBJECT) &&
       UA_NodeId_isNull(typeDefinitionId)) {
        UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: No TypeDefinition for %.*s; Use the default "
                            "TypeDefinition for the Variable/Object",
                            (int)nodeIdStr.length, nodeIdStr.data));
        if(node->nodeClass == UA_NODECLASS_VARIABLE)
            typeDefinitionId = &baseDataVariableType;
        else
            typeDefinitionId = &baseObjectType;
    }

    /* Get the node type. There must be a typedefinition for variables, objects
     * and type-nodes. See the above checks. */
    if(!UA_NodeId_isNull(typeDefinitionId)) {
        /* Get the type node */
        type = UA_Nodestore_getNode(server->nsCtx, typeDefinitionId);
        if(!type) {
            UA_LOG_NODEID_WRAP(typeDefinitionId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Node type %.*s not found",
                                (int)nodeIdStr.length, nodeIdStr.data));
            retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
            goto cleanup;
        }

        UA_Boolean typeOk = false;
        switch(node->nodeClass) {
            case UA_NODECLASS_DATATYPE:
                typeOk = type->nodeClass == UA_NODECLASS_DATATYPE;
                break;
            case UA_NODECLASS_METHOD:
                typeOk = type->nodeClass == UA_NODECLASS_METHOD;
                break;
            case UA_NODECLASS_OBJECT:
                typeOk = type->nodeClass == UA_NODECLASS_OBJECTTYPE;
                break;
            case UA_NODECLASS_OBJECTTYPE:
                typeOk = type->nodeClass == UA_NODECLASS_OBJECTTYPE;
                break;
            case UA_NODECLASS_REFERENCETYPE:
                typeOk = type->nodeClass == UA_NODECLASS_REFERENCETYPE;
                break;
            case UA_NODECLASS_VARIABLE:
                typeOk = type->nodeClass == UA_NODECLASS_VARIABLETYPE;
                break;
            case UA_NODECLASS_VARIABLETYPE:
                typeOk = type->nodeClass == UA_NODECLASS_VARIABLETYPE;
                break;
            case UA_NODECLASS_VIEW:
                typeOk = type->nodeClass == UA_NODECLASS_VIEW;
                break;
            default:
                typeOk = false;
        }
        if(!typeOk) {
            UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Type for %.*s does not match node class",
                                (int)nodeIdStr.length, nodeIdStr.data));
            retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
            goto cleanup;
        }

        /* See if the type has the correct node class. For type-nodes, we know
         * that type has the same nodeClass from checkParentReference. */
        if(node->nodeClass == UA_NODECLASS_VARIABLE) {
            if(((const UA_VariableTypeNode*)type)->isAbstract) {
                /* Get subtypes of the parent reference types */
                UA_NodeId *parentTypeHierarchy = NULL;
                size_t parentTypeHierarchySize = 0;
                retval |= referenceSubtypes(server, &parentReferences[0],
                                            &parentTypeHierarchySize, &parentTypeHierarchy);
                retval |= referenceSubtypes(server, &parentReferences[1],
                                            &parentTypeHierarchySize, &parentTypeHierarchy);
                if(retval != UA_STATUSCODE_GOOD) {
                    UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize,
                                    &UA_TYPES[UA_TYPES_NODEID]);
                    goto cleanup;
                }

                /* Abstract variable is allowed if parent is a children of a
                 * base data variable. An abstract variable may be part of an
                 * object type which again is below BaseObjectType */
                const UA_NodeId variableTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
                const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE);
                if(!isNodeInTree(server->nsCtx, parentNodeId, &variableTypes,
                                 parentTypeHierarchy, parentTypeHierarchySize) &&
                   !isNodeInTree(server->nsCtx, parentNodeId, &objectTypes,
                                 parentTypeHierarchy, parentTypeHierarchySize)) {
                    UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                        "AddNodes: Type of variable node %.*s must "
                                        "be VariableType and not cannot be abstract",
                                        (int)nodeIdStr.length, nodeIdStr.data));
                    retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
                }
                UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize,
                                &UA_TYPES[UA_TYPES_NODEID]);
                if(retval != UA_STATUSCODE_GOOD)
                    goto cleanup;
            }
        }

        if(node->nodeClass == UA_NODECLASS_OBJECT) {
            if(((const UA_ObjectTypeNode*)type)->isAbstract) {
                /* Get subtypes of the parent reference types */
                UA_NodeId *parentTypeHierarchy = NULL;
                size_t parentTypeHierarchySize = 0;
                retval |= referenceSubtypes(server, &parentReferences[0],
                                            &parentTypeHierarchySize, &parentTypeHierarchy);
                retval |= referenceSubtypes(server, &parentReferences[1],
                                            &parentTypeHierarchySize, &parentTypeHierarchy);
                if(retval != UA_STATUSCODE_GOOD) {
                    UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize,
                                    &UA_TYPES[UA_TYPES_NODEID]);
                    goto cleanup;
                }

                /* Object node created of an abstract ObjectType. Only allowed
                 * if within BaseObjectType folder or if it's an event (subType of BaseEventType) */
                const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE);
                UA_Boolean isInBaseObjectType = isNodeInTree(server->nsCtx, parentNodeId, &objectTypes,
                                                             parentTypeHierarchy, parentTypeHierarchySize);

                const UA_NodeId eventTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEEVENTTYPE);
                UA_Boolean isInBaseEventType = isNodeInTree(server->nsCtx, &type->nodeId, &eventTypes, &hasSubtype, 1);

                if(!isInBaseObjectType && !(isInBaseEventType && UA_NodeId_isNull(parentNodeId))) {
                    UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                        "AddNodes: Type of object node %.*s must "
                                        "be ObjectType and not be abstract",
                                        (int)nodeIdStr.length, nodeIdStr.data));
                    retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
                }
                UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize,
                                &UA_TYPES[UA_TYPES_NODEID]);
                if(retval != UA_STATUSCODE_GOOD)
                    goto cleanup;
            }
        }
    }

    /* Add reference to the parent */
    if(!UA_NodeId_isNull(parentNodeId)) {
        if(UA_NodeId_isNull(referenceTypeId)) {
            UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Reference to parent of %.*s cannot be null",
                                (int)nodeIdStr.length, nodeIdStr.data));
            retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
            goto cleanup;
        }

        retval = addRef(server, session, &node->nodeId, referenceTypeId, parentNodeId, false);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Adding reference to parent of %.*s failed",
                                (int)nodeIdStr.length, nodeIdStr.data));
            goto cleanup;
        }
    }

    /* Add a hasTypeDefinition reference */
    if(node->nodeClass == UA_NODECLASS_VARIABLE ||
       node->nodeClass == UA_NODECLASS_OBJECT) {
        UA_assert(type != NULL); /* see above */
        retval = addRef(server, session, &node->nodeId, &hasTypeDefinition, &type->nodeId, true);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                "AddNodes: Adding a reference to the type "
                                "definition of %.*s failed with error code %s",
                                (int)nodeIdStr.length, nodeIdStr.data,
                                UA_StatusCode_name(retval)));
        }
    }

 cleanup:
    UA_Nodestore_releaseNode(server->nsCtx, node);
    if(type)
        UA_Nodestore_releaseNode(server->nsCtx, type);
    return retval;
}

/* Create the node and add it to the nodestore. But don't typecheck and add
 * references so far */
UA_StatusCode
AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext,
            const UA_AddNodesItem *item, UA_NodeId *outNewNodeId) {
    /* Do not check access for server */
    if(session != &server->adminSession && server->config.accessControl.allowAddNode) {
        UA_UNLOCK(server->serviceMutex)
        if (!server->config.accessControl.allowAddNode(server, &server->config.accessControl,
                                                       &session->sessionId, session->sessionHandle, item)) {
            UA_LOCK(server->serviceMutex);
            return UA_STATUSCODE_BADUSERACCESSDENIED;
        }
        UA_LOCK(server->serviceMutex);
    }

    /* Check the namespaceindex */
    if(item->requestedNewNodeId.nodeId.namespaceIndex >= server->namespacesSize) {
        UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Namespace invalid");
        return UA_STATUSCODE_BADNODEIDINVALID;
    }

    if(item->nodeAttributes.encoding != UA_EXTENSIONOBJECT_DECODED &&
       item->nodeAttributes.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) {
        UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Node attributes invalid");
        return UA_STATUSCODE_BADINTERNALERROR;
    }

    /* Create a node */
    UA_Node *node = UA_Nodestore_newNode(server->nsCtx, item->nodeClass);
    if(!node) {
        UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Node could not create a node "
                            "in the nodestore");
        return UA_STATUSCODE_BADOUTOFMEMORY;
    }

    /* Fill the node attributes */
    node->context = nodeContext;
    UA_StatusCode retval = UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId);
    if(retval != UA_STATUSCODE_GOOD)
        goto create_error;

    retval = UA_QualifiedName_copy(&item->browseName, &node->browseName);
    if(retval != UA_STATUSCODE_GOOD)
        goto create_error;

    retval = UA_Node_setAttributes(node, item->nodeAttributes.content.decoded.data,
                                   item->nodeAttributes.content.decoded.type);
    if(retval != UA_STATUSCODE_GOOD)
        goto create_error;

    /* Add the node to the nodestore */
    retval = UA_Nodestore_insertNode(server->nsCtx, node, outNewNodeId);
    if(retval != UA_STATUSCODE_GOOD)
        UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Node could not add the new node "
                            "to the nodestore with error code %s",
                            UA_StatusCode_name(retval));
    return retval;

create_error:
    UA_LOG_INFO_SESSION(&server->config.logger, session,
                        "AddNodes: Node could not create a node "
                        "with error code %s", UA_StatusCode_name(retval));
    UA_Nodestore_deleteNode(server->nsCtx, node);
    return retval;
}

/* Prepare the node, then add it to the nodestore */
static UA_StatusCode
Operation_addNode_begin(UA_Server *server, UA_Session *session, void *nodeContext,
                        const UA_AddNodesItem *item, const UA_NodeId *parentNodeId,
                        const UA_NodeId *referenceTypeId, UA_NodeId *outNewNodeId) {
    /* Create a temporary NodeId if none is returned */
    UA_NodeId newId;
    if(!outNewNodeId) {
        UA_NodeId_init(&newId);
        outNewNodeId = &newId;
    }

    /* Create the node and add it to the nodestore */
    UA_StatusCode retval = AddNode_raw(server, session, nodeContext, item, outNewNodeId);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    /* Typecheck and add references to parent and type definition */
    retval = AddNode_addRefs(server, session, outNewNodeId, parentNodeId,
                             referenceTypeId, &item->typeDefinition.nodeId);
    if(retval != UA_STATUSCODE_GOOD)
        deleteNode(server, *outNewNodeId, true);

    if(outNewNodeId == &newId)
        UA_NodeId_deleteMembers(&newId);
    return retval;
}

static UA_StatusCode
recursiveTypeCheckAddChildren(UA_Server *server, UA_Session *session,
                              const UA_Node **nodeptr, const UA_Node *type) {
    UA_assert(type != NULL);
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    const UA_Node *node = *nodeptr;

    /* Use attributes from the type. The value and value constraints are the
     * same for the variable and variabletype attribute structs. */
    if(node->nodeClass == UA_NODECLASS_VARIABLE ||
       node->nodeClass == UA_NODECLASS_VARIABLETYPE) {
        retval = useVariableTypeAttributes(server, session, (const UA_VariableNode**)nodeptr,
                                           (const UA_VariableTypeNode*)type);
        node = *nodeptr; /* If the node was replaced */
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                               "AddNodes: Using attributes for %.*s from the variable type "
                               "failed with error code %s", (int)nodeIdStr.length,
                               nodeIdStr.data, UA_StatusCode_name(retval)));
            return retval;
        }

        /* Check NodeClass for 'hasSubtype'. UA_NODECLASS_VARIABLE not allowed to have subtype */
        if((node->nodeClass == UA_NODECLASS_VARIABLE) && (UA_NodeId_equal(
                &node->references->referenceTypeId, &hasSubtype))) {
            UA_LOG_INFO_SESSION(&server->config.logger, session,
                                            "AddNodes: VariableType not allowed to have HasSubType");
            return UA_STATUSCODE_BADREFERENCENOTALLOWED;
        }

        /* Check if all attributes hold the constraints of the type now. The initial
         * attributes must type-check. The constructor might change the attributes
         * again. Then, the changes are type-checked by the normal write service. */
        retval = typeCheckVariableNode(server, session, (const UA_VariableNode*)node,
                                       (const UA_VariableTypeNode*)type);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                               "AddNodes: Type-checking the variable node %.*s "
                               "failed with error code %s", (int)nodeIdStr.length,
                               nodeIdStr.data, UA_StatusCode_name(retval)));
            return retval;
        }
    }

    /* Add (mandatory) child nodes from the type definition */
    if(node->nodeClass == UA_NODECLASS_VARIABLE ||
       node->nodeClass == UA_NODECLASS_OBJECT) {
        retval = addTypeChildren(server, session, node, type);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                               "AddNodes: Adding child nodes of  %.*s failed with error code %s",
                               (int)nodeIdStr.length, nodeIdStr.data, UA_StatusCode_name(retval)));
        }
    }

    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
findDefaultInstanceBrowseNameNode(UA_Server *server,
                    UA_NodeId startingNode, UA_NodeId *foundId){

    UA_NodeId_init(foundId);
    UA_RelativePathElement rpe;
    UA_RelativePathElement_init(&rpe);
    rpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY);
    rpe.isInverse = false;
    rpe.includeSubtypes = false;
    rpe.targetName = UA_QUALIFIEDNAME(0, "DefaultInstanceBrowseName");
    UA_BrowsePath bp;
    UA_BrowsePath_init(&bp);
    bp.startingNode = startingNode;
    bp.relativePath.elementsSize = 1;
    bp.relativePath.elements = &rpe;
    UA_BrowsePathResult bpr =
            translateBrowsePathToNodeIds(server, &bp);
    UA_StatusCode retval = bpr.statusCode;
    if (retval == UA_STATUSCODE_GOOD &&
        bpr.targetsSize > 0) {
        retval = UA_NodeId_copy(&bpr.targets[0].targetId.nodeId, foundId);
    }
    UA_BrowsePathResult_deleteMembers(&bpr);
    return retval;
}

/* Check if we got a valid browse name for the new node.
 * For object nodes the BrowseName may only be null if the parent type has a
 * 'DefaultInstanceBrowseName' property.
 * */
static UA_StatusCode
checkValidBrowseName(UA_Server *server, UA_Session *session,
                     const UA_Node *node, const UA_Node *type) {

    UA_assert(type != NULL);
    UA_StatusCode retval = UA_STATUSCODE_GOOD;

    if(node->nodeClass != UA_NODECLASS_OBJECT) {
        /* nodes other than Objects must have a browseName */
        if (UA_QualifiedName_isNull(&node->browseName))
            return UA_STATUSCODE_BADBROWSENAMEINVALID;
        return UA_STATUSCODE_GOOD;
    }

    /* If the object node already has a browse name we are done here. */
    if(!UA_QualifiedName_isNull(&node->browseName))
        return UA_STATUSCODE_GOOD;

    /* at this point we have an object with an empty browse name.
     * Check the type node if it has a DefaultInstanceBrowseName property
     */

    UA_NodeId defaultBrowseNameNode;
    retval = findDefaultInstanceBrowseNameNode(server, type->nodeId, &defaultBrowseNameNode);
    if (retval != UA_STATUSCODE_GOOD) {
        if (retval == UA_STATUSCODE_BADNOMATCH)
            /* the DefaultBrowseName property is not found, return the corresponding status code */
            return UA_STATUSCODE_BADBROWSENAMEINVALID;
        return retval;
    }

    UA_Variant defaultBrowseName;
    retval = readWithReadValue(server, &defaultBrowseNameNode, UA_ATTRIBUTEID_VALUE, &defaultBrowseName);
    if (retval != UA_STATUSCODE_GOOD)
        return retval;

    UA_QualifiedName *defaultValue = (UA_QualifiedName *) defaultBrowseName.data;
    retval = writeWithWriteValue(server, &node->nodeId, UA_ATTRIBUTEID_BROWSENAME, &UA_TYPES[UA_TYPES_QUALIFIEDNAME], defaultValue);
    UA_Variant_clear(&defaultBrowseName);

    return retval;
}

/* Construct children first */
static UA_StatusCode
recursiveCallConstructors(UA_Server *server, UA_Session *session,
                          const UA_Node *node, const UA_Node *type) {
    if(node->constructed)
        return UA_STATUSCODE_GOOD;
    
    /* Construct the children */
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = node->nodeId;
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES);
    bd.includeSubtypes = true;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;

    UA_BrowseResult br;
    UA_BrowseResult_init(&br);
    UA_UInt32 maxrefs = 0;
    Operation_Browse(server, session, &maxrefs, &bd, &br);
    if(br.statusCode != UA_STATUSCODE_GOOD)
        return br.statusCode;

    /* Call the constructor for every unconstructed node */
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    for(size_t i = 0; i < br.referencesSize; ++i) {
        UA_ReferenceDescription *rd = &br.references[i];
        const UA_Node *target = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId);
        if(!target)
            continue;
        if(target->constructed) {
            UA_Nodestore_releaseNode(server->nsCtx, target);
            continue;
        }

        const UA_Node *targetType = NULL;
        if(node->nodeClass == UA_NODECLASS_VARIABLE ||
           node->nodeClass == UA_NODECLASS_OBJECT) {
            targetType = getNodeType(server, target);
            if(!targetType) {
                UA_Nodestore_releaseNode(server->nsCtx, target);
                retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
                break;
            }
        }
        retval = recursiveCallConstructors(server, session, target, targetType);
        UA_Nodestore_releaseNode(server->nsCtx, target);
        if(targetType)
            UA_Nodestore_releaseNode(server->nsCtx, targetType);
        if(retval != UA_STATUSCODE_GOOD)
            break;
    }

    UA_BrowseResult_deleteMembers(&br);

    /* If a child could not be constructed or the node is already constructed */
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    /* Get the node type constructor */
    const UA_NodeTypeLifecycle *lifecycle = NULL;
    if(type && node->nodeClass == UA_NODECLASS_OBJECT) {
        const UA_ObjectTypeNode *ot = (const UA_ObjectTypeNode*)type;
        lifecycle = &ot->lifecycle;
    } else if(type && node->nodeClass == UA_NODECLASS_VARIABLE) {
        const UA_VariableTypeNode *vt = (const UA_VariableTypeNode*)type;
        lifecycle = &vt->lifecycle;
    }

    /* Call the global constructor */
    void *context = node->context;
    if(server->config.nodeLifecycle.constructor) {
        UA_UNLOCK(server->serviceMutex);
        retval = server->config.nodeLifecycle.constructor(server, &session->sessionId,
                                                          session->sessionHandle,
                                                          &node->nodeId, &context);
        UA_LOCK(server->serviceMutex);
    }

    /* Call the type constructor */
    if(retval == UA_STATUSCODE_GOOD && lifecycle && lifecycle->constructor) {
        UA_UNLOCK(server->serviceMutex)
        retval = lifecycle->constructor(server, &session->sessionId,
                                        session->sessionHandle, &type->nodeId,
                                        type->context, &node->nodeId, &context);
        UA_LOCK(server->serviceMutex);
    }

    if(retval != UA_STATUSCODE_GOOD)
        goto fail1;

    /* Set the context *and* mark the node as constructed */
    if(retval == UA_STATUSCODE_GOOD)
        retval = UA_Server_editNode(server, &server->adminSession, &node->nodeId,
                                    (UA_EditNodeCallback)setConstructedNodeContext,
                                    context);

    /* All good, return */
    if(retval == UA_STATUSCODE_GOOD)
        return retval;

    /* Fail. Call the destructors. */
    if(lifecycle && lifecycle->destructor) {
        UA_UNLOCK(server->serviceMutex);
        lifecycle->destructor(server, &session->sessionId,
                              session->sessionHandle, &type->nodeId,
                              type->context, &node->nodeId, &context);
        UA_LOCK(server->serviceMutex)
    }


 fail1:
    if(server->config.nodeLifecycle.destructor) {
        UA_UNLOCK(server->serviceMutex);
        server->config.nodeLifecycle.destructor(server, &session->sessionId,
                                                session->sessionHandle,
                                                &node->nodeId, context);
        UA_LOCK(server->serviceMutex);
    }

    return retval;
}

static void
recursiveDeconstructNode(UA_Server *server, UA_Session *session,
                         size_t hierarchicalReferencesSize,
                         UA_ExpandedNodeId *hierarchicalReferences,
                         const UA_Node *node);

static void
recursiveDeleteNode(UA_Server *server, UA_Session *session,
                    size_t hierarchicalReferencesSize,
                    UA_ExpandedNodeId *hierarchicalReferences,
                    const UA_Node *node, UA_Boolean removeTargetRefs);

/* Children, references, type-checking, constructors. */
UA_StatusCode
AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId) {
    UA_StatusCode retval = UA_STATUSCODE_GOOD;

    /* Get the node */
    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId);
    if(!node)
        return UA_STATUSCODE_BADNODEIDUNKNOWN;

    const UA_Node *type = NULL;

    /* Instantiate variables and objects */
    if(node->nodeClass == UA_NODECLASS_VARIABLE ||
       node->nodeClass == UA_NODECLASS_VARIABLETYPE ||
       node->nodeClass == UA_NODECLASS_OBJECT) {
        /* Get the type node */
        type = getNodeType(server, node);
        if(!type) {
            if(server->bootstrapNS0)
                goto constructor;
            UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                               "AddNodes: Node type for %.*s not found",
                               (int)nodeIdStr.length, nodeIdStr.data));
            retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
            goto cleanup;
        }

        retval = checkValidBrowseName(server, session, node, type);
        if(retval != UA_STATUSCODE_GOOD)
            goto cleanup;

        retval = recursiveTypeCheckAddChildren(server, session, &node, type);
        if(retval != UA_STATUSCODE_GOOD)
            goto cleanup;
    }

    /* Call the constructor(s) */
 constructor:
    retval = recursiveCallConstructors(server, session, node, type);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                           "AddNodes: Calling the node constructor(s) of %.*s failed "
                           "with status code %s", (int)nodeIdStr.length,
                           nodeIdStr.data, UA_StatusCode_name(retval)));
    }

 cleanup:
    if(type)
        UA_Nodestore_releaseNode(server->nsCtx, type);
    if(retval != UA_STATUSCODE_GOOD) {
        recursiveDeconstructNode(server, session, 0, NULL, node);
        recursiveDeleteNode(server, session, 0, NULL, node, true);
    }
    UA_Nodestore_releaseNode(server->nsCtx, node);
    return retval;
}

static void
Operation_addNode(UA_Server *server, UA_Session *session, void *nodeContext,
                  const UA_AddNodesItem *item, UA_AddNodesResult *result) {
    result->statusCode =
        Operation_addNode_begin(server, session, nodeContext, item, &item->parentNodeId.nodeId,
                                &item->referenceTypeId, &result->addedNodeId);
    if(result->statusCode != UA_STATUSCODE_GOOD)
        return;

    /* AddNodes_finish */
    result->statusCode = AddNode_finish(server, session, &result->addedNodeId);

    /* If finishing failed, the node was deleted */
    if(result->statusCode != UA_STATUSCODE_GOOD)
        UA_NodeId_deleteMembers(&result->addedNodeId);
}

void
Service_AddNodes(UA_Server *server, UA_Session *session,
                 const UA_AddNodesRequest *request,
                 UA_AddNodesResponse *response) {
    UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing AddNodesRequest");
    UA_LOCK_ASSERT(server->serviceMutex, 1);

    if(server->config.maxNodesPerNodeManagement != 0 &&
       request->nodesToAddSize > server->config.maxNodesPerNodeManagement) {
        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
        return;
    }

    response->responseHeader.serviceResult =
        UA_Server_processServiceOperations(server, session,
                                           (UA_ServiceOperation)Operation_addNode, NULL,
                                           &request->nodesToAddSize, &UA_TYPES[UA_TYPES_ADDNODESITEM],
                                           &response->resultsSize, &UA_TYPES[UA_TYPES_ADDNODESRESULT]);
}

UA_StatusCode
addNode(UA_Server *server, const UA_NodeClass nodeClass,
        const UA_NodeId *requestedNewNodeId,
        const UA_NodeId *parentNodeId,
        const UA_NodeId *referenceTypeId,
        const UA_QualifiedName browseName,
        const UA_NodeId *typeDefinition,
        const UA_NodeAttributes *attr,
        const UA_DataType *attributeType,
        void *nodeContext, UA_NodeId *outNewNodeId) {
    /* Create the AddNodesItem */
    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    item.nodeClass = nodeClass;
    item.requestedNewNodeId.nodeId = *requestedNewNodeId;
    item.browseName = browseName;
    item.parentNodeId.nodeId = *parentNodeId;
    item.referenceTypeId = *referenceTypeId;
    item.typeDefinition.nodeId = *typeDefinition;
    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
    item.nodeAttributes.content.decoded.type = attributeType;
    item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)attr;

    /* Call the normal addnodes service */
    UA_AddNodesResult result;
    UA_AddNodesResult_init(&result);
    Operation_addNode(server, &server->adminSession, nodeContext, &item, &result);
    if(outNewNodeId)
        *outNewNodeId = result.addedNodeId;
    else
        UA_NodeId_deleteMembers(&result.addedNodeId);
    return result.statusCode;
}

UA_StatusCode
__UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
                    const UA_NodeId *requestedNewNodeId,
                    const UA_NodeId *parentNodeId,
                    const UA_NodeId *referenceTypeId,
                    const UA_QualifiedName browseName,
                    const UA_NodeId *typeDefinition,
                    const UA_NodeAttributes *attr,
                    const UA_DataType *attributeType,
                    void *nodeContext, UA_NodeId *outNewNodeId) {
    UA_LOCK(server->serviceMutex)
    UA_StatusCode  reval = addNode(server, nodeClass, requestedNewNodeId, parentNodeId,
            referenceTypeId, browseName, typeDefinition, attr, attributeType, nodeContext, outNewNodeId);
    UA_UNLOCK(server->serviceMutex);
    return reval;
}

UA_StatusCode
UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
                        const UA_NodeId requestedNewNodeId,
                        const UA_NodeId parentNodeId,
                        const UA_NodeId referenceTypeId,
                        const UA_QualifiedName browseName,
                        const UA_NodeId typeDefinition,
                        const void *attr, const UA_DataType *attributeType,
                        void *nodeContext, UA_NodeId *outNewNodeId) {
    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    item.nodeClass = nodeClass;
    item.requestedNewNodeId.nodeId = requestedNewNodeId;
    item.browseName = browseName;
    item.typeDefinition.nodeId = typeDefinition;
    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
    item.nodeAttributes.content.decoded.type = attributeType;
    item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)attr;

    UA_LOCK(server->serviceMutex);
    UA_StatusCode retval = Operation_addNode_begin(server, &server->adminSession, nodeContext, &item,
                                   &parentNodeId, &referenceTypeId, outNewNodeId);
    UA_UNLOCK(server->serviceMutex);
    return retval;
}

UA_StatusCode
UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId) {
    UA_LOCK(server->serviceMutex);
    UA_StatusCode retval = AddNode_finish(server, &server->adminSession, &nodeId);
    UA_UNLOCK(server->serviceMutex);
    return retval;
}

/****************/
/* Delete Nodes */
/****************/

static void
Operation_deleteReference(UA_Server *server, UA_Session *session, void *context,
                          const UA_DeleteReferencesItem *item, UA_StatusCode *retval);

/* Remove references to this node (in the other nodes) */
static void
removeIncomingReferences(UA_Server *server, UA_Session *session,
                         const UA_Node *node) {
    UA_DeleteReferencesItem item;
    UA_DeleteReferencesItem_init(&item);
    item.targetNodeId.nodeId = node->nodeId;
    item.deleteBidirectional = false;
    UA_StatusCode dummy;
    for(size_t i = 0; i < node->referencesSize; ++i) {
        UA_NodeReferenceKind *refs = &node->references[i];
        item.isForward = refs->isInverse;
        item.referenceTypeId = refs->referenceTypeId;
        for(size_t j = 0; j < refs->targetIdsSize; ++j) {
            item.sourceNodeId = refs->targetIds[j].nodeId;
            Operation_deleteReference(server, session, NULL, &item, &dummy);
        }
    }
}

/* A node can only be deleted if it has at most one incoming hierarchical
 * reference. If hierarchicalReferences is NULL, always remove. */
static UA_Boolean
multipleHierarchies(size_t hierarchicalRefsSize, UA_ExpandedNodeId *hierarchicalRefs,
                    const UA_Node *node) {
    if(!hierarchicalRefs)
        return false;

    size_t incomingRefs = 0;
    for(size_t i = 0; i < node->referencesSize; i++) {
        const UA_NodeReferenceKind *k = &node->references[i];
        if(!k->isInverse)
            continue;

        UA_Boolean hierarchical = false;
        for(size_t j = 0; j < hierarchicalRefsSize; j++) {
            if(UA_NodeId_equal(&hierarchicalRefs[j].nodeId,
                               &k->referenceTypeId)) {
                hierarchical = true;
                break;
            }
        }
        if(!hierarchical)
            continue;

        incomingRefs += k->targetIdsSize;
        if(incomingRefs > 1)
            return true;
    }

    return false;
}

/* Recursively call the destructors of this node and all child nodes.
 * Deconstructs the parent before its children. */
static void
recursiveDeconstructNode(UA_Server *server, UA_Session *session,
                         size_t hierarchicalRefsSize,
                         UA_ExpandedNodeId *hierarchicalRefs,
                         const UA_Node *node) {
    /* Was the constructor called for the node? */
    if(!node->constructed)
        return;

    /* Call the type-level destructor */
    void *context = node->context; /* No longer needed after this function */
    if(node->nodeClass == UA_NODECLASS_OBJECT ||
       node->nodeClass == UA_NODECLASS_VARIABLE) {
        const UA_Node *type = getNodeType(server, node);
        if(type) {
            const UA_NodeTypeLifecycle *lifecycle;
            if(node->nodeClass == UA_NODECLASS_OBJECT)
                lifecycle = &((const UA_ObjectTypeNode*)type)->lifecycle;
            else
                lifecycle = &((const UA_VariableTypeNode*)type)->lifecycle;
            if(lifecycle->destructor)
                lifecycle->destructor(server,
                                      &session->sessionId, session->sessionHandle,
                                      &type->nodeId, type->context,
                                      &node->nodeId, &context);
            UA_Nodestore_releaseNode(server->nsCtx, type);
        }
    }

    /* Call the global destructor */
    if(server->config.nodeLifecycle.destructor)
        server->config.nodeLifecycle.destructor(server, &session->sessionId,
                                                session->sessionHandle,
                                                &node->nodeId, context);

    /* Set the constructed flag to false */
    UA_Server_editNode(server, &server->adminSession, &node->nodeId,
                       (UA_EditNodeCallback)setDeconstructedNode, context);

    /* Browse to get all children of the node */
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = node->nodeId;
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES);
    bd.includeSubtypes = true;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;

    UA_BrowseResult br;
    UA_BrowseResult_init(&br);
    UA_UInt32 maxrefs = 0;
    Operation_Browse(server, session, &maxrefs, &bd, &br);
    if(br.statusCode != UA_STATUSCODE_GOOD)
        return;

    /* Deconstruct every child node */
    for(size_t i = 0; i < br.referencesSize; ++i) {
        UA_ReferenceDescription *rd = &br.references[i];
        const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId);
        if(!child)
            continue;
        /* Only delete child nodes that have no other parent */
        if(!multipleHierarchies(hierarchicalRefsSize, hierarchicalRefs, child))
            recursiveDeconstructNode(server, session, hierarchicalRefsSize,
                                     hierarchicalRefs, child);
        UA_Nodestore_releaseNode(server->nsCtx, child);
    }

    UA_BrowseResult_deleteMembers(&br);
}

static void
recursiveDeleteNode(UA_Server *server, UA_Session *session,
                    size_t hierarchicalRefsSize,
                    UA_ExpandedNodeId *hierarchicalRefs,
                    const UA_Node *node, UA_Boolean removeTargetRefs) {
    /* Browse to get all children of the node */
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = node->nodeId;
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES);
    bd.includeSubtypes = true;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;

    UA_BrowseResult br;
    UA_BrowseResult_init(&br);
    UA_UInt32 maxrefs = 0;
    Operation_Browse(server, session, &maxrefs, &bd, &br);
    if(br.statusCode != UA_STATUSCODE_GOOD)
        return;

    /* Remove every child */
    for(size_t i = 0; i < br.referencesSize; ++i) {
        UA_ReferenceDescription *rd = &br.references[i];
        /* Check for self-reference to avoid endless loop */
        if(UA_NodeId_equal(&node->nodeId, &rd->nodeId.nodeId))
            continue;
        const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId);
        if(!child)
            continue;
        /* Only delete child nodes that have no other parent */
        if(!multipleHierarchies(hierarchicalRefsSize, hierarchicalRefs, child))
            recursiveDeleteNode(server, session, hierarchicalRefsSize,
                                hierarchicalRefs, child, true);
        UA_Nodestore_releaseNode(server->nsCtx, child);
    }

    UA_BrowseResult_deleteMembers(&br);

    if(removeTargetRefs)
        removeIncomingReferences(server, session, node);

    UA_Nodestore_removeNode(server->nsCtx, &node->nodeId);
}

static void
deleteNodeOperation(UA_Server *server, UA_Session *session, void *context,
                    const UA_DeleteNodesItem *item, UA_StatusCode *result) {
    /* Do not check access for server */
    if(session != &server->adminSession && server->config.accessControl.allowDeleteNode) {
        UA_UNLOCK(server->serviceMutex);
        if ( !server->config.accessControl.allowDeleteNode(server, &server->config.accessControl,
                &session->sessionId, session->sessionHandle, item)) {
            UA_LOCK(server->serviceMutex);
            *result = UA_STATUSCODE_BADUSERACCESSDENIED;
            return;
        }
        UA_LOCK(server->serviceMutex);
    }

    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &item->nodeId);
    if(!node) {
        *result = UA_STATUSCODE_BADNODEIDUNKNOWN;
        return;
    }

    if(UA_Node_hasSubTypeOrInstances(node)) {
        UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "Delete Nodes: Cannot delete a type node "
                            "with active instances or subtypes");
        UA_Nodestore_releaseNode(server->nsCtx, node);
        *result = UA_STATUSCODE_BADINTERNALERROR;
        return;
    }

    /* TODO: Check if the information model consistency is violated */
    /* TODO: Check if the node is a mandatory child of a parent */

    /* A node can be referenced with hierarchical references from several
     * parents in the information model. (But not in a circular way.) The
     * hierarchical references are checked to see if a node can be deleted.
     * Getting the type hierarchy can fail in case of low RAM. In that case the
     * nodes are always deleted. */
    UA_ExpandedNodeId *hierarchicalRefs = NULL;
    size_t hierarchicalRefsSize = 0;
    UA_NodeId hr = UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES);
    browseRecursive(server, 1, &hr, 1, &subtypeId, UA_BROWSEDIRECTION_FORWARD, true,
                    &hierarchicalRefsSize, &hierarchicalRefs);
    if(!hierarchicalRefs) {
        UA_LOG_WARNING_SESSION(&server->config.logger, session,
                               "Delete Nodes: Cannot test for hierarchical "
                               "references. Deleting the node and all child nodes.");
    }
    recursiveDeconstructNode(server, session, hierarchicalRefsSize, hierarchicalRefs, node);
    recursiveDeleteNode(server, session, hierarchicalRefsSize, hierarchicalRefs, node,
                        item->deleteTargetReferences);
    UA_Array_delete(hierarchicalRefs, hierarchicalRefsSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
    
    UA_Nodestore_releaseNode(server->nsCtx, node);
}

void Service_DeleteNodes(UA_Server *server, UA_Session *session,
                         const UA_DeleteNodesRequest *request,
                         UA_DeleteNodesResponse *response) {
    UA_LOG_DEBUG_SESSION(&server->config.logger, session,
                         "Processing DeleteNodesRequest");
    UA_LOCK_ASSERT(server->serviceMutex, 1);

    if(server->config.maxNodesPerNodeManagement != 0 &&
       request->nodesToDeleteSize > server->config.maxNodesPerNodeManagement) {
        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
        return;
    }

    response->responseHeader.serviceResult =
        UA_Server_processServiceOperations(server, session,
                                           (UA_ServiceOperation)deleteNodeOperation,
                                           NULL, &request->nodesToDeleteSize,
                                           &UA_TYPES[UA_TYPES_DELETENODESITEM],
                                           &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
}

UA_StatusCode
UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId,
                     UA_Boolean deleteReferences) {
    UA_LOCK(server->serviceMutex)
    UA_StatusCode retval = deleteNode(server, nodeId, deleteReferences);
    UA_UNLOCK(server->serviceMutex);
    return retval;
}

UA_StatusCode
deleteNode(UA_Server *server, const UA_NodeId nodeId,
                     UA_Boolean deleteReferences) {
    UA_DeleteNodesItem item;
    item.deleteTargetReferences = deleteReferences;
    item.nodeId = nodeId;
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    deleteNodeOperation(server, &server->adminSession, NULL, &item, &retval);
    return retval;
}

/******************/
/* Add References */
/******************/

static UA_StatusCode
addOneWayReference(UA_Server *server, UA_Session *session,
             UA_Node *node, const UA_AddReferencesItem *item) {
    return UA_Node_addReference(node, item);
}

static UA_StatusCode
deleteOneWayReference(UA_Server *server, UA_Session *session, UA_Node *node,
                      const UA_DeleteReferencesItem *item) {
    return UA_Node_deleteReference(node, item);
}

static void
Operation_addReference(UA_Server *server, UA_Session *session, void *context,
                       const UA_AddReferencesItem *item, UA_StatusCode *retval) {
    /* Do not check access for server */
    if(session != &server->adminSession && server->config.accessControl.allowAddReference) {
        UA_UNLOCK(server->serviceMutex);
        if (!server->config.accessControl.
                allowAddReference(server, &server->config.accessControl,
                                  &session->sessionId, session->sessionHandle, item)) {
            UA_LOCK(server->serviceMutex);
            *retval = UA_STATUSCODE_BADUSERACCESSDENIED;
            return;
        }
        UA_LOCK(server->serviceMutex);
    }

    /* Currently no expandednodeids are allowed */
    if(item->targetServerUri.length > 0) {
        *retval = UA_STATUSCODE_BADNOTIMPLEMENTED;
        return;
    }

    /* Add the first direction */
    *retval = UA_Server_editNode(server, session, &item->sourceNodeId,
                                 (UA_EditNodeCallback)addOneWayReference,
                                 /* cast away const because callback uses const anyway */
                                 (UA_AddReferencesItem *)(uintptr_t)item);
    UA_Boolean firstExisted = false;
    if(*retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) {
        *retval = UA_STATUSCODE_GOOD;
        firstExisted = true;
    } else if(*retval != UA_STATUSCODE_GOOD)
        return;

    /* Add the second direction */
    UA_AddReferencesItem secondItem;
    UA_AddReferencesItem_init(&secondItem);
    secondItem.sourceNodeId = item->targetNodeId.nodeId;
    secondItem.referenceTypeId = item->referenceTypeId;
    secondItem.isForward = !item->isForward;
    secondItem.targetNodeId.nodeId = item->sourceNodeId;
    /* keep default secondItem.targetNodeClass = UA_NODECLASS_UNSPECIFIED */
    *retval = UA_Server_editNode(server, session, &secondItem.sourceNodeId,
                                 (UA_EditNodeCallback)addOneWayReference, &secondItem);

    /* remove reference if the second direction failed */
    UA_Boolean secondExisted = false;
    if(*retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) {
        *retval = UA_STATUSCODE_GOOD;
        secondExisted = true;
    } else if(*retval != UA_STATUSCODE_GOOD && !firstExisted) {
        UA_DeleteReferencesItem deleteItem;
        deleteItem.sourceNodeId = item->sourceNodeId;
        deleteItem.referenceTypeId = item->referenceTypeId;
        deleteItem.isForward = item->isForward;
        deleteItem.targetNodeId = item->targetNodeId;
        deleteItem.deleteBidirectional = false;
        /* ignore returned status code */
        UA_Server_editNode(server, session, &item->sourceNodeId,
                           (UA_EditNodeCallback)deleteOneWayReference, &deleteItem);
    }

    /* Calculate common duplicate reference not allowed result and set bad result
     * if BOTH directions already existed */
    if(firstExisted && secondExisted)
        *retval = UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED;
}

void Service_AddReferences(UA_Server *server, UA_Session *session,
                           const UA_AddReferencesRequest *request,
                           UA_AddReferencesResponse *response) {
    UA_LOG_DEBUG_SESSION(&server->config.logger, session,
                         "Processing AddReferencesRequest");
    UA_LOCK_ASSERT(server->serviceMutex, 1);

    if(server->config.maxNodesPerNodeManagement != 0 &&
       request->referencesToAddSize > server->config.maxNodesPerNodeManagement) {
        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
        return;
    }

    response->responseHeader.serviceResult =
        UA_Server_processServiceOperations(server, session,
                                           (UA_ServiceOperation)Operation_addReference,
                                           NULL, &request->referencesToAddSize,
                                           &UA_TYPES[UA_TYPES_ADDREFERENCESITEM],
                                           &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
}

UA_StatusCode
UA_Server_addReference(UA_Server *server, const UA_NodeId sourceId,
                       const UA_NodeId refTypeId,
                       const UA_ExpandedNodeId targetId,
                       UA_Boolean isForward) {
    UA_AddReferencesItem item;
    UA_AddReferencesItem_init(&item);
    item.sourceNodeId = sourceId;
    item.referenceTypeId = refTypeId;
    item.isForward = isForward;
    item.targetNodeId = targetId;

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    UA_LOCK(server->serviceMutex);
    Operation_addReference(server, &server->adminSession, NULL, &item, &retval);
    UA_UNLOCK(server->serviceMutex)
    return retval;
}

/*********************/
/* Delete References */
/*********************/

static void
Operation_deleteReference(UA_Server *server, UA_Session *session, void *context,
                          const UA_DeleteReferencesItem *item, UA_StatusCode *retval) {
    /* Do not check access for server */
    if(session != &server->adminSession && server->config.accessControl.allowDeleteReference) {
        UA_UNLOCK(server->serviceMutex);
        if (!server->config.accessControl.
                allowDeleteReference(server, &server->config.accessControl,
                                     &session->sessionId, session->sessionHandle, item)){
            UA_LOCK(server->serviceMutex);
            *retval = UA_STATUSCODE_BADUSERACCESSDENIED;
            return;
        }
        UA_LOCK(server->serviceMutex)
    }

    // TODO: Check consistency constraints, remove the references.
    *retval = UA_Server_editNode(server, session, &item->sourceNodeId,
                                 (UA_EditNodeCallback)deleteOneWayReference,
                                 /* cast away const qualifier because callback uses it anyway */
                                 (UA_DeleteReferencesItem *)(uintptr_t)item);
    if(*retval != UA_STATUSCODE_GOOD)
        return;

    if(!item->deleteBidirectional || item->targetNodeId.serverIndex != 0)
        return;

    UA_DeleteReferencesItem secondItem;
    UA_DeleteReferencesItem_init(&secondItem);
    secondItem.isForward = !item->isForward;
    secondItem.sourceNodeId = item->targetNodeId.nodeId;
    secondItem.targetNodeId.nodeId = item->sourceNodeId;
    secondItem.referenceTypeId = item->referenceTypeId;
    *retval = UA_Server_editNode(server, session, &secondItem.sourceNodeId,
                                 (UA_EditNodeCallback)deleteOneWayReference,
                                 &secondItem);
}

void
Service_DeleteReferences(UA_Server *server, UA_Session *session,
                         const UA_DeleteReferencesRequest *request,
                         UA_DeleteReferencesResponse *response) {
    UA_LOG_DEBUG_SESSION(&server->config.logger, session,
                         "Processing DeleteReferencesRequest");
    UA_LOCK_ASSERT(server->serviceMutex, 1);

    if(server->config.maxNodesPerNodeManagement != 0 &&
       request->referencesToDeleteSize > server->config.maxNodesPerNodeManagement) {
        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
        return;
    }

    response->responseHeader.serviceResult =
        UA_Server_processServiceOperations(server, session,
                                           (UA_ServiceOperation)Operation_deleteReference,
                                           NULL, &request->referencesToDeleteSize,
                                           &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM],
                                           &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
}

UA_StatusCode
UA_Server_deleteReference(UA_Server *server, const UA_NodeId sourceNodeId,
                          const UA_NodeId referenceTypeId, UA_Boolean isForward,
                          const UA_ExpandedNodeId targetNodeId,
                          UA_Boolean deleteBidirectional) {
    UA_DeleteReferencesItem item;
    item.sourceNodeId = sourceNodeId;
    item.referenceTypeId = referenceTypeId;
    item.isForward = isForward;
    item.targetNodeId = targetNodeId;
    item.deleteBidirectional = deleteBidirectional;

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    UA_LOCK(server->serviceMutex);
    Operation_deleteReference(server, &server->adminSession, NULL, &item, &retval);
    UA_UNLOCK(server->serviceMutex);
    return retval;
}

/**********************/
/* Set Value Callback */
/**********************/

static UA_StatusCode
setValueCallback(UA_Server *server, UA_Session *session,
                 UA_VariableNode *node, const UA_ValueCallback *callback) {
    if(node->nodeClass != UA_NODECLASS_VARIABLE)
        return UA_STATUSCODE_BADNODECLASSINVALID;
    node->value.data.callback = *callback;
    return UA_STATUSCODE_GOOD;
}



UA_StatusCode
UA_Server_setVariableNode_valueCallback(UA_Server *server,
                                        const UA_NodeId nodeId,
                                        const UA_ValueCallback callback) {
    UA_LOCK(server->serviceMutex);
    UA_StatusCode retval = UA_Server_editNode(server, &server->adminSession, &nodeId,
                                              (UA_EditNodeCallback)setValueCallback,
                                              /* cast away const because callback uses const anyway */
                                              (UA_ValueCallback *)(uintptr_t) &callback);
    UA_UNLOCK(server->serviceMutex);
    return retval;
}

/***************************************************/
/* Special Handling of Variables with Data Sources */
/***************************************************/

UA_StatusCode
UA_Server_addDataSourceVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
                                    const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
                                    const UA_VariableAttributes attr, const UA_DataSource dataSource,
                                    void *nodeContext, UA_NodeId *outNewNodeId) {
    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    item.nodeClass = UA_NODECLASS_VARIABLE;
    item.requestedNewNodeId.nodeId = requestedNewNodeId;
    item.browseName = browseName;
    UA_ExpandedNodeId typeDefinitionId;
    UA_ExpandedNodeId_init(&typeDefinitionId);
    typeDefinitionId.nodeId = typeDefinition;
    item.typeDefinition = typeDefinitionId;
    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
    item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)&attr;
    item.nodeAttributes.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES];
    UA_NodeId newNodeId;
    if(!outNewNodeId) {
        newNodeId = UA_NODEID_NULL;
        outNewNodeId = &newNodeId;
    }

    UA_LOCK(server->serviceMutex);
    /* Create the node and add it to the nodestore */
    UA_StatusCode retval = AddNode_raw(server, &server->adminSession, nodeContext,
                                       &item, outNewNodeId);
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    /* Set the data source */
    retval = setVariableNode_dataSource(server, *outNewNodeId, dataSource);
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    /* Typecheck and add references to parent and type definition */
    retval = AddNode_addRefs(server, &server->adminSession, outNewNodeId, &parentNodeId,
                             &referenceTypeId, &typeDefinition);
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    /* Call the constructors */
    retval = AddNode_finish(server, &server->adminSession, outNewNodeId);

 cleanup:
    UA_UNLOCK(server->serviceMutex);
    if(outNewNodeId == &newNodeId)
        UA_NodeId_deleteMembers(&newNodeId);

    return retval;
}

static UA_StatusCode
setDataSource(UA_Server *server, UA_Session *session,
              UA_VariableNode* node, const UA_DataSource *dataSource) {
    if(node->nodeClass != UA_NODECLASS_VARIABLE)
        return UA_STATUSCODE_BADNODECLASSINVALID;
    if(node->valueSource == UA_VALUESOURCE_DATA)
        UA_DataValue_deleteMembers(&node->value.data.value);
    node->value.dataSource = *dataSource;
    node->valueSource = UA_VALUESOURCE_DATASOURCE;
    return UA_STATUSCODE_GOOD;
}

UA_StatusCode
setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
                                     const UA_DataSource dataSource) {
    return UA_Server_editNode(server, &server->adminSession, &nodeId,
                              (UA_EditNodeCallback)setDataSource,
                              /* casting away const because callback casts it back anyway */
                              (UA_DataSource *) (uintptr_t)&dataSource);
}

UA_StatusCode
UA_Server_setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
                                     const UA_DataSource dataSource) {
    UA_LOCK(server->serviceMutex);
    UA_StatusCode retval = setVariableNode_dataSource(server, nodeId, dataSource);
    UA_UNLOCK(server->serviceMutex);
    return retval;
}

/************************************/
/* Special Handling of Method Nodes */
/************************************/

#ifdef UA_ENABLE_METHODCALLS

static const UA_NodeId hasproperty = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASPROPERTY}};
static const UA_NodeId propertytype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_PROPERTYTYPE}};

static UA_StatusCode
UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId, UA_MethodCallback method,
                                 const size_t inputArgumentsSize, const UA_Argument *inputArguments,
                                 const UA_NodeId inputArgumentsRequestedNewNodeId,
                                 UA_NodeId *inputArgumentsOutNewNodeId,
                                 const size_t outputArgumentsSize, const UA_Argument *outputArguments,
                                 const UA_NodeId outputArgumentsRequestedNewNodeId,
                                 UA_NodeId *outputArgumentsOutNewNodeId) {
    /* Browse to see which argument nodes exist */
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = nodeId;
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY);
    bd.includeSubtypes = false;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
    bd.nodeClassMask = UA_NODECLASS_VARIABLE;
    bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME;

    UA_BrowseResult br;
    UA_BrowseResult_init(&br);
    UA_UInt32 maxrefs = 0;
    Operation_Browse(server, &server->adminSession, &maxrefs, &bd, &br);

    UA_StatusCode retval = br.statusCode;
    if(retval != UA_STATUSCODE_GOOD) {
        deleteNode(server, nodeId, true);
        UA_BrowseResult_deleteMembers(&br);
        return retval;
    }

    /* Filter out the argument nodes */
    UA_NodeId inputArgsId = UA_NODEID_NULL;
    UA_NodeId outputArgsId = UA_NODEID_NULL;
    const UA_QualifiedName inputArgsName = UA_QUALIFIEDNAME(0, "InputArguments");
    const UA_QualifiedName outputArgsName = UA_QUALIFIEDNAME(0, "OutputArguments");
    for(size_t i = 0; i < br.referencesSize; i++) {
        UA_ReferenceDescription *rd = &br.references[i];
        if(rd->browseName.namespaceIndex == 0 &&
           UA_String_equal(&rd->browseName.name, &inputArgsName.name))
            inputArgsId = rd->nodeId.nodeId;
        else if(rd->browseName.namespaceIndex == 0 &&
                UA_String_equal(&rd->browseName.name, &outputArgsName.name))
            outputArgsId = rd->nodeId.nodeId;
    }

    /* Add the Input Arguments VariableNode */
    if(inputArgumentsSize > 0 && UA_NodeId_isNull(&inputArgsId)) {
        UA_VariableAttributes attr = UA_VariableAttributes_default;
        char *name = "InputArguments";
        attr.displayName = UA_LOCALIZEDTEXT("", name);
        attr.dataType = UA_TYPES[UA_TYPES_ARGUMENT].typeId;
        attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
        UA_UInt32 inputArgsSize32 = (UA_UInt32)inputArgumentsSize;
        attr.arrayDimensions = &inputArgsSize32;
        attr.arrayDimensionsSize = 1;
        UA_Variant_setArray(&attr.value, (void *)(uintptr_t)inputArguments,
                            inputArgumentsSize, &UA_TYPES[UA_TYPES_ARGUMENT]);
        retval = addNode(server, UA_NODECLASS_VARIABLE, &inputArgumentsRequestedNewNodeId,
                         &nodeId, &hasproperty, UA_QUALIFIEDNAME(0, name),
                         &propertytype, (const UA_NodeAttributes*)&attr,
                         &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
                         NULL, &inputArgsId);
        if(retval != UA_STATUSCODE_GOOD)
            goto error;
    }

    /* Add the Output Arguments VariableNode */
    if(outputArgumentsSize > 0 && UA_NodeId_isNull(&outputArgsId)) {
        UA_VariableAttributes attr = UA_VariableAttributes_default;
        char *name = "OutputArguments";
        attr.displayName = UA_LOCALIZEDTEXT("", name);
        attr.dataType = UA_TYPES[UA_TYPES_ARGUMENT].typeId;
        attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
        UA_UInt32 outputArgsSize32 = (UA_UInt32)outputArgumentsSize;
        attr.arrayDimensions = &outputArgsSize32;
        attr.arrayDimensionsSize = 1;
        UA_Variant_setArray(&attr.value, (void *)(uintptr_t)outputArguments,
                            outputArgumentsSize, &UA_TYPES[UA_TYPES_ARGUMENT]);
        retval = addNode(server, UA_NODECLASS_VARIABLE, &outputArgumentsRequestedNewNodeId,
                         &nodeId, &hasproperty, UA_QUALIFIEDNAME(0, name),
                         &propertytype, (const UA_NodeAttributes*)&attr,
                         &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
                         NULL, &outputArgsId);
        if(retval != UA_STATUSCODE_GOOD)
            goto error;
    }

    retval = setMethodNode_callback(server, nodeId, method);
    if(retval != UA_STATUSCODE_GOOD)
        goto error;

    /* Call finish to add the parent reference */
    retval = AddNode_finish(server, &server->adminSession, &nodeId);
    if(retval != UA_STATUSCODE_GOOD)
        goto error;

    if(inputArgumentsOutNewNodeId != NULL) {
        UA_NodeId_copy(&inputArgsId, inputArgumentsOutNewNodeId);
    }
    if(outputArgumentsOutNewNodeId != NULL) {
        UA_NodeId_copy(&outputArgsId, outputArgumentsOutNewNodeId);
    }
    UA_BrowseResult_deleteMembers(&br);
    return retval;

error:
    deleteNode(server, nodeId, true);
    deleteNode(server, inputArgsId, true);
    deleteNode(server, outputArgsId, true);
    UA_BrowseResult_deleteMembers(&br);

    return retval;
}

UA_StatusCode
UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
                               UA_MethodCallback method,
                               size_t inputArgumentsSize, const UA_Argument* inputArguments,
                               size_t outputArgumentsSize, const UA_Argument* outputArguments) {
    UA_LOCK(server->serviceMutex)
    UA_StatusCode retval = UA_Server_addMethodNodeEx_finish(server, nodeId, method,
                                            inputArgumentsSize, inputArguments, UA_NODEID_NULL, NULL,
                                            outputArgumentsSize, outputArguments, UA_NODEID_NULL, NULL);
    UA_UNLOCK(server->serviceMutex)
    return retval;
}

UA_StatusCode
UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId,
                          const UA_NodeId parentNodeId,
                          const UA_NodeId referenceTypeId,
                          const UA_QualifiedName browseName,
                          const UA_MethodAttributes attr, UA_MethodCallback method,
                          size_t inputArgumentsSize, const UA_Argument *inputArguments,
                          const UA_NodeId inputArgumentsRequestedNewNodeId,
                          UA_NodeId *inputArgumentsOutNewNodeId,
                          size_t outputArgumentsSize, const UA_Argument *outputArguments,
                          const UA_NodeId outputArgumentsRequestedNewNodeId,
                          UA_NodeId *outputArgumentsOutNewNodeId,
                          void *nodeContext, UA_NodeId *outNewNodeId) {
    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    item.nodeClass = UA_NODECLASS_METHOD;
    item.requestedNewNodeId.nodeId = requestedNewNodeId;
    item.browseName = browseName;
    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
    item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)&attr;
    item.nodeAttributes.content.decoded.type = &UA_TYPES[UA_TYPES_METHODATTRIBUTES];

    UA_NodeId newId;
    if(!outNewNodeId) {
        UA_NodeId_init(&newId);
        outNewNodeId = &newId;
    }
    UA_LOCK(server->serviceMutex);
    UA_StatusCode retval = Operation_addNode_begin(server, &server->adminSession,
                                                   nodeContext, &item, &parentNodeId,
                                                   &referenceTypeId, outNewNodeId);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_UNLOCK(server->serviceMutex);
        return retval;
    }

    retval = UA_Server_addMethodNodeEx_finish(server, *outNewNodeId, method,
                                              inputArgumentsSize, inputArguments,
                                              inputArgumentsRequestedNewNodeId,
                                              inputArgumentsOutNewNodeId,
                                              outputArgumentsSize, outputArguments,
                                              outputArgumentsRequestedNewNodeId,
                                              outputArgumentsOutNewNodeId);
    UA_UNLOCK(server->serviceMutex);
    if(outNewNodeId == &newId)
        UA_NodeId_deleteMembers(&newId);
    return retval;
}

static UA_StatusCode
editMethodCallback(UA_Server *server, UA_Session* session,
                   UA_Node* node, void* handle) {
    if(node->nodeClass != UA_NODECLASS_METHOD)
        return UA_STATUSCODE_BADNODECLASSINVALID;
    UA_MethodNode *mnode = (UA_MethodNode*) node;
    mnode->method = (UA_MethodCallback)(uintptr_t)handle;
    return UA_STATUSCODE_GOOD;
}

UA_StatusCode
setMethodNode_callback(UA_Server *server,
                                 const UA_NodeId methodNodeId,
                                 UA_MethodCallback methodCallback) {
    return UA_Server_editNode(server, &server->adminSession, &methodNodeId,
                                              (UA_EditNodeCallback)editMethodCallback,
                                              (void*)(uintptr_t)methodCallback);
}

UA_StatusCode
UA_Server_setMethodNode_callback(UA_Server *server,
                                 const UA_NodeId methodNodeId,
                                 UA_MethodCallback methodCallback) {
    UA_LOCK(server->serviceMutex);
    UA_StatusCode retVal = setMethodNode_callback(server, methodNodeId, methodCallback);
    UA_UNLOCK(server->serviceMutex);
    return retVal;
}

#endif

/************************/
/* Lifecycle Management */
/************************/

static UA_StatusCode
setNodeTypeLifecycle(UA_Server *server, UA_Session *session,
                     UA_Node* node, UA_NodeTypeLifecycle *lifecycle) {
    if(node->nodeClass == UA_NODECLASS_OBJECTTYPE) {
        UA_ObjectTypeNode *ot = (UA_ObjectTypeNode*)node;
        ot->lifecycle = *lifecycle;
        return UA_STATUSCODE_GOOD;
    }

    if(node->nodeClass == UA_NODECLASS_VARIABLETYPE) {
        UA_VariableTypeNode *vt = (UA_VariableTypeNode*)node;
        vt->lifecycle = *lifecycle;
        return UA_STATUSCODE_GOOD;
    }

    return UA_STATUSCODE_BADNODECLASSINVALID;
}

UA_StatusCode
UA_Server_setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId,
                               UA_NodeTypeLifecycle lifecycle) {
    return UA_Server_editNode(server, &server->adminSession, &nodeId,
                              (UA_EditNodeCallback)setNodeTypeLifecycle,
                              &lifecycle);
}
