static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer)
{
	u32 i, count, to_dump, sub_el, ID;
	u32 *def_fields;
	Bool isDEF, isScript, isProto, hasISed;
	char *name;
	GF_Node *base;
	GF_FieldInfo field, base_field;

	if (!node) {
		gf_fprintf(sdump->trace, "NULL");
		return;
	}

	/*this dumper works only for VRML like graphs*/
	if (node->sgprivate->tag>GF_NODE_RANGE_LAST_X3D) return;

	if (!scene_dump_vrml_can_dump(sdump, node)) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] node %s not part of %s standard - removing\n", gf_node_get_class_name(node), sdump->X3DDump ? "X3D" : (sdump->dump_mode==GF_SM_DUMP_VRML) ? "VRML" : "MPEG4"));
		if (!in_list) gf_fprintf(sdump->trace, "NULL");
		return;
	}

	/*convert whatever possible*/
	name = (char*)gf_node_get_class_name(node);
#ifndef GPAC_DISABLE_VRML
	if (sdump->X3DDump) {
		if (node->sgprivate->tag == TAG_MPEG4_Circle) name = "Circle2D";
		else if (node->sgprivate->tag == TAG_MPEG4_Rectangle) name = "Rectangle2D";
#ifndef GPAC_DISABLE_X3D
	} else {
		if (node->sgprivate->tag == TAG_X3D_Circle2D) name = "Circle";
		else if (node->sgprivate->tag == TAG_X3D_Rectangle2D) name = "Rectangle";
#endif
	}
#endif



	isProto = (gf_node_get_tag(node) == TAG_ProtoNode) ? 1 : 0;
	ID = gf_node_get_id(node);
	isDEF = 0;
	if (ID) {
		isDEF = gf_dump_vrml_is_def_node(sdump, node);
		if (!isDEF) {
			if (!sdump->XMLDump) {
				if (in_list) DUMP_IND(sdump);
				gf_fprintf(sdump->trace, "USE ");
				scene_dump_vrml_id(sdump, node);
				if (in_list) gf_fprintf(sdump->trace, "\n");
			} else {
				if (isProto) {
					StartElement(sdump, "ProtoInstance");
					StartAttribute(sdump, "name");
					gf_fprintf(sdump->trace, "%s", name);
					EndAttribute(sdump);
				} else {
					StartElement(sdump, name);
				}
				StartAttribute(sdump, "USE");
				scene_dump_vrml_id(sdump, node);
				EndAttribute(sdump);
				EndElementHeader(sdump, 0);
			}
			return;
		}
	}

	/*get all fields*/
	count = gf_node_get_field_count(node);
	def_fields = (u32*)gf_malloc(sizeof(u32) * count);

	base = NULL;
	switch (gf_node_get_tag(node)) {
#ifndef GPAC_DISABLE_VRML
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Script:
#endif
	case TAG_MPEG4_Script:
		isScript = 1;
		break;
#endif
	default:
		isScript = 0;
		break;
	}


	if (!isScript) {
		if (isProto) {
			base = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);
		} else {
			base = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
		}
	}

	if (base) gf_node_register(base, NULL);

	hasISed = 0;
	to_dump = sub_el = 0;
	for (i=0; i<count; i++) {
		if (isScript) {
			/*dyn script fields are complex types*/
			def_fields[i] = (i>2) ? 2 : 1;
		} else {
			def_fields[i] = 0;
		}

		gf_node_get_field(node, i, &field);

		if (sdump->current_proto) {
			if (gf_dump_vrml_get_IS(sdump, node, &field) != NULL) {
				def_fields[i] = 3;
				if ((field.fieldType == GF_SG_VRML_SFNODE) || (field.fieldType == GF_SG_VRML_MFNODE))
					def_fields[i] = sdump->XMLDump ? 4 : 3;
				/*in XMT the ISed is not an attribute*/
				if (sdump->XMLDump) sub_el++;
				to_dump++;
				hasISed = 1;
				continue;
			}
		}

		if (!isScript && ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) ) {
			continue;
		}
		/*proto instance in XMT lists all fields as elements*/
		if (sdump->XMLDump && isProto) {
			def_fields[i] = 2;
			to_dump++;
			sub_el++;
			continue;
		}
		switch (field.fieldType) {
		case GF_SG_VRML_SFNODE:
			if (* (GF_Node **) field.far_ptr) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
			break;
		case GF_SG_VRML_MFNODE:
			if (* (GF_ChildNodeItem**) field.far_ptr) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
			break;
		case GF_SG_VRML_SFCOMMANDBUFFER:
		{
			SFCommandBuffer *p = (SFCommandBuffer *)field.far_ptr;
			if (p->bufferSize || gf_list_count(p->commandList)) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
		}
		break;
		case GF_SG_VRML_MFATTRREF:
		{
			MFAttrRef *p = (MFAttrRef*)field.far_ptr;
			if (p->count) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
		}
		break;
		default:
			if (isScript) {
				to_dump++;
			} else {
				gf_node_get_field(base, i, &base_field);
				if (!gf_sg_vrml_field_equal(base_field.far_ptr, field.far_ptr, field.fieldType)) {
					def_fields[i] = 1;
					to_dump++;
				}
			}
			break;
		}
	}
	if (base) gf_node_unregister(base, NULL);

	if (!to_dump) {
		if (in_list) DUMP_IND(sdump);
		if (!sdump->XMLDump) {
			if (isDEF) {
				gf_fprintf(sdump->trace, "DEF ");
				scene_dump_vrml_id(sdump, node);
				gf_fprintf(sdump->trace, " ");
			}
			gf_fprintf(sdump->trace, "%s {}\n", name);
		} else {
			if (isDEF) {
				if (isProto) {
					gf_fprintf(sdump->trace, "<ProtoInstance name=\"%s\" DEF=\"", name);
				} else {
					gf_fprintf(sdump->trace, "<%s DEF=\"", name);
				}
				scene_dump_vrml_id(sdump, node);
				gf_fprintf(sdump->trace, "\"/>\n");
			} else {
				if (isProto) {
					gf_fprintf(sdump->trace, "<ProtoInstance name=\"%s\"/>\n", name);
				} else {
					gf_fprintf(sdump->trace, "<%s/>\n", name);
				}
			}
		}
		gf_free(def_fields);
		return;
	}

	if (!sdump->XMLDump) {
		if (in_list) DUMP_IND(sdump);
		if (isDEF) {
			gf_fprintf(sdump->trace, "DEF ");
			scene_dump_vrml_id(sdump, node);
			gf_fprintf(sdump->trace, " ");
		}
		gf_fprintf(sdump->trace, "%s {\n", name);
	} else {
		if (isProto) {
			StartElement(sdump, "ProtoInstance");
			StartAttribute(sdump, "name");
			gf_fprintf(sdump->trace, "%s", name);
			EndAttribute(sdump);
		} else {
			StartElement(sdump, name);
		}
		if (isDEF) {
			StartAttribute(sdump, "DEF");
			scene_dump_vrml_id(sdump, node);
			EndAttribute(sdump);
		}
	}

	sdump->indent ++;
	for (i=0; i<count; i++) {
		switch (def_fields[i]) {
		/*regular field*/
		case 1:
			gf_node_get_field(node, i, &field);
			if (!isScript) {
				gf_dump_vrml_field(sdump, node, field);
			}
			/*special script dump case, static fields except url*/
			else if (i==1 || i==2) {
				if (*((SFBool *)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
			}
			/*in bt first dump fields - in XMT first dump url*/
			else if (i && !sdump->XMLDump) {
				gf_dump_vrml_dyn_field(sdump, node, field, 0);
			} else if (!i && sdump->XMLDump) {
				gf_dump_vrml_field(sdump, node, field);
			}
			break;
		/*IS field*/
		case 3:
			if (sdump->XMLDump) break;
			gf_node_get_field(node, i, &field);
			gf_dump_vrml_IS_field(sdump, node, field, isScript, 0);
			def_fields[i] = 0;
			break;
		default:
			break;
		}
	}
	if (fieldContainer) gf_fprintf(sdump->trace, " fieldContainer=\"%s\"", fieldContainer);

	if (isScript) sub_el = 1;
	EndElementHeader(sdump, sub_el ? 1 : 0);

	if (sub_el) {
		/*dump all normal IS elements for XMT*/
		if (hasISed && sdump->XMLDump) {
			StartElement(sdump, "IS");
			EndElementHeader(sdump, 1);
			sdump->indent++;
		}
		for (i=0; i<count; i++) {
			if (def_fields[i]==3) {
				gf_node_get_field(node, i, &field);
				gf_dump_vrml_IS_field(sdump, node, field, isScript, 1);
			}
		}
		if (hasISed && sdump->XMLDump) {
			sdump->indent--;
			EndElement(sdump, "IS", 1);
		}
		/*dump all sub elements and complex IS*/
		for (i=0; i<count; i++) {
			switch (def_fields[i]) {
			case 2:
				gf_node_get_field(node, i, &field);
				if (!isScript) {
					if (isProto && sdump->XMLDump) {
						gf_dump_vrml_proto_field(sdump, node, field);
					} else {
						gf_dump_vrml_field(sdump, node, field);
					}
				} else {
#ifndef GPAC_DISABLE_X3D
					/*X3D script metadata, NOT DYN*/
					if ((i==3) && (node->sgprivate->tag==TAG_X3D_Script) ) {
						if (*((GF_Node **)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
					} else
#endif
					{
						gf_dump_vrml_dyn_field(sdump, node, field, 0);
					}
				}
				break;
			case 4:
				gf_node_get_field(node, i, &field);
				gf_dump_vrml_IS_field(sdump, node, field, isScript, 0);
				break;
			}
		}
	}

	/*finally dump script - XMT dumping is broken!!*/
	if (isScript && !sdump->XMLDump) {
		gf_node_get_field(node, 0, &field);
		gf_dump_vrml_field(sdump, node, field);
	}

	sdump->indent --;
	if (!sdump->XMLDump && !in_list) {
		DUMP_IND(sdump);
		gf_fprintf(sdump->trace, "}");
	} else {
		EndElement(sdump, isProto ? "ProtoInstance" : name, sub_el);
	}
	gf_free(def_fields);
}
static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer)
{
	u32 i, count, to_dump, sub_el, ID;
	u32 *def_fields;
	Bool isDEF, isScript, isProto, hasISed;
	char *name;
	GF_Node *base;
	GF_FieldInfo field, base_field;

	if (!node) {
		gf_fprintf(sdump->trace, "NULL");
		return;
	}

	 
	if (node->sgprivate->tag>GF_NODE_RANGE_LAST_X3D) return;

	if (!scene_dump_vrml_can_dump(sdump, node)) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] node %s not part of %s standard - removing\n", gf_node_get_class_name(node), sdump->X3DDump ? "X3D" : (sdump->dump_mode==GF_SM_DUMP_VRML) ? "VRML" : "MPEG4"));
		if (!in_list) gf_fprintf(sdump->trace, "NULL");
		return;
	}

	 
	name = (char*)gf_node_get_class_name(node);
#ifndef GPAC_DISABLE_VRML
	if (sdump->X3DDump) {
		if (node->sgprivate->tag == TAG_MPEG4_Circle) name = "Circle2D";
		else if (node->sgprivate->tag == TAG_MPEG4_Rectangle) name = "Rectangle2D";
#ifndef GPAC_DISABLE_X3D
	} else {
		if (node->sgprivate->tag == TAG_X3D_Circle2D) name = "Circle";
		else if (node->sgprivate->tag == TAG_X3D_Rectangle2D) name = "Rectangle";
#endif
	}
#endif



	isProto = (gf_node_get_tag(node) == TAG_ProtoNode) ? 1 : 0;
	ID = gf_node_get_id(node);
	isDEF = 0;
	if (ID) {
		isDEF = gf_dump_vrml_is_def_node(sdump, node);
		if (!isDEF) {
			if (!sdump->XMLDump) {
				if (in_list) DUMP_IND(sdump);
				gf_fprintf(sdump->trace, "USE ");
				scene_dump_vrml_id(sdump, node);
				if (in_list) gf_fprintf(sdump->trace, "\n");
			} else {
				if (isProto) {
					StartElement(sdump, "ProtoInstance");
					StartAttribute(sdump, "name");
					gf_fprintf(sdump->trace, "%s", name);
					EndAttribute(sdump);
				} else {
					StartElement(sdump, name);
				}
				StartAttribute(sdump, "USE");
				scene_dump_vrml_id(sdump, node);
				EndAttribute(sdump);
				EndElementHeader(sdump, 0);
			}
			return;
		}
	}

	 
	count = gf_node_get_field_count(node);
	def_fields = (u32*)gf_malloc(sizeof(u32) * count);

	base = NULL;
	switch (gf_node_get_tag(node)) {
#ifndef GPAC_DISABLE_VRML
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Script:
#endif
	case TAG_MPEG4_Script:
		isScript = 1;
		break;
#endif
	default:
		isScript = 0;
		break;
	}


	if (!isScript) {
		if (isProto) {
			base = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);
		} else {
			base = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
		}
	}

	if (base) gf_node_register(base, NULL);

	hasISed = 0;
	to_dump = sub_el = 0;
	for (i=0; i<count; i++) {
		if (isScript) {
			 
			def_fields[i] = (i>2) ? 2 : 1;
		} else {
			def_fields[i] = 0;
		}

		gf_node_get_field(node, i, &field);

		if (sdump->current_proto) {
			if (gf_dump_vrml_get_IS(sdump, node, &field) != NULL) {
				def_fields[i] = 3;
				if ((field.fieldType == GF_SG_VRML_SFNODE) || (field.fieldType == GF_SG_VRML_MFNODE))
					def_fields[i] = sdump->XMLDump ? 4 : 3;
				 
				if (sdump->XMLDump) sub_el++;
				to_dump++;
				hasISed = 1;
				continue;
			}
		}

		if (!isScript && ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) ) {
			continue;
		}
		 
		if (sdump->XMLDump && isProto) {
			def_fields[i] = 2;
			to_dump++;
			sub_el++;
			continue;
		}
		switch (field.fieldType) {
		case GF_SG_VRML_SFNODE:
			if (* (GF_Node **) field.far_ptr) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
			break;
		case GF_SG_VRML_MFNODE:
			if (* (GF_ChildNodeItem**) field.far_ptr) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
			break;
		case GF_SG_VRML_SFCOMMANDBUFFER:
		{
			SFCommandBuffer *p = (SFCommandBuffer *)field.far_ptr;
			if (p->bufferSize || gf_list_count(p->commandList)) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
		}
		break;
		case GF_SG_VRML_MFATTRREF:
		{
			MFAttrRef *p = (MFAttrRef*)field.far_ptr;
			if (p->count) {
				def_fields[i] = 2;
				to_dump++;
				sub_el++;
			}
		}
		break;
		default:
			if (isScript) {
				to_dump++;
			} else {
				gf_node_get_field(base, i, &base_field);
				if (!gf_sg_vrml_field_equal(base_field.far_ptr, field.far_ptr, field.fieldType)) {
					def_fields[i] = 1;
					to_dump++;
				}
			}
			break;
		}
	}
	if (base) gf_node_unregister(base, NULL);

	if (!to_dump) {
		if (in_list) DUMP_IND(sdump);
		if (!sdump->XMLDump) {
			if (isDEF) {
				gf_fprintf(sdump->trace, "DEF ");
				scene_dump_vrml_id(sdump, node);
				gf_fprintf(sdump->trace, " ");
			}
			gf_fprintf(sdump->trace, "%s {}\n", name);
		} else {
			if (isDEF) {
				if (isProto) {
					gf_fprintf(sdump->trace, "<ProtoInstance name=\"%s\" DEF=\"", name);
				} else {
					gf_fprintf(sdump->trace, "<%s DEF=\"", name);
				}
				scene_dump_vrml_id(sdump, node);
				gf_fprintf(sdump->trace, "\"/>\n");
			} else {
				if (isProto) {
					gf_fprintf(sdump->trace, "<ProtoInstance name=\"%s\"/>\n", name);
				} else {
					gf_fprintf(sdump->trace, "<%s/>\n", name);
				}
			}
		}
		gf_free(def_fields);
		return;
	}

	if (!sdump->XMLDump) {
		if (in_list) DUMP_IND(sdump);
		if (isDEF) {
			gf_fprintf(sdump->trace, "DEF ");
			scene_dump_vrml_id(sdump, node);
			gf_fprintf(sdump->trace, " ");
		}
		gf_fprintf(sdump->trace, "%s {\n", name);
	} else {
		if (isProto) {
			StartElement(sdump, "ProtoInstance");
			StartAttribute(sdump, "name");
			gf_fprintf(sdump->trace, "%s", name);
			EndAttribute(sdump);
		} else {
			StartElement(sdump, name);
		}
		if (isDEF) {
			StartAttribute(sdump, "DEF");
			scene_dump_vrml_id(sdump, node);
			EndAttribute(sdump);
		}
	}

	sdump->indent ++;
	for (i=0; i<count; i++) {
		switch (def_fields[i]) {
		 
		case 1:
			gf_node_get_field(node, i, &field);
			if (!isScript) {
				gf_dump_vrml_field(sdump, node, field);
			}
			 
			else if (i==1 || i==2) {
				if (*((SFBool *)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
			}
			 
			else if (i && !sdump->XMLDump) {
				gf_dump_vrml_dyn_field(sdump, node, field, 0);
			} else if (!i && sdump->XMLDump) {
				gf_dump_vrml_field(sdump, node, field);
			}
			break;
		 
		case 3:
			if (sdump->XMLDump) break;
			gf_node_get_field(node, i, &field);
			gf_dump_vrml_IS_field(sdump, node, field, isScript, 0);
			def_fields[i] = 0;
			break;
		default:
			break;
		}
	}
	if (fieldContainer) gf_fprintf(sdump->trace, " fieldContainer=\"%s\"", fieldContainer);

	if (isScript) sub_el = 1;
	EndElementHeader(sdump, sub_el ? 1 : 0);

	if (sub_el) {
		 
		if (hasISed && sdump->XMLDump) {
			StartElement(sdump, "IS");
			EndElementHeader(sdump, 1);
			sdump->indent++;
		}
		for (i=0; i<count; i++) {
			if (def_fields[i]==3) {
				gf_node_get_field(node, i, &field);
				gf_dump_vrml_IS_field(sdump, node, field, isScript, 1);
			}
		}
		if (hasISed && sdump->XMLDump) {
			sdump->indent--;
			EndElement(sdump, "IS", 1);
		}
		 
		for (i=0; i<count; i++) {
			switch (def_fields[i]) {
			case 2:
				gf_node_get_field(node, i, &field);
				if (!isScript) {
					if (isProto && sdump->XMLDump) {
						gf_dump_vrml_proto_field(sdump, node, field);
					} else {
						gf_dump_vrml_field(sdump, node, field);
					}
				} else {
#ifndef GPAC_DISABLE_X3D
					 
					if ((i==3) && (node->sgprivate->tag==TAG_X3D_Script) ) {
						if (*((GF_Node **)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
					} else
#endif
					{
						gf_dump_vrml_dyn_field(sdump, node, field, 0);
					}
				}
				break;
			case 4:
				gf_node_get_field(node, i, &field);
				gf_dump_vrml_IS_field(sdump, node, field, isScript, 0);
				break;
			}
		}
	}

	 
	if (isScript && !sdump->XMLDump) {
		gf_node_get_field(node, 0, &field);
		gf_dump_vrml_field(sdump, node, field);
	}

	sdump->indent --;
	if (!sdump->XMLDump && !in_list) {
		DUMP_IND(sdump);
		gf_fprintf(sdump->trace, "}");
	} else {
		EndElement(sdump, isProto ? "ProtoInstance" : name, sub_el);
	}
	gf_free(def_fields);
}