void SG_GraphRemoved(GF_Node *node, GF_SceneGraph *sg)
{
	u32 i, count;
	GF_FieldInfo info;
	u32 tag;


	tag = node->sgprivate->tag;
	if (tag == TAG_ProtoNode) return;

	/*not possible in DOM ?*/
	if (tag>GF_NODE_RANGE_LAST_VRML) return;

	count = gf_node_get_field_count(node);
	for (i=0; i<count; i++) {
		gf_node_get_field(node, i, &info);
		if (info.fieldType==GF_SG_VRML_SFNODE) {
			GF_Node *n = *(GF_Node **) info.far_ptr;
			if (n) {
				if (n->sgprivate->scenegraph==sg) {
					/*if root of graph, skip*/
					if (sg->RootNode!=n) {
						gf_node_unregister(n, node);
						/*don't forget to remove node...*/
						*(GF_Node **) info.far_ptr = NULL;
					}
				} else {
					SG_GraphRemoved(n, sg);
				}
			}
		}
		else if (info.fieldType==GF_SG_VRML_MFNODE) {
			GF_ChildNodeItem *cur, *prev, *list = *(GF_ChildNodeItem **) info.far_ptr;
			prev = NULL;
			while (list) {
				if (list->node->sgprivate->scenegraph==sg) {
					gf_node_unregister(list->node, node);

					if (prev) prev->next = list->next;
					else *(GF_ChildNodeItem **) info.far_ptr = list->next;
					cur = list;
					gf_free(cur);
				} else {
					SG_GraphRemoved(list->node, sg);
				}
				list = list->next;
			}
		}
		/*for uncompressed files (bt/xmt/laserML), also reset command lists*/
		else if (info.fieldType==GF_SG_VRML_SFCOMMANDBUFFER) {
			u32 j, count2;
			SFCommandBuffer *cb = (SFCommandBuffer*)info.far_ptr;
			count2 = gf_list_count(cb->commandList);
			for (j=0; j<count2; j++) {
				u32 k = 0;
				GF_CommandField *f;
				GF_Command *com = gf_list_get(cb->commandList, j);
				while ((f=gf_list_enum(com->command_fields, &k))) {
					switch (f->fieldType) {
					case GF_SG_VRML_SFNODE:
						if (f->new_node) {
							if (f->new_node->sgprivate->scenegraph==sg) {
								/*if root of graph, skip*/
								if (sg->RootNode!=f->new_node) {
									gf_node_unregister(f->new_node, node);
									/*don't forget to remove node...*/
									f->new_node = NULL;
								}
							} else {
								SG_GraphRemoved(f->new_node, sg);
							}
						}
						break;
					case GF_SG_VRML_MFNODE:
						if (f->node_list) {
							GF_ChildNodeItem *cur, *prev, *list = f->node_list;
							prev = NULL;
							while (list) {
								if (list->node->sgprivate->scenegraph==sg) {
									gf_node_unregister(list->node, node);

									if (prev) prev->next = list->next;
									else f->node_list = list->next;
									cur = list;
									gf_free(cur);
								} else {
									SG_GraphRemoved(list->node, sg);
								}
								list = list->next;
							}
						}
						break;
					}
				}
			}
		}
	}
}
void SG_GraphRemoved(GF_Node *node, GF_SceneGraph *sg)
{
	u32 i, count;
	GF_FieldInfo info;
	u32 tag;


	tag = node->sgprivate->tag;
	if (tag == TAG_ProtoNode) return;

	 
	if (tag>GF_NODE_RANGE_LAST_VRML) return;

	count = gf_node_get_field_count(node);
	for (i=0; i<count; i++) {
		gf_node_get_field(node, i, &info);
		if (info.fieldType==GF_SG_VRML_SFNODE) {
			GF_Node *n = *(GF_Node **) info.far_ptr;
			if (n) {
				if (n->sgprivate->scenegraph==sg) {
					 
					if (sg->RootNode!=n) {
						gf_node_unregister(n, node);
						 
						*(GF_Node **) info.far_ptr = NULL;
					}
				} else {
					SG_GraphRemoved(n, sg);
				}
			}
		}
		else if (info.fieldType==GF_SG_VRML_MFNODE) {
			GF_ChildNodeItem *cur, *prev, *list = *(GF_ChildNodeItem **) info.far_ptr;
			prev = NULL;
			while (list) {
				if (list->node->sgprivate->scenegraph==sg) {
					gf_node_unregister(list->node, node);

					if (prev) prev->next = list->next;
					else *(GF_ChildNodeItem **) info.far_ptr = list->next;
					cur = list;
					gf_free(cur);
				} else {
					SG_GraphRemoved(list->node, sg);
				}
				list = list->next;
			}
		}
		 
		else if (info.fieldType==GF_SG_VRML_SFCOMMANDBUFFER) {
			u32 j, count2;
			SFCommandBuffer *cb = (SFCommandBuffer*)info.far_ptr;
			count2 = gf_list_count(cb->commandList);
			for (j=0; j<count2; j++) {
				u32 k = 0;
				GF_CommandField *f;
				GF_Command *com = gf_list_get(cb->commandList, j);
				while ((f=gf_list_enum(com->command_fields, &k))) {
					switch (f->fieldType) {
					case GF_SG_VRML_SFNODE:
						if (f->new_node) {
							if (f->new_node->sgprivate->scenegraph==sg) {
								 
								if (sg->RootNode!=f->new_node) {
									gf_node_unregister(f->new_node, node);
									 
									f->new_node = NULL;
								}
							} else {
								SG_GraphRemoved(f->new_node, sg);
							}
						}
						break;
					case GF_SG_VRML_MFNODE:
						if (f->node_list) {
							GF_ChildNodeItem *cur, *prev, *list = f->node_list;
							prev = NULL;
							while (list) {
								if (list->node->sgprivate->scenegraph==sg) {
									gf_node_unregister(list->node, node);

									if (prev) prev->next = list->next;
									else f->node_list = list->next;
									cur = list;
									gf_free(cur);
								} else {
									SG_GraphRemoved(list->node, sg);
								}
								list = list->next;
							}
						}
						break;
					}
				}
			}
		}
	}
}