async Task <bool> LoadRemoteOrLocalData()
        {
            this.IsBusy = true;
            try
            {
                bool RemoteDataLoaded = false;
                try
                {
                    // Useful for demonstrating that a failure will load the last copy
                    // throw new Exception("Testing failure");

                    // Load the customers from the net if available
                    var restClient        = new CustomersRestClient();
                    var customersOnServer = await restClient.GetCustomers();

                    await App.DataManager.SetupDatabaseAsync();

                    await App.DataManager.UpdateCustomersAsync(customersOnServer);

                    RemoteDataLoaded = true;
                }
                catch (Exception ex)
                {
                    // We don't have the access, we need to use the local copy
                    RemoteDataLoaded = false;
                }

                // Load the local copy of the classes
                var localCustomers = await App.DataManager.GetCustomersAsync();

                customers.Clear();

                foreach (var c in localCustomers)
                {
                    customers.Add(c);
                }

                return(RemoteDataLoaded);
            } finally
            {
                this.IsBusy = false;
            }
        }
        public ConflictDetailsPage(SyncResult <Customer> items)
        {
            Title = "Tap to overwrite";

            var listView = new ListView {
                ItemsSource  = items.Conflicts,
                ItemTemplate = new DataTemplate(typeof(CustomerConflictInfoCell))
            };

            listView.ItemSelected += async(s, e) => {
                var item = e.SelectedItem as ConflictItem <Customer>;

                List <Customer> customers = new List <Customer>();
                customers.Add(item.RequestedUpdateItem);

                // Force the change to the server and then remove the item
                CustomersRestClient client = new CustomersRestClient();
                var response = await client.SyncData(customers, true);
            };

            Content = listView;
        }
        public async Task PerformTheSync()
        {
            this.IsBusy = true;
            try
            {
                DisplayProcessing("Synchronizing...");

                // Get the items that should be synced. Push them to the server
                DateTime syncDate = DateTime.UtcNow;

                var items = await App.DataManager.GetSyncableCustomersAsync();

                // Don't do anything if we don't need to
                if (items.Count == 0)
                {
                    DisplayResults();
                    return;
                }

                // Push the changes to the server to see what should be changed
                CustomersRestClient client = new CustomersRestClient();

                SyncResult <Customer> syncResult = null;
                bool couldSync;
                try
                {
                    syncResult = await client.SyncData(items);

                    couldSync = true;
                }
                catch (Exception ex)
                {
                    couldSync = false;
                }

                if (!couldSync)
                {
                    // We have an issue connecting to the service
                    await DisplayAlert("Could not sync", "Check your network connection and try again",
                                       "OK", "Cancel");

                    return;
                }

                // Check to see if there are any conflicts and if there are present them
                switch (syncResult.Status)
                {
                case SyncStatus.Success:
                    await App.DataManager.UpdateSyncDateTimeAsync(syncDate);

                    await App.DataManager.UpdateCorrelationIds(syncResult.CorrelationIds);

                    await App.DataManager.UpdateVersionHistory(syncResult.VersionChanges);

                    await App.DataManager.DeleteCustomers(syncResult.DeletedRecords);

                    await DisplayAlert("Sync", "The Customer Sync executed correctly", "OK");

                    break;

                case SyncStatus.PartialSuccessWithConflict:
                    // TODO: Update the correlation Identifiers on the site
                    await App.DataManager.UpdateSyncDateTimeAsync(syncDate);

                    await App.DataManager.UpdateCorrelationIds(syncResult.CorrelationIds);

                    await App.DataManager.UpdateVersionHistory(syncResult.VersionChanges);

                    await App.DataManager.DeleteCustomers(syncResult.DeletedRecords);

                    var details = await DisplayAlert("Sync Conflict", "You have sync conflicts. Do you want to force the changes?", "OK", "Cancel");

                    if (details)
                    {
                        try
                        {
                            await client.SyncData(items, true);
                            await DisplayAlert("Sync Conflict", "The Sync has been applied", "Close");
                        }
                        catch (Exception ex)
                        {
                            await DisplayAlert("Sync Conflict", "Could not process: " + ex.Message, "Close");
                        }
                    }
                    break;

                case SyncStatus.Failed:
                    await DisplayAlert("Sync", "The Customer Sync failed", "OK");

                    break;
                }

                await LoadRemoteOrLocalData();

                DisplayResults();
            } finally
            {
                this.IsBusy = false;
            }
        }