VJSStructuredClone::SNode* VJSStructuredClone::_VValueBagToNode( const XBOX::VValueBag& inBag, bool inUniqueElementsAreNotArrays)
{
	// inspired from VValueBag::GetJSONString
	SNode *bagNode = NULL;
	
	if ((bagNode = new SNode()) == NULL)
		return NULL;
	
	bagNode->fType = eNODE_OBJECT;
	bagNode->fValue.fFirstChild = NULL;
	
	SNode *curNode = NULL;

	// Iterate the attributes
	VString attName;
	VIndex attCount = inBag.GetAttributesCount();
	for (VIndex attIndex = 1 ; attIndex <= attCount ; ++attIndex)
	{
		const VValueSingle *attValue = inBag.GetNthAttribute( attIndex, &attName);
		if ((attName != L"____objectunic") && (attName != L"____property_name_in_jsarray"))
		{
			SNode *attNode = NULL;

			if (attValue != NULL)
			{
				attNode = _VValueSingleToNode( *attValue);
			}
			else
			{
				VString emptyString;
				attNode = _VValueSingleToNode( emptyString);
			}

			if (attNode != NULL)
			{
				VValueBag::StKey CDataBagKey( attName);
				if (CDataBagKey.Equal( VValueBag::CDataAttributeName()))
					attName = "__cdata";

				attNode->fName.FromString( attName);
				attNode->fNextSibling = NULL;
				if (curNode == NULL)
					curNode = bagNode->fValue.fFirstChild = attNode;
				else
					curNode = curNode->fNextSibling = attNode;
			}
		}
	}

	// Iterate the elements
	VString elementName;
	VIndex elementNamesCount = inBag.GetElementNamesCount();
	for (VIndex elementNamesIndex = 1 ; elementNamesIndex <= elementNamesCount ; ++elementNamesIndex)
	{
		const VBagArray* bagArray = inBag.GetNthElementName( elementNamesIndex, &elementName);
		if (bagArray != NULL)
		{
			SNode *elemNode = NULL;

			if ((bagArray->GetCount() == 1) && inUniqueElementsAreNotArrays)
			{
				elemNode = _VValueBagToNode( *bagArray->GetNth(1), inUniqueElementsAreNotArrays);
			}
			else if (bagArray->GetNth(1)->GetAttribute("____objectunic") != NULL)
			{
				elemNode = _VValueBagToNode( *bagArray->GetNth(1), inUniqueElementsAreNotArrays);
			}
			else
			{
				elemNode = _VBagArrayToNode( *bagArray, inUniqueElementsAreNotArrays);
			}

			if (elemNode != NULL)
			{
				elemNode->fName.FromString( elementName);
				elemNode->fNextSibling = NULL;

				if (curNode == NULL)
					curNode = bagNode->fValue.fFirstChild = elemNode;
				else
					curNode = curNode->fNextSibling = elemNode;
			}
		}
	}

	return bagNode;
}
void VJSSessionStorageObject::FillWithVValueBag( const XBOX::VValueBag& inBag, bool inUniqueElementsAreNotArrays)
{
	// inspired from VValueBag::GetJSONString
	XBOX::StLocker<XBOX::VCriticalSection>	lock(&fMutex);

	// Iterate the attributes
	VString attName;
	VIndex attCount = inBag.GetAttributesCount();
	for (VIndex attIndex = 1 ; attIndex <= attCount ; ++attIndex)
	{
		const VValueSingle *attValue = inBag.GetNthAttribute( attIndex, &attName);
		if ((attName != L"____objectunic") && (attName != L"____property_name_in_jsarray"))
		{
			VJSStructuredClone *clone = NULL;

			if (attValue != NULL)
			{
				clone = VJSStructuredClone::RetainCloneForVValueSingle( *attValue);
			}
			else
			{
				VString emptyString;
				clone = VJSStructuredClone::RetainCloneForVValueSingle( emptyString);
			}

			if (clone != NULL)
			{
				VValueBag::StKey CDataBagKey( attName);
				if (CDataBagKey.Equal( VValueBag::CDataAttributeName()))
					attName = "__cdata";

				fKeysValues[attName] = VRefPtr<VJSStructuredClone>(clone);
				ReleaseRefCountable( &clone);
			}
		}
	}

	// Iterate the elements
	VString elementName;
	VIndex elementNamesCount = inBag.GetElementNamesCount();
	for (VIndex elementNamesIndex = 1 ; elementNamesIndex <= elementNamesCount ; ++elementNamesIndex)
	{
		const VBagArray* bagArray = inBag.GetNthElementName( elementNamesIndex, &elementName);
		if (bagArray != NULL)
		{
			VJSStructuredClone *clone = NULL;

			if ((bagArray->GetCount() == 1) && inUniqueElementsAreNotArrays)
			{
				clone = VJSStructuredClone::RetainCloneForVValueBag( *bagArray->GetNth(1), inUniqueElementsAreNotArrays);
			}
			else if (bagArray->GetNth(1)->GetAttribute("____objectunic") != NULL)
			{
				clone = VJSStructuredClone::RetainCloneForVValueBag( *bagArray->GetNth(1), inUniqueElementsAreNotArrays);
			}
			else
			{
				clone = VJSStructuredClone::RetainCloneForVBagArray( *bagArray, inUniqueElementsAreNotArrays);
			}

			if (clone != NULL)
			{
				fKeysValues[elementName] = VRefPtr<VJSStructuredClone>(clone);
				ReleaseRefCountable( &clone);
			}
		}
	}
}