static void gf_dump_vrml_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field)
{
	u32 i, sf_type;
	Bool needs_field_container;
	GF_ChildNodeItem *list;
	void *slot_ptr;

	switch (field.fieldType) {
	case GF_SG_VRML_SFNODE:
		assert ( *(GF_Node **)field.far_ptr);

		if (sdump->XMLDump) {
			if (!sdump->X3DDump) {
				StartElement(sdump, (char *) field.name);
				EndElementHeader(sdump, 1);
				sdump->indent++;
			}
		} else {
			StartAttribute(sdump, field.name);
		}
		gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL);

		if (sdump->XMLDump) {
			if (!sdump->X3DDump) {
				sdump->indent--;
				EndElement(sdump, (char *) field.name, 1);
			}
		} else {
			EndAttribute(sdump);
		}
		return;
	case GF_SG_VRML_MFNODE:
		needs_field_container = 0;
		if (sdump->XMLDump && sdump->X3DDump) {
			u32 count, nb_ndt;
			GF_FieldInfo info;
			if (!strcmp(field.name, "children")) {
				needs_field_container = 0;
			} else {
				nb_ndt = 0;
				count = gf_node_get_field_count(node);
				for (i=0; i<count; i++) {
					gf_node_get_field(node, i, &info);
					if ((info.eventType==GF_SG_EVENT_IN) || (info.eventType==GF_SG_EVENT_OUT)) continue;
					if (info.NDTtype==field.NDTtype) nb_ndt++;
				}
				needs_field_container = (nb_ndt>1) ? 1 : 0;
			}
		}

#ifndef GPAC_DISABLE_X3D
		if (!sdump->X3DDump) {
			if (gf_node_get_tag(node)==TAG_X3D_Switch) field.name = "choice";
		}
#endif
		list = * ((GF_ChildNodeItem **) field.far_ptr);
		assert(list);
		if (!sdump->XMLDump || !sdump->X3DDump) StartList(sdump, field.name);
		sdump->indent++;
		while (list) {
			gf_dump_vrml_node(sdump, list->node, 1, needs_field_container ? (char *) field.name : NULL);
			list = list->next;
		}
		sdump->indent--;
		if (!sdump->XMLDump || !sdump->X3DDump) EndList(sdump, field.name);
		return;
	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
		StartElement(sdump, (char *) field.name);
		EndElementHeader(sdump, 1);
		sdump->indent++;
		if (!gf_list_count(cb->commandList)) {
			/*the arch does not allow for that (we would need a codec and so on, or decompress the command list
			in all cases...)*/
			if (sdump->trace && cb->bufferSize) {
				if (sdump->XMLDump) gf_fprintf(sdump->trace, "<!--SFCommandBuffer cannot be dumped while playing - use MP4Box instead-->\n");
				else gf_fprintf(sdump->trace, "#SFCommandBuffer cannot be dumped while playing - use MP4Box instead\n");
			}
		} else {
			gf_sm_dump_command_list(sdump, cb->commandList, sdump->indent, 0);
		}
		sdump->indent--;
		EndElement(sdump, (char *) field.name, 1);
	}
	return;

	case GF_SG_VRML_MFATTRREF:
		if (sdump->XMLDump) {
			MFAttrRef *ar = (MFAttrRef *)field.far_ptr;
			StartElement(sdump, (char *) field.name);
			EndElementHeader(sdump, 1);
			sdump->indent++;

			for (i=0; i<ar->count; i++) {
				if (ar->vals[i].node) {
					GF_FieldInfo pinfo;
					DUMP_IND(sdump);
					gf_node_get_field(ar->vals[i].node, ar->vals[i].fieldIndex, &pinfo);
					gf_fprintf(sdump->trace, "<store node=\"");
					scene_dump_vrml_id(sdump, ar->vals[i].node);
					gf_fprintf(sdump->trace, "\" field=\"%s\"/>\n", pinfo.name);
				}
			}

			sdump->indent--;
			EndElement(sdump, (char *) field.name, 1);
			return;
		}
		break;
	}


	if (gf_sg_vrml_is_sf_field(field.fieldType)) {
		StartAttribute(sdump, field.name);
		gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0, node);
		EndAttribute(sdump);
	} else {
		GenMFField *mffield = (GenMFField *) field.far_ptr;
		sf_type = gf_sg_vrml_get_sf_type(field.fieldType);

		if (sdump->XMLDump && sdump->X3DDump) {
			switch (sf_type) {
			case GF_SG_VRML_SFSTRING:
			case GF_SG_VRML_SFSCRIPT:
			case GF_SG_VRML_SFURL:
				gf_fprintf(sdump->trace, " %s=\'", (char *) field.name);
				break;
			default:
				StartAttribute(sdump, field.name);
				break;
			}
		} else {
			StartAttribute(sdump, field.name);
		}

		if (!sdump->XMLDump) gf_fprintf(sdump->trace, "[");
		for (i=0; mffield && (i<mffield->count); i++) {
			if (i) gf_fprintf(sdump->trace, " ");
			gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
			gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, 1, node);
		}
		if (!sdump->XMLDump) gf_fprintf(sdump->trace, "]");

		if (sdump->XMLDump && sdump->X3DDump) {
			switch (sf_type) {
			case GF_SG_VRML_SFSTRING:
			case GF_SG_VRML_SFSCRIPT:
			case GF_SG_VRML_SFURL:
				gf_fprintf(sdump->trace, "\'");
				break;
			default:
				EndAttribute(sdump);
				break;
			}
		} else {
			EndAttribute(sdump);
		}
	}
}
static void gf_dump_vrml_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field)
{
	u32 i, sf_type;
	Bool needs_field_container;
	GF_ChildNodeItem *list;
	void *slot_ptr;

	switch (field.fieldType) {
	case GF_SG_VRML_SFNODE:
		assert ( *(GF_Node **)field.far_ptr);

		if (sdump->XMLDump) {
			if (!sdump->X3DDump) {
				StartElement(sdump, (char *) field.name);
				EndElementHeader(sdump, 1);
				sdump->indent++;
			}
		} else {
			StartAttribute(sdump, field.name);
		}
		gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL);

		if (sdump->XMLDump) {
			if (!sdump->X3DDump) {
				sdump->indent--;
				EndElement(sdump, (char *) field.name, 1);
			}
		} else {
			EndAttribute(sdump);
		}
		return;
	case GF_SG_VRML_MFNODE:
		needs_field_container = 0;
		if (sdump->XMLDump && sdump->X3DDump) {
			u32 count, nb_ndt;
			GF_FieldInfo info;
			if (!strcmp(field.name, "children")) {
				needs_field_container = 0;
			} else {
				nb_ndt = 0;
				count = gf_node_get_field_count(node);
				for (i=0; i<count; i++) {
					gf_node_get_field(node, i, &info);
					if ((info.eventType==GF_SG_EVENT_IN) || (info.eventType==GF_SG_EVENT_OUT)) continue;
					if (info.NDTtype==field.NDTtype) nb_ndt++;
				}
				needs_field_container = (nb_ndt>1) ? 1 : 0;
			}
		}

#ifndef GPAC_DISABLE_X3D
		if (!sdump->X3DDump) {
			if (gf_node_get_tag(node)==TAG_X3D_Switch) field.name = "choice";
		}
#endif
		list = * ((GF_ChildNodeItem **) field.far_ptr);
		assert(list);
		if (!sdump->XMLDump || !sdump->X3DDump) StartList(sdump, field.name);
		sdump->indent++;
		while (list) {
			gf_dump_vrml_node(sdump, list->node, 1, needs_field_container ? (char *) field.name : NULL);
			list = list->next;
		}
		sdump->indent--;
		if (!sdump->XMLDump || !sdump->X3DDump) EndList(sdump, field.name);
		return;
	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
		StartElement(sdump, (char *) field.name);
		EndElementHeader(sdump, 1);
		sdump->indent++;
		if (!gf_list_count(cb->commandList)) {
			 
			if (sdump->trace && cb->bufferSize) {
				if (sdump->XMLDump) gf_fprintf(sdump->trace, "<!--SFCommandBuffer cannot be dumped while playing - use MP4Box instead-->\n");
				else gf_fprintf(sdump->trace, "#SFCommandBuffer cannot be dumped while playing - use MP4Box instead\n");
			}
		} else {
			gf_sm_dump_command_list(sdump, cb->commandList, sdump->indent, 0);
		}
		sdump->indent--;
		EndElement(sdump, (char *) field.name, 1);
	}
	return;

	case GF_SG_VRML_MFATTRREF:
		if (sdump->XMLDump) {
			MFAttrRef *ar = (MFAttrRef *)field.far_ptr;
			StartElement(sdump, (char *) field.name);
			EndElementHeader(sdump, 1);
			sdump->indent++;

			for (i=0; i<ar->count; i++) {
				if (ar->vals[i].node) {
					GF_FieldInfo pinfo;
					DUMP_IND(sdump);
					gf_node_get_field(ar->vals[i].node, ar->vals[i].fieldIndex, &pinfo);
					gf_fprintf(sdump->trace, "<store node=\"");
					scene_dump_vrml_id(sdump, ar->vals[i].node);
					gf_fprintf(sdump->trace, "\" field=\"%s\"/>\n", pinfo.name);
				}
			}

			sdump->indent--;
			EndElement(sdump, (char *) field.name, 1);
			return;
		}
		break;
	}


	if (gf_sg_vrml_is_sf_field(field.fieldType)) {
		StartAttribute(sdump, field.name);
		gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0, node);
		EndAttribute(sdump);
	} else {
		GenMFField *mffield = (GenMFField *) field.far_ptr;
		sf_type = gf_sg_vrml_get_sf_type(field.fieldType);

		if (sdump->XMLDump && sdump->X3DDump) {
			switch (sf_type) {
			case GF_SG_VRML_SFSTRING:
			case GF_SG_VRML_SFSCRIPT:
			case GF_SG_VRML_SFURL:
				gf_fprintf(sdump->trace, " %s=\'", (char *) field.name);
				break;
			default:
				StartAttribute(sdump, field.name);
				break;
			}
		} else {
			StartAttribute(sdump, field.name);
		}

		if (!sdump->XMLDump) gf_fprintf(sdump->trace, "[");
		for (i=0; mffield && (i<mffield->count); i++) {
			if (i) gf_fprintf(sdump->trace, " ");
			gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
			gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, 1, node);
		}
		if (!sdump->XMLDump) gf_fprintf(sdump->trace, "]");

		if (sdump->XMLDump && sdump->X3DDump) {
			switch (sf_type) {
			case GF_SG_VRML_SFSTRING:
			case GF_SG_VRML_SFSCRIPT:
			case GF_SG_VRML_SFURL:
				gf_fprintf(sdump->trace, "\'");
				break;
			default:
				EndAttribute(sdump);
				break;
			}
		} else {
			EndAttribute(sdump);
		}
	}
}