GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode)
{
#ifndef GPAC_DISABLE_VRML
	u32 j;
#endif
#ifdef GPAC_HAS_QJS
	Bool detach=0;
#endif
	GF_SceneGraph *pSG;

	if (!pNode) return GF_OK;
	pSG = pNode->sgprivate->scenegraph;

	if (parentNode) {
		GF_ParentList *nlist = pNode->sgprivate->parents;
		if (nlist) {
			GF_ParentList *prev = NULL;
			while (nlist) {
				if (nlist->node != parentNode) {
					prev = nlist;
					nlist = nlist->next;
					continue;
				}
				if (prev) prev->next = nlist->next;
				else pNode->sgprivate->parents = nlist->next;
				gf_free(nlist);
#ifdef GPAC_HAS_QJS
				if (pNode->sgprivate->parents==NULL) detach=1;
#endif
				break;
			}
		}
		if (parentNode->sgprivate->scenegraph != pSG) {
			gf_list_del_item(pSG->exported_nodes, pNode);
		}
	}

#ifndef GPAC_DISABLE_VRML
	/*if this is a proto its is registered in its parent graph, not the current*/
	if (pSG && (pNode == (GF_Node*)pSG->pOwningProto)) pSG = pSG->parent_scene;
#endif

	/*unregister the instance*/
	assert(pNode->sgprivate->num_instances);
	pNode->sgprivate->num_instances -= 1;

	/*this is just an instance removed*/
	if (pNode->sgprivate->num_instances) {
#ifdef GPAC_HAS_QJS
		if (pNode->sgprivate->num_instances==1) detach=1;
		if (pSG && pNode->sgprivate->scenegraph->on_node_modified && detach && pNode->sgprivate->interact && pNode->sgprivate->interact->js_binding) {
			pNode->sgprivate->scenegraph->on_node_modified(pNode->sgprivate->scenegraph, pNode, NULL, NULL);
		}
#endif
		return GF_OK;
	}

	assert(pNode->sgprivate->parents==NULL);

	if (pSG) {
		/*if def, remove from sg def table*/
		if (pNode->sgprivate->flags & GF_NODE_IS_DEF) {
			remove_node_id(pSG, pNode);
		}

#ifndef GPAC_DISABLE_VRML
		/*check all routes from or to this node and destroy them - cf spec*/
		GF_Route *r;
		j=0;
		while ((r = (GF_Route *)gf_list_enum(pSG->Routes, &j))) {
			if ( (r->ToNode == pNode) || (r->FromNode == pNode)) {
				gf_sg_route_del(r);
				j--;
			}
		}
#endif

#ifndef GPAC_DISABLE_SVG
		if (pSG->use_stack && (gf_list_del_item(pSG->use_stack, pNode)>=0)) {
			pSG->abort_bubbling = 1;
		}
#endif

	}
	/*delete the node*/
	if (pNode->sgprivate->scenegraph && (pNode->sgprivate->scenegraph->RootNode==pNode)) {
		pSG = pNode->sgprivate->scenegraph;
		gf_node_del(pNode);
		pSG->RootNode = NULL;
	} else {
		gf_node_del(pNode);
	}
	return GF_OK;
}
GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode)
{
#ifndef GPAC_DISABLE_VRML
	u32 j;
#endif
#ifdef GPAC_HAS_QJS
	Bool detach=0;
#endif
	GF_SceneGraph *pSG;

	if (!pNode) return GF_OK;
	pSG = pNode->sgprivate->scenegraph;

	if (parentNode) {
		GF_ParentList *nlist = pNode->sgprivate->parents;
		if (nlist) {
			GF_ParentList *prev = NULL;
			while (nlist) {
				if (nlist->node != parentNode) {
					prev = nlist;
					nlist = nlist->next;
					continue;
				}
				if (prev) prev->next = nlist->next;
				else pNode->sgprivate->parents = nlist->next;
				gf_free(nlist);
#ifdef GPAC_HAS_QJS
				if (pNode->sgprivate->parents==NULL) detach=1;
#endif
				break;
			}
		}
		if (parentNode->sgprivate->scenegraph != pSG) {
			gf_list_del_item(pSG->exported_nodes, pNode);
		}
	}

#ifndef GPAC_DISABLE_VRML
	 
	if (pSG && (pNode == (GF_Node*)pSG->pOwningProto)) pSG = pSG->parent_scene;
#endif

	 
	assert(pNode->sgprivate->num_instances);
	pNode->sgprivate->num_instances -= 1;

	 
	if (pNode->sgprivate->num_instances) {
#ifdef GPAC_HAS_QJS
		if (pNode->sgprivate->num_instances==1) detach=1;
		if (pSG && pNode->sgprivate->scenegraph->on_node_modified && detach && pNode->sgprivate->interact && pNode->sgprivate->interact->js_binding) {
			pNode->sgprivate->scenegraph->on_node_modified(pNode->sgprivate->scenegraph, pNode, NULL, NULL);
		}
#endif
		return GF_OK;
	}

	assert(pNode->sgprivate->parents==NULL);

	if (pSG) {
		 
		if (pNode->sgprivate->flags & GF_NODE_IS_DEF) {
			remove_node_id(pSG, pNode);
		}

#ifndef GPAC_DISABLE_VRML
		 
		GF_Route *r;
		j=0;
		while ((r = (GF_Route *)gf_list_enum(pSG->Routes, &j))) {
			if ( (r->ToNode == pNode) || (r->FromNode == pNode)) {
				gf_sg_route_del(r);
				j--;
			}
		}
#endif

#ifndef GPAC_DISABLE_SVG
		if (pSG->use_stack && (gf_list_del_item(pSG->use_stack, pNode)>=0)) {
			pSG->abort_bubbling = 1;
		}
#endif

	}
	 
	if (pNode->sgprivate->scenegraph && (pNode->sgprivate->scenegraph->RootNode==pNode)) {
		pSG = pNode->sgprivate->scenegraph;
		gf_node_del(pNode);
		pSG->RootNode = NULL;
	} else {
		gf_node_del(pNode);
	}
	return GF_OK;
}