unsigned int CCSpriteBatchNode::rebuildIndexInOrder(CCSprite *pobParent, unsigned int uIndex)
	{
		NSMutableArray<CCNode*> *pChildren = pobParent->getChildren();

		if (pChildren && pChildren->count() > 0)
		{
			CCSprite *pSprite;
			NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
			for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
			{
				pSprite = (CCSprite*)(*iter);

				if (! pSprite)
				{
					break;
				}

				if (pSprite->getZOrder() < 0)
				{
					uIndex = rebuildIndexInOrder(pSprite, uIndex);
				}
			}
		}	

		// ignore self (batch node)
		if (! pobParent->isEqual(this))
		{
			pobParent->setAtlasIndex(uIndex);
			uIndex++;
		}

		if (pChildren && pChildren->count() > 0)
		{
			CCSprite *pSprite;
			NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
			for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
			{
				pSprite = (CCSprite*)(*iter);

				if (! pSprite)
				{
					break;
				}

				if (pSprite->getZOrder() >= 0)
				{
					uIndex = rebuildIndexInOrder(pSprite, uIndex);
				}
			}
		}

		return uIndex;
	}
	void CCSpriteBatchNode::insertChild(CCSprite *pobSprite, unsigned int uIndex)
	{
		pobSprite->useBatchNode(this);
		pobSprite->setAtlasIndex(uIndex);
		pobSprite->setDirty(true);

		if (m_pobTextureAtlas->getTotalQuads() == m_pobTextureAtlas->getCapacity())
		{
			increaseAtlasCapacity();
		}

		ccV3F_C4B_T2F_Quad quad = pobSprite->getQuad();
		m_pobTextureAtlas->insertQuad(&quad, uIndex);

		m_pobDescendants->insertObjectAtIndex(pobSprite, uIndex);

		// update indices
		unsigned int i = 0;
		if (m_pobDescendants && m_pobDescendants->count() > 0)
		{
			NSMutableArray<CCSprite*>::NSMutableArrayIterator iter;
			for (iter = m_pobDescendants->begin(); iter != m_pobDescendants->end(); ++iter)
			{
				if (! *iter)
				{
					break;
				}

				if (i > uIndex)
				{
					(*iter)->setAtlasIndex((*iter)->getAtlasIndex() + 1);
				}

				++i;
			}
		}	

		// add children recursively
		NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren();
		if (pChildren && pChildren->count() > 0)
		{
			NSMutableArray<CCNode*>::NSMutableArrayIterator iterNode;
			CCSprite *pSprite;
			for (iterNode = pChildren->begin(); iterNode != pChildren->end(); ++iterNode)
			{
				pSprite = (CCSprite*)(*iterNode);

				if (! pSprite)
				{
					break;
				}

				unsigned int uIndex = atlasIndexForChild(pSprite, pSprite->getZOrder());
				insertChild(pSprite, uIndex);
			}
		}
	}
	bool CCTMXTiledMap::initWithTMXFile(const char *tmxFile)
	{
		NSAssert(tmxFile != NULL && strlen(tmxFile)>0, "TMXTiledMap: tmx file should not bi nil");
		
		setContentSize(CGSizeZero);

		CCTMXMapInfo *mapInfo = CCTMXMapInfo::formatWithTMXFile(tmxFile);

		NSAssert( mapInfo->getTilesets()->count() != 0, "TMXTiledMap: Map not found. Please check the filename.");

		m_tMapSize = mapInfo->getMapSize();
		m_tTileSize = mapInfo->getTileSize();
		m_nMapOrientation = mapInfo->getOrientation();
		setObjectGroups(mapInfo->getObjectGroups());
		setProperties(mapInfo->getProperties());
		CCX_SAFE_RELEASE(m_pTileProperties);
		m_pTileProperties = mapInfo->getTileProperties();
		CCX_SAFE_RETAIN(m_pTileProperties);

		int idx = 0;

		NSMutableArray<CCTMXLayerInfo*>* layers = mapInfo->getLayers();
		if (layers && layers->count()>0)
		{
			CCTMXLayerInfo *layerInfo = NULL;
			NSMutableArray<CCTMXLayerInfo*>::NSMutableArrayIterator it;
			for (it = layers->begin(); it != layers->end(); ++it)
			{
				layerInfo = *it;
				if (layerInfo && layerInfo->m_bVisible)
				{
					CCTMXLayer *child = parseLayer(layerInfo, mapInfo);
					addChild((CCNode*)child, idx, idx);

					// update content size with the max size
					CGSize childSize = child->getContentSize();
					CGSize currentSize = this->getContentSize();
					currentSize.width = MAX( currentSize.width, childSize.width );
					currentSize.height = MAX( currentSize.height, childSize.height );
					this->setContentSize(currentSize);

					idx++;
				}
			}
		}
		return true;
	}
	void CCSpriteBatchNode::removeSpriteFromAtlas(CCSprite *pobSprite)
	{
		// remove from TextureAtlas
		m_pobTextureAtlas->removeQuadAtIndex(pobSprite->getAtlasIndex());

		// Cleanup sprite. It might be reused (issue #569)
		pobSprite->useSelfRender();

		unsigned int uIndex = m_pobDescendants->getIndexOfObject(pobSprite);
		if (uIndex != -1)
		{
			m_pobDescendants->removeObjectAtIndex(uIndex);

			// update all sprites beyond this one
			unsigned int count = m_pobDescendants->count();

			for(; uIndex < count; ++uIndex)
			{
				CCSprite* s = (CCSprite*)(m_pobDescendants->getObjectAtIndex(uIndex));
				s->setAtlasIndex( s->getAtlasIndex() - 1 );
			}
		}

		// remove children recursively
		NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren();
		if (pChildren && pChildren->count() > 0)
		{
			CCSprite *pSprite;
			NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
			for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
			{
				pSprite = (CCSprite*)(*iter);

				if (! pSprite)
				{
					break;
				}

				removeSpriteFromAtlas(pSprite);
			}
		}
	}