void RunCrashReportClient(const TCHAR* CommandLine)
{
	// Override the stack size for the thread pool.
	FQueuedThreadPool::OverrideStackSize = 256 * 1024;

	// Set up the main loop
	GEngineLoop.PreInit(CommandLine);

	// Initialize config.
	FCrashReportClientConfig::Get();

	const bool bUnattended = 
#if CRASH_REPORT_UNATTENDED_ONLY
		true;
#else
		FApp::IsUnattended();
#endif // CRASH_REPORT_UNATTENDED_ONLY

	// Set up the main ticker
	FMainLoopTiming MainLoop(IdealTickRate, bUnattended ? EMainLoopOptions::CoreTickerOnly : EMainLoopOptions::UsingSlate);

	// Find the report to upload in the command line arguments
	ParseCommandLine(CommandLine);

	// Increase the HttpSendTimeout to 5 minutes
	GConfig->SetFloat(TEXT("HTTP"), TEXT("HttpSendTimeout"), 5*60.0f, GEngineIni);

	FPlatformErrorReport::Init();
	auto ErrorReport = LoadErrorReport();
	
	if( ErrorReport.HasFilesToUpload() )
	{
		// Send analytics.
		extern FCrashDescription& GetCrashDescription();
		GetCrashDescription().SendAnalytics();
	}

	if (bUnattended)
	{
		ErrorReport.SetUserComment( NSLOCTEXT( "CrashReportClient", "UnattendedMode", "Sent in the unattended mode" ), false );
		FCrashReportClientUnattended CrashReportClient( ErrorReport );

		// loop until the app is ready to quit
		while (!GIsRequestingExit)
		{
			MainLoop.Tick();
		}
	}
	else
	{
#if !CRASH_REPORT_UNATTENDED_ONLY
		// crank up a normal Slate application using the platform's standalone renderer
		FSlateApplication::InitializeAsStandaloneApplication(GetStandardStandaloneRenderer());

		// Prepare the custom Slate styles
		FCrashReportClientStyle::Initialize();

		// Create the main implementation object
		TSharedRef<FCrashReportClient> CrashReportClient = MakeShareable(new FCrashReportClient(ErrorReport));

		// open up the app window	
		TSharedRef<SCrashReportClient> ClientControl = SNew(SCrashReportClient, CrashReportClient);

		auto Window = FSlateApplication::Get().AddWindow(
			SNew(SWindow)
			.Title(NSLOCTEXT("CrashReportClient", "CrashReportClientAppName", "Unreal Engine 4 Crash Reporter"))
			.ClientSize(InitialWindowDimensions)
			[
				ClientControl
			]);

		Window->SetRequestDestroyWindowOverride(FRequestDestroyWindowOverride::CreateSP(CrashReportClient, &FCrashReportClient::RequestCloseWindow));

		// Setting focus seems to have to happen after the Window has been added
		FSlateApplication::Get().ClearKeyboardFocus(EFocusCause::Cleared);

		// Debugging code
		if (RunWidgetReflector)
		{
			FSlateApplication::Get().AddWindow(
				SNew(SWindow)
				.ClientSize(FVector2D(800, 600))
				[
					FModuleManager::LoadModuleChecked<ISlateReflectorModule>("SlateReflector").GetWidgetReflector()
				]);
		}

		// loop until the app is ready to quit
		while (!GIsRequestingExit)
		{
			MainLoop.Tick();

			if (CrashReportClient->ShouldWindowBeHidden())
			{
				Window->HideWindow();
			}
		}

		// Clean up the custom styles
		FCrashReportClientStyle::Shutdown();

		// Close down the Slate application
		FSlateApplication::Shutdown();
#endif // !CRASH_REPORT_UNATTENDED_ONLY
	}

	FPlatformErrorReport::ShutDown();

	FEngineLoop::AppPreExit();
	FTaskGraphInterface::Shutdown();

	FEngineLoop::AppExit();
}
void RunAllarBuilderClient(const TCHAR* CommandLine)
{
	GEngineLoop.PreInit(CommandLine);

	UE_LOG(LogAllarBuilder, Display, TEXT("Hello World"));

	// Set up the main ticker
	FMainLoopTiming MainLoop(IdealTickRate);

	// crank up a normal Slate application using the platform's standalone renderer
	FSlateApplication::InitializeAsStandaloneApplication(GetStandardStandaloneRenderer());

	// Prepare the custom Slate styles
	FAllarBuilderClientStyle::Initialize();

	// Create the main implementation object
	TSharedRef<FAllarBuilderClient> AllarBuilderClient = MakeShareable(new FAllarBuilderClient());

	TSharedRef<FSlateStyleSet> Style = FAllarBuilderClientStyle::GetPtr().ToSharedRef();

	// open up the app window	
	TSharedRef<SAllarBuilderClient> ClientControl = SNew(SAllarBuilderClient, AllarBuilderClient, Style);

	auto Window = FSlateApplication::Get().AddWindow(
		SNew(SWindow)
		.Title(NSLOCTEXT("AllarBuilder", "AllarBuilderClientAppName", "Allar's Unreal Engine 4 Development Launcher"))	
		.ClientSize(InitialWindowDimensions)
		.SupportsMaximize(false)
		[
			ClientControl
		]
	);

	// Debugging code
	if (true)
	{
		FSlateApplication::Get().AddWindow(
			SNew(SWindow)
			.ClientSize(FVector2D(720, 600))
			.ScreenPosition(FVector2D(0, 1080))
			.AutoCenter(EAutoCenter::None)
			[
				FModuleManager::LoadModuleChecked<ISlateReflectorModule>("SlateReflector").GetWidgetReflector()
			]);
	}

	// Setting focus seems to have to happen after the Window has been added
	FSlateApplication::Get().ClearKeyboardFocus(EFocusCause::Cleared);

	// loop until the app is ready to quit
	while (!GIsRequestingExit)
	{
		MainLoop.Tick();
	}

	Window->SetRequestDestroyWindowOverride(FRequestDestroyWindowOverride::CreateSP(AllarBuilderClient, &FAllarBuilderClient::RequestCloseWindow));

	// Clean up the custom styles
	FAllarBuilderClientStyle::Shutdown();

	// Close down the Slate application
	FSlateApplication::Shutdown();

	FEngineLoop::AppPreExit();
	FTaskGraphInterface::Shutdown();

	FEngineLoop::AppExit();
}