xmlNode* AddArray(xmlNode* parent, const char* id, const FloatList& values)
	{
		size_t valueCount = values.size();
		FUSStringBuilder builder;
		builder.reserve(valueCount * FLOAT_STR_ESTIMATE);
		FUStringConversion::ToString(builder, values);
		return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount);
	}
	xmlNode* AddArray(xmlNode* parent, const char* id, const StringList& values, const char* arrayType)
	{
		size_t valueCount = values.size();
		FUSStringBuilder builder;
		builder.reserve(valueCount * 18); // Pulled out of a hat
		if (valueCount > 0)
		{
			StringList::const_iterator itV = values.begin();
			builder.set(*itV);
			for (++itV; itV != values.end(); ++itV) { builder.append(' '); builder.append(*itV); }
		}
		return AddArray(parent, id, arrayType, builder.ToCharPtr(), valueCount);
	}
	xmlNode* AddArray(xmlNode* parent, const char* id, const FMMatrix44List& values)
	{
		FUSStringBuilder builder;
		size_t valueCount = values.size();
		builder.reserve(valueCount * 16 * FLOAT_STR_ESTIMATE);
		if (valueCount > 0)
		{
			FMMatrix44List::const_iterator itM = values.begin();
			FUStringConversion::ToString(builder, *itM);
			for (++itM; itM != values.end(); ++itM) { builder.append(' '); FUStringConversion::ToString(builder, *itM); }
		}
		return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount * 16);
	}
	xmlNode* AddArray(xmlNode* parent, const char* id, const FMVector3List& values)
	{
		// Reserve the necessary space within the string builder
		FUSStringBuilder builder;
		size_t valueCount = values.size();
		builder.reserve(valueCount * 3 * FLOAT_STR_ESTIMATE);
		if (valueCount > 0)
		{
			// Write out the values
			FMVector3List::const_iterator itP = values.begin();
			FUStringConversion::ToString(builder, *itP);
			for (++itP; itP != values.end(); ++itP) { builder.append(' '); FUStringConversion::ToString(builder, *itP); }
		}

		// Create the typed array node.
		return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount * 3);
	}
	xmlNode* AddSourceInterpolation(xmlNode* parent, const char* id, const FUDaeInterpolationList& interpolations)
	{
		xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT);
		AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id);
		FUSStringBuilder arrayId(id); arrayId.append("-array");

		FUSStringBuilder builder;
		size_t valueCount = interpolations.size();
		if (valueCount > 0)
		{
			FUDaeInterpolationList::const_iterator itI = interpolations.begin();
			builder.append(FUDaeInterpolation::ToString(*itI));
			for (++itI; itI != interpolations.end(); ++itI)
			{
				builder.append(' '); builder.append(FUDaeInterpolation::ToString(*itI));
			}
		}
		AddArray(sourceNode, arrayId.ToCharPtr(), DAE_NAME_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount);
		xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
		const char* parameter = "INTERPOLATION";
		AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), valueCount, 1, &parameter, DAE_NAME_TYPE);
		return sourceNode;
	}