public override Task<Results> Run ()
		{
			string zoneName;
			bool shouldCache;
			if (!TryGetString ("zoneName", out zoneName) || !TryGetBool ("cache", out shouldCache))
				throw new InvalidProgramException ();

			var zoneId = new CKRecordZoneID (zoneName, CKContainer.OwnerDefaultName);
			ChangedRecords cache;
			if (!recordCache.TryGetValue (zoneId, out cache))
				recordCache [zoneId] = cache = new ChangedRecords ();

			cache.RemoveChanges ();

			if (!cache.Results.MoreComing && !shouldCache)
				cache.Reset ();

			CKServerChangeToken changeToken = null;

			var token = cache.ChangeToken;
			if (token != null && (shouldCache || cache.Results.MoreComing))
				changeToken = token;

			// TODO: https://bugzilla.xamarin.com/show_bug.cgi?id=42163
			//var operation = new CKFetchRecordChangesOperation (zoneId, changeToken);
			var operation = CKFetchRecordChangesOperationFactory.GetOperation (zoneId, changeToken);

			operation.DesiredKeys = new string [] { "name", "location" };
			operation.ResultsLimit = 2;
			operation.RecordChanged = (record) => {
				CKRecord cachedRecord = cache.GetRecordById (record.Id);
				if (cachedRecord != null) {
					foreach (var key in record.AllKeys ())
						cachedRecord [key] = record [key];
					cache.MarkRecordAsModified (cachedRecord);
				} else {
					cache.AddRecord (record);
				}
			};

			operation.RecordDeleted = cache.MarkRecordAsDeleted;

			var tcs = new TaskCompletionSource<Results> ();
			operation.AllChangesReported = (chToken, nsData, nsError) => {
				if (nsError == null) {
					cache.ChangeToken = chToken;
					cache.SetMoreComing (operation.MoreComing);
				}
				tcs.SetResult (cache.GetRecords ());
			};

			operation.Start ();
			return tcs.Task;
		}
        public override Task <Results> Run()
        {
            string zoneName;
            bool   shouldCache;

            if (!TryGetString("zoneName", out zoneName) || !TryGetBool("cache", out shouldCache))
            {
                throw new InvalidProgramException();
            }

            var            zoneId = new CKRecordZoneID(zoneName, CKContainer.OwnerDefaultName);
            ChangedRecords cache;

            if (!recordCache.TryGetValue(zoneId, out cache))
            {
                recordCache [zoneId] = cache = new ChangedRecords();
            }

            cache.RemoveChanges();

            if (!cache.Results.MoreComing && !shouldCache)
            {
                cache.Reset();
            }

            CKServerChangeToken changeToken = null;

            var token = cache.ChangeToken;

            if (token != null && (shouldCache || cache.Results.MoreComing))
            {
                changeToken = token;
            }

            // TODO: https://bugzilla.xamarin.com/show_bug.cgi?id=42163
            //var operation = new CKFetchRecordChangesOperation (zoneId, changeToken);
            var operation = CKFetchRecordChangesOperationFactory.GetOperation(zoneId, changeToken);

            operation.DesiredKeys   = new string [] { "name", "location" };
            operation.ResultsLimit  = 2;
            operation.RecordChanged = (record) => {
                CKRecord cachedRecord = cache.GetRecordById(record.Id);
                if (cachedRecord != null)
                {
                    foreach (var key in record.AllKeys())
                    {
                        cachedRecord [key] = record [key];
                    }
                    cache.MarkRecordAsModified(cachedRecord);
                }
                else
                {
                    cache.AddRecord(record);
                }
            };

            operation.RecordDeleted = cache.MarkRecordAsDeleted;

            var tcs = new TaskCompletionSource <Results> ();

            operation.AllChangesReported = (chToken, nsData, nsError) => {
                if (nsError == null)
                {
                    cache.ChangeToken = chToken;
                    cache.SetMoreComing(operation.MoreComing);
                }
                tcs.SetResult(cache.GetRecords());
            };

            operation.Start();
            return(tcs.Task);
        }