//If we get back an error (not found, etc...), handle it here
void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)
{
    LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();

    llinfos << "LLInventoryModelFetchDescendentsResponder::error "
            << status << ": " << reason << llendl;

    fetcher->incrFetchCount(-1);

    if (status==499) // timed out
    {
        for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
                folder_it != mRequestSD["folders"].endArray();
                ++folder_it)
        {
            LLSD folder_sd = *folder_it;
            LLUUID folder_id = folder_sd["folder_id"];
            const BOOL recursive = getIsRecursive(folder_id);
            fetcher->mFetchQueue.push_front(LLInventoryModelBackgroundFetch::FetchQueueInfo(folder_id, recursive));
        }
    }
    else
    {
        if (fetcher->isBulkFetchProcessingComplete())
        {
            fetcher->setAllFoldersFetched();
        }
    }
    gInventory.notifyObservers();
}
//If we get back an error (not found, etc...), handle it here
void LLInventoryModelFetchDescendentsResponder::httpFailure(void)
{
	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();

	llinfos << "LLInventoryModelFetchDescendentsResponder::error "
		<< mStatus << ": " << mReason << llendl;
						
	fetcher->incrFetchCount(-1);

	if (is_internal_http_error_that_warrants_a_retry(mStatus)) // timed out
	{
		for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
			folder_it != mRequestSD["folders"].endArray();
			++folder_it)
		{	
			LLSD folder_sd = *folder_it;
			LLUUID folder_id = folder_sd["folder_id"];
			const BOOL recursive = getIsRecursive(folder_id);
			fetcher->mFetchQueue.push_front(LLInventoryModelBackgroundFetch::FetchQueueInfo(folder_id, recursive));
		}
	}
	else
	{
		if (fetcher->isBulkFetchProcessingComplete())
		{
			fetcher->setAllFoldersFetched();
		}
	}
	gInventory.notifyObservers();
}
// If we get back a normal response, handle it here.
void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
{
    LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
    if (content.has("folders"))
    {

        for(LLSD::array_const_iterator folder_it = content["folders"].beginArray();
                folder_it != content["folders"].endArray();
                ++folder_it)
        {
            LLSD folder_sd = *folder_it;


            //LLUUID agent_id = folder_sd["agent_id"];

            //if(agent_id != gAgent.getID())	//This should never happen.
            //{
            //	llwarns << "Got a UpdateInventoryItem for the wrong agent."
            //			<< llendl;
            //	break;
            //}

            LLUUID parent_id = folder_sd["folder_id"];
            LLUUID owner_id = folder_sd["owner_id"];
            S32    version  = (S32)folder_sd["version"].asInteger();
            S32    descendents = (S32)folder_sd["descendents"].asInteger();
            LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);

            if (parent_id.isNull())
            {
                LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
                for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
                        item_it != folder_sd["items"].endArray();
                        ++item_it)
                {
                    LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
                    if (lost_uuid.notNull())
                    {
                        LLSD item = *item_it;
                        titem->unpackMessage(item);

                        LLInventoryModel::update_list_t update;
                        LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
                        update.push_back(new_folder);
                        gInventory.accountForUpdate(update);

                        titem->setParent(lost_uuid);
                        titem->updateParentOnServer(FALSE);
                        gInventory.updateItem(titem);
                        gInventory.notifyObservers();

                    }
                }
            }

            LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id);
            if (!pcat)
            {
                continue;
            }

            for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray();
                    category_it != folder_sd["categories"].endArray();
                    ++category_it)
            {
                LLSD category = *category_it;
                tcategory->fromLLSD(category);

                const BOOL recursive = getIsRecursive(tcategory->getUUID());

                if (recursive)
                {
                    fetcher->mFetchQueue.push_back(LLInventoryModelBackgroundFetch::FetchQueueInfo(tcategory->getUUID(), recursive));
                }
                else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) )
                {
                    gInventory.updateCategory(tcategory);
                }

            }
            LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
            for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
                    item_it != folder_sd["items"].endArray();
                    ++item_it)
            {
                LLSD item = *item_it;
                titem->unpackMessage(item);

                gInventory.updateItem(titem);
            }

            // set version and descendentcount according to message.
            LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
            if(cat)
            {
                cat->setVersion(version);
                cat->setDescendentCount(descendents);
                cat->determineFolderType();
            }

        }
    }

    if (content.has("bad_folders"))
    {
        for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray();
                folder_it != content["bad_folders"].endArray();
                ++folder_it)
        {
            LLSD folder_sd = *folder_it;

            //These folders failed on the dataserver.  We probably don't want to retry them.
            llinfos << "Folder " << folder_sd["folder_id"].asString()
                    << "Error: " << folder_sd["error"].asString() << llendl;
        }
    }

    fetcher->incrFetchCount(-1);

    if (fetcher->isBulkFetchProcessingComplete())
    {
        llinfos << "Inventory fetch completed" << llendl;
        fetcher->setAllFoldersFetched();
    }

    gInventory.notifyObservers();
}