public async void Can_Install_Apk()
        {
            var logger = new ConsoleLogger();
            Guid emuId = Guid.NewGuid();

            // Start an emulator.
            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            int consolePort = 5554;
            var emuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, false, emuId);

            using (IEmulator droidEmulator = emuFactory.GetEmulator())
            {
                await droidEmulator.Start(TestConfig.EmulatorStartupTimeout).ContinueWith((t) =>
                {
                    // sut
                    var adb = adbFactory.GetAndroidDebugBridge();
                    var currentDir = Environment.CurrentDirectory;

                    var apkPath = System.IO.Path.Combine(currentDir, "..\\..\\..\\", TestConfig.PathToAndroidTestsApk);

                    adb.Install(droidEmulator.Device, apkPath, AdbInstallFlags.ReplaceExistingApplication);


                });


            }


        }
        public async void Can_Run_Tests()
        {
            var logger = new ConsoleLogger();
            Guid emuId = Guid.NewGuid();

            // Start an emulator.
            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            int consolePort = 5554;
            var emuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, false, emuId);

            using (IEmulator droidEmulator = emuFactory.GetEmulator())
            {
                await droidEmulator.Start(TestConfig.EmulatorStartupTimeout).ContinueWith((t) =>
                {

                    if (t.IsFaulted)
                    {
                        throw t.Exception;
                    }

                    var adb = adbFactory.GetAndroidDebugBridge();

                    // install tests apk
                    var currentDir = Environment.CurrentDirectory;
                    var apkPath = System.IO.Path.Combine(currentDir, "..\\..\\..\\", TestConfig.PathToAndroidTestsApk);
                    adb.Install(droidEmulator.Device, apkPath, AdbInstallFlags.ReplaceExistingApplication);

                    // sut
                    var testRunner = new AndroidTestRunner(logger, adbFactory, droidEmulator.Device, TestConfig.AndroidTestsPackageName, TestConfig.AndroidTestsInstrumentationClassPath);
                    var testResults = testRunner.RunTests();

                    Assert.That(testResults, Is.Not.Null);
                    var tests = testResults.GetTests().ToList();
                    var failedTests = tests.Where(a => a.Kind == TestResultKind.Failure);

                    foreach (var a in failedTests)
                    {
                        logger.LogMessage(string.Format("{0} - ", a.Name, a.StackTrace));
                    }

                });

            }

        }
        public async void Can_Report_Tests_To_Default_Reporter()
        {
            var logger = new ConsoleLogger();
            Guid emuId = Guid.NewGuid();

            // Start an emulator.
            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            int consolePort = 5554;
            var emuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, false, emuId);

            using (IEmulator droidEmulator = emuFactory.GetEmulator())
            {
                await droidEmulator.Start(TestConfig.EmulatorStartupTimeout).ContinueWith((t) =>
                {

                    if (t.IsFaulted)
                    {
                        throw t.Exception;
                    }

                    var adb = adbFactory.GetAndroidDebugBridge();

                    // install tests apk
                    var currentDir = Environment.CurrentDirectory;
                    var apkPath = System.IO.Path.Combine(currentDir, "..\\..\\..\\", TestConfig.PathToAndroidTestsApk);
                    adb.Install(droidEmulator.Device, apkPath, AdbInstallFlags.ReplaceExistingApplication);

                    // sut
                    IProgressReporter progressReporter = new DefaultProgressReporter(Console.WriteLine);
                    progressReporter.ReportTestsStarted(TestConfig.AndroidTestsPackageName);
                    var testRunner = new AndroidTestRunner(logger, adbFactory, droidEmulator.Device, TestConfig.AndroidTestsPackageName, TestConfig.AndroidTestsInstrumentationClassPath);
                    var testResults = testRunner.RunTests();
                    Assert.That(testResults, Is.Not.Null);

                    progressReporter.ReportTests(testResults);
                    progressReporter.ReportTestsFinished(TestConfig.AndroidTestsPackageName);
                    return testResults;

                });

            }

        }
        public async void Can_Get_Devices()
        {
            var logger = new ConsoleLogger();
            Guid emuId = Guid.NewGuid();

            // Start an emulator.
            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            int consolePort = 5554;
            var emuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, false, emuId);

            using (IEmulator droidEmulator = emuFactory.GetEmulator())
            {
                await droidEmulator.Start(TestConfig.EmulatorStartupTimeout).ContinueWith((t) =>
                {
                    // sut
                    var adb = adbFactory.GetAndroidDebugBridge();
                    var devices = adb.GetDevices();

                    Assert.That(devices, Is.Not.Null);
                    Assert.That(devices.Length, Is.GreaterThanOrEqualTo(1));

                    var deviceFound = devices.Where(a => a.Port == consolePort).FirstOrDefault();
                    Assert.That(deviceFound, Is.Not.Null);

                    foreach (var item in devices)
                    {
                        Console.WriteLine("Device Name: {0}, Status: {1}", item.Name, item.Status);
                    }

                });


            }


        }
        public async void Can_Start_Emulator_If_Existing_Device_Using_Port_Then_It_Is_Reused_And_Killed_Afterwards_When_Single_Instance_Mode_ReuseExistingThenKill_Specified()
        {
            var logger = new ConsoleLogger();
            Guid emuId = Guid.NewGuid();

            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            int consolePort = 5554;
            var emuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, true, emuId, SingleInstanceMode.ReuseExistingThenKill);

            IEmulator droidEmulator = emuFactory.GetEmulator();
            await droidEmulator.Start(TestConfig.EmulatorStartupTimeout).ContinueWith((t) =>
            {

                var firstDevice = (AndroidDevice)droidEmulator.Device;

                // now try and start another one on same port.
                Guid secondEmuId = Guid.NewGuid();
                var secondEmuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, true, secondEmuId, SingleInstanceMode.ReuseExistingThenKill);

                IEmulator secondEmulator = secondEmuFactory.GetEmulator();
                secondEmulator.Start(TestConfig.EmulatorStartupTimeout).Wait();

                // now try and start another one on same port.
                AndroidDevice device = (AndroidDevice)secondEmulator.Device;

                Assert.That(device.FullName() == firstDevice.FullName());

                var adb = adbFactory.GetAndroidDebugBridge();

                // this should result in the device being killed.
                secondEmulator.Stop();

                Thread.Sleep(new TimeSpan(0, 0, 3)); // give time for device to be killed.

                // device should no longer be listed.
                var devices = adb.GetDevices();
                foreach (var d in devices)
                {
                    Assert.That(d.FullName() != firstDevice.FullName(), "device was still listed in adb devices after it was killed");
                }

                droidEmulator.Stop();
            });

        }
        public async void Can_Start_Emulator_If_Existing_Device_Using_Port_Then_It_Is_Reused_When_Single_Instance_Mode_ReuseExisting_Specified()
        {
            var logger = new ConsoleLogger();
            Guid emuId = Guid.NewGuid();

            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            int consolePort = 5554;
            var emuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, true, emuId, SingleInstanceMode.ReuseExisting);

            IEmulator droidEmulator = emuFactory.GetEmulator();
            await droidEmulator.Start(TestConfig.EmulatorStartupTimeout).ContinueWith((t) =>
            {
                // now try and start another one on same port.
                Guid secondEmuId = Guid.NewGuid();
                var secondEmuFactory = new AndroidSdkEmulatorFactory(logger, TestConfig.PathToAndroidEmulatorExe, adbFactory, TestConfig.AvdName, consolePort, true, true, secondEmuId, SingleInstanceMode.ReuseExisting);

                IEmulator secondEmulator = secondEmuFactory.GetEmulator();
                secondEmulator.Start(TestConfig.EmulatorStartupTimeout).Wait();

                // now try and start another one on same port.
                AndroidDevice device = (AndroidDevice)secondEmulator.Device;
                var adb = adbFactory.GetAndroidDebugBridge();

                // this second device should actually re-use the first device so should have device 1 emu id, not device 2.
                var secondId = device.QueryId(adb);
                Assert.That(Guid.Parse(secondId) != secondEmuId);

                secondEmulator.Stop();
                droidEmulator.Stop();
            });

        }
        public void Can_Restart()
        {                     
            var adbFactory = new AndroidDebugBridgeFactory(TestConfig.PathToAdbExe);
            var adb = adbFactory.GetAndroidDebugBridge();
            adb.RestartServer();

        }