public IAppInstance Run(IAppInstall App)
		{
			LuminAppInstall LuminInstall = App as LuminAppInstall;

			if (LuminInstall == null)
			{
				throw new Exception("AppInstance is of incorrect type!");
			}

			string QualifiedPackageName = GetQualifiedProjectName(LuminInstall.Name);

			// wake the device - we can install while its asleep but not run
			PowerOn();

			// kill any currently running instance:
			KillRunningProcess(QualifiedPackageName);
			
			Log.Info("Launching {0} on '{1}' ", QualifiedPackageName, ToString());
			Log.Verbose("\t{0}", LuminInstall.CommandLine);

			// Clear the device's log in preparation for the test..
			RunMldbDeviceCommand("log -c");

			// start the app on device!
			string CommandLine = "launch --auto-net-privs " + QualifiedPackageName + " -i \"" + LuminInstall.CommandLine + "\"";
			IProcessResult Process = RunMldbDeviceCommand(CommandLine, false, true);

			return new LuminAppInstance(this, LuminInstall, Process);
		}
		public IAppInstall InstallApplication(UnrealAppConfig AppConfig)
		{
			LuminBuild Build = AppConfig.Build as LuminBuild;

			string QualifiedPackageName = GetQualifiedProjectName(AppConfig.ProjectName);

			InstalledAppName = AppConfig.ProjectName;

			// Ensure MPK exists
			if (Build == null)
			{
				throw new AutomationException("Invalid build for Lumin!");
			}

			// kill any currently running instance:
			KillRunningProcess(QualifiedPackageName);

			bool SkipDeploy = Globals.Params.ParseParam("SkipDeploy");

			if (SkipDeploy == false)
			{
				// remote dir used to save things
				string RemoteDir = "/documents/c2/" + AppConfig.ProjectName.ToLower();				
				//string DependencyDir = RemoteDir + "/deps";

				// device artifact path, always clear between runs
				// This clear is from andorid, but currently not needed on mldb.  Everything is removed when you remove the pak
				// If in the future mldb supports a "sidecar" of data like the obb on Android, might need to delete that here
				DeviceArtifactPath = string.Format("{0}/{1}/saved", RemoteDir.ToLower(), AppConfig.ProjectName.ToLower());

				if (Globals.Params.ParseParam("cleandevice"))
				{
					Log.Info("Cleaning previous builds due to presence of -cleandevice");

					// we need to ununstall then install the mpk - don't care if it fails, may have been deleted
					Log.Info("Uninstalling {0}", QualifiedPackageName);
					RunMldbDeviceCommand(string.Format("uninstall {0}", QualifiedPackageName));
				}

				// path to the MPK to install.
				string MpkPath = Build.SourceMpkPath;

				// check for a local newer executable
				if (Globals.Params.ParseParam("dev"))
				{
					string MpkFileName = UnrealHelpers.GetExecutableName(AppConfig.ProjectName, UnrealTargetPlatform.Lumin, AppConfig.Configuration, AppConfig.ProcessType, "mpk");

					string LocalMPK = Path.Combine(Environment.CurrentDirectory, AppConfig.ProjectName, "Binaries/Lumin", MpkFileName);

					bool LocalFileExists = File.Exists(LocalMPK);
					bool LocalFileNewer = LocalFileExists && File.GetLastWriteTime(LocalMPK) > File.GetLastWriteTime(MpkPath);

					Log.Verbose("Checking for newer binary at {0}", LocalMPK);
					Log.Verbose("LocalFile exists: {0}. Newer: {1}", LocalFileExists, LocalFileNewer);

					if (LocalFileExists && LocalFileNewer)
					{
						MpkPath = LocalMPK;
					}
				}

				// first install the MPK
				RunMldbDeviceCommand(string.Format("install -u {0}", MpkPath));

				// If in the future mldb supports a "sidecar" of data like the obb on Android, might need to install that here
				// The Gauntlet.TargetDeviceAndroid.cs implementation should be a good starting point
			}

			LuminAppInstall AppInstall = new LuminAppInstall(this, AppConfig.ProjectName, Build.LuminPackageName, AppConfig.CommandLine);

			return AppInstall;
		}
		public LuminAppInstance(TargetDeviceLumin InDevice, LuminAppInstall InInstall, IProcessResult InProcess)
		{
			LuminDevice = InDevice;
			Install = InInstall;
			LaunchProcess = InProcess;
		}