void FBlueprintStatsModule::DumpBlueprintStats()
{
	TArray<FBlueprintStatRecord> Records;
	for (TObjectIterator<UBlueprint> BlueprintIt; BlueprintIt; ++BlueprintIt)
	{
		UBlueprint* Blueprint = *BlueprintIt;

		new (Records) FBlueprintStatRecord(Blueprint);
	}


	// Now merge them
	FBlueprintStatRecord Aggregate(NULL);
	for (const FBlueprintStatRecord& SourceRecord : Records)
	{
		Aggregate.MergeAnotherRecordIn(SourceRecord);
	}

	// Sort the lists
	Aggregate.NodeCount.ValueSort(TGreater<int32>());
	Aggregate.FunctionCount.ValueSort(TGreater<int32>());
	Aggregate.FunctionOwnerCount.ValueSort(TGreater<int32>());
	Aggregate.RemoteMacroCount.ValueSort(TGreater<int32>());

	// Print out the merged record
	UE_LOG(LogBlueprintStats, Log, TEXT("Blueprint stats for %d blueprints in %s"), Records.Num(), GGameName);
	UE_LOG(LogBlueprintStats, Log, TEXT("%s"), *Aggregate.ToString(true));
	UE_LOG(LogBlueprintStats, Log, TEXT("%s"), *Aggregate.ToString(false));
	UE_LOG(LogBlueprintStats, Log, TEXT("\n"));

	// Print out the node list
	UE_LOG(LogBlueprintStats, Log, TEXT("NodeClass,NumInstances"));
	for (const auto& NodePair : Aggregate.NodeCount)
	{
		UE_LOG(LogBlueprintStats, Log, TEXT("%s,%d"), *(NodePair.Key->GetName()), NodePair.Value);
	}
	UE_LOG(LogBlueprintStats, Log, TEXT("\n"));

	// Print out the function list
	UE_LOG(LogBlueprintStats, Log, TEXT("FunctionPath,ClassName,FunctionName,NumInstances"));
	for (const auto& FunctionPair : Aggregate.FunctionCount)
	{
		UFunction* Function = FunctionPair.Key;
		UE_LOG(LogBlueprintStats, Log, TEXT("%s,%s,%s,%d"), *(Function->GetPathName()), *(Function->GetOuterUClass()->GetName()), *(Function->GetName()), FunctionPair.Value);
	}
	UE_LOG(LogBlueprintStats, Log, TEXT("\n"));

	// Print out the macro list
	UE_LOG(LogBlueprintStats, Log, TEXT("MacroPath,MacroName,NumInstances"));
	for (const auto& MacroPair : Aggregate.RemoteMacroCount)
	{
		UEdGraph* MacroGraph = MacroPair.Key;
		UE_LOG(LogBlueprintStats, Log, TEXT("%s,%s,%d"), *(MacroGraph->GetPathName()), *(MacroGraph->GetName()), MacroPair.Value);
	}
	UE_LOG(LogBlueprintStats, Log, TEXT("\n"));
}
//------------------------------------------------------------------------------
static int32 GetHiddenFunctions(uint32 Indent, UClass* Class, bool bShowFunLibs, FString& JsonOut)
{
	int32 HiddenFuncCount = 0;

	FString IndentString = GetIndentString(Indent);
	JsonOut += IndentString + TEXT("\"HiddenFunctions\" : [");

	FString& OutputString = JsonOut;
	UClass*  CallingClass = Class;
	auto FindHiddenFuncs = [&IndentString, &CallingClass, &HiddenFuncCount, &OutputString] (UClass* FunctionClass) 
	{
		for (TFieldIterator<UFunction> FunctionIt(FunctionClass, EFieldIteratorFlags::IncludeSuper); FunctionIt; ++FunctionIt)
		{
			UFunction* Function = *FunctionIt;
			if (FObjectEditorUtils::IsFunctionHiddenFromClass(Function, CallingClass))
			{
				++HiddenFuncCount;
				OutputString += TEXT("\n\t") + IndentString + TEXT("\"") + Function->GetPathName() + TEXT("\",");
			}
		}

		/*for (TFieldIterator<UObjectProperty> PropIt(FuncClass, EFieldIteratorFlags::IncludeSuper); PropIt; ++PropIt)
		{
			UClass* PropClass = PropIt->PropertyClass;
			for (TFieldIterator<UFunction> FunctionIt(PropClass, EFieldIteratorFlags::IncludeSuper); FunctionIt; ++FunctionIt)
			{
				if (FObjectEditorUtils::IsFunctionHiddenFromClass(*FunctionIt, ThisClass))
				{
					++HiddenFuncCount;
					OutputString += TEXT("\n\t\t\t\"") + FunctionIt->GetPathName() + TEXT("\",");
				}
			}
		}*/
	};

	FindHiddenFuncs(CallingClass); // find all this class's functions

	if (bShowFunLibs)
	{
		for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) // find all functions in each function library
		{
			UClass* TestClass = *ClassIt;
			// if this is a skeleton class, don't bother
			if (FKismetEditorUtilities::IsClassABlueprintSkeleton(TestClass))
			{
				continue;
			}

			if (TestClass->IsChildOf(UBlueprintFunctionLibrary::StaticClass()))
			{
				FindHiddenFuncs(TestClass);
			}
		}
	}
	if (HiddenFuncCount > 0)
	{
		OutputString.RemoveAt(OutputString.Len() - 1); // remove the last comma
	}
	OutputString += TEXT("\n") + IndentString + TEXT("]");

	return HiddenFuncCount;
}