/// <summary>
        /// Sets the default startup app asynchronously.
        /// </summary>
        /// <param name="app">The package that shall run on the device's startup</param>
        /// <remarks>This operation occurs in two steps: 1) Setting the app via the app's name and verification if the app was set as startup app.</remarks>
        /// <exception cref="Exception">The startup setting could not be verified, but it maybe functional.</exception>
        /// <exception cref="Exception">The server response could not be parsed, but maybe the request was successful.</exception>
        public async Task SetDefaultStartupAppAsync(AppxPackage app)
        {
            // converts the appId to UFT8 Base64 encoded string of the string-bytes
            string appId = Convert.ToBase64String(Encoding.UTF8.GetBytes(app.PackageRelativeId));

            // request set the startup app
            HttpResponseMessage httpResponseMessage = await this.AuthenticatedApiRequestAsync(this.targetBaseUri + "/api/iot/appx/default?appid=" + appId, HttpMethod.POST, false, new StringContent(""));

            httpResponseMessage.EnsureSuccessStatusCode();

            // test if the app is now really set as startup
            httpResponseMessage = await this.AuthenticatedApiRequestAsync(this.targetBaseUri + "/api/iot/appx/default", HttpMethod.GET, false);

            httpResponseMessage.EnsureSuccessStatusCode();
            JObject requestResultJsonObject = JObject.Parse(await httpResponseMessage.Content.ReadAsStringAsync());
            JToken  appStartupInfo;
            bool    isStartup = false;

            try
            {
                appStartupInfo = requestResultJsonObject["AppPackages"]
                                 .Where(appx => appx["PackageFullName"].ToString() // the property field "PackageFullName" seems to be a mistake, it should be PackageRelativeId. See https://social.msdn.microsoft.com/Forums/en-US/8984391b-da0a-4882-bf05-72f5fff90e0f/msiot-api-default-app-returns-wrong-property-name?forum=WindowsIoT
                                        .Contains(app.PackageRelativeId))
                                 .FirstOrDefault();
                isStartup = Convert.ToBoolean(appStartupInfo["IsStartup"]);
            }
            catch
            {
                throw new Exception("MsIotApiWrapper.SetDefaultStartupAppAsync: The server's response does not contain information about the desired startupp app.");
            }
            if (appStartupInfo == null || !isStartup)
            {
                throw new Exception("MsIotApiWrapper.SetDefaultStartupAppAsync: Could not verify that " + app.PackageRelativeId + " was set as the target's startup app.");
            }
        }
        /// <summary>
        /// Gets a list of the installed packages on the target asynchronously.
        /// </summary>
        /// <returns>Returns a List of installed <see cref="AppxPackage"/>s</returns>
        /// <exception cref="Exception">The installed packages could not be queried.</exception>
        public async Task <List <AppxPackage> > GetInstalledAppsAsync()
        {
            List <AppxPackage>  packageList         = new List <AppxPackage>();
            HttpResponseMessage httpResponseMessage = await this.AuthenticatedApiRequestAsync(this.targetBaseUri + "/api/appx/packagemanager/packages", HttpMethod.GET, false);

            httpResponseMessage.EnsureSuccessStatusCode();
            JObject requestResultJsonObject = JObject.Parse(await httpResponseMessage.Content.ReadAsStringAsync());
            JToken  installedPackages       = requestResultJsonObject["InstalledPackages"];

            if (installedPackages == null)
            {
                throw new Exception("MsIotApiWrapper.GetInstalledAppsAsync: Unable to query for \"InstalledPackages\" on the target.");
            }
            // todo : test ob vorhanden
            foreach (JToken installedPackage in installedPackages)
            {
                try
                {
                    AppxPackage AppxPackage = new AppxPackage
                    {
                        PackageFullName   = installedPackage["PackageFullName"].ToString(),
                        PackageName       = installedPackage["Name"].ToString(),
                        PackageRelativeId = installedPackage["PackageRelativeId"].ToString(),
                        CanUninstall      = Convert.ToBoolean(installedPackage["CanUninstall"].ToString())
                    };
                    packageList.Add(AppxPackage);
                }
                catch
                {
                    continue;
                }
            }
            return(packageList);
        }
        /// <summary>
        /// Removes a package from the target asynchronously.
        /// </summary>
        /// <param name="appxPackage">The package to remove.</param>
        /// <exception cref="Exception">The provided package is marked as uninstallable.</exception>
        public async Task RemoveAppxPackageFromTargetAsync(AppxPackage appxPackage)
        {
            if (!appxPackage.CanUninstall)
            {
                throw new Exception("MsIotApiWrapper.RemoveAppxPackageFromTarget: Package " + appxPackage.PackageName + " is marked as non-removable on the target.");
            }
            HttpResponseMessage httpResponseMessage = await this.AuthenticatedApiRequestAsync(this.targetBaseUri + "/api/appx/packagemanager/package?package=" + appxPackage.PackageFullName, HttpMethod.DELETE, false);

            httpResponseMessage.EnsureSuccessStatusCode();
        }
        /// <summary>
        /// The synchronous version of <see cref="SetDefaultStartupAppAsync(AppxPackage)"/>
        /// </summary>
        public void SetDefaultStartupApp(AppxPackage app)
        {
            Task setDefaultStartupAppTask = Task.Run(async() => await this.SetDefaultStartupAppAsync(app));

            Task.WaitAll(setDefaultStartupAppTask);
        }
        /// <summary>
        /// The synchronous version of <see cref="RemoveAppxPackageFromTargetAsync(AppxPackage)"/>
        /// </summary>
        public void RemoveAppxPackageFromTarget(AppxPackage appxPackage)
        {
            Task removeAppxPackageFromTargetTask = Task.Run(async() => await this.RemoveAppxPackageFromTargetAsync(appxPackage));

            Task.WaitAll(removeAppxPackageFromTargetTask);
        }