void OnDownloadCompleted (object sender, NSUrlEventArgs e)
		{
			FileStream fileStream = null;
			string filePath = null;

			try {
				if (e.Error == null) {
					filePath = e.FilePath.Replace ("file://", "").Replace ("%20", " ");

					NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response;
					if (response != null) {

						HttpStatusCode code = (HttpStatusCode)response.StatusCode; 
						if (code == HttpStatusCode.OK) {

							NSDictionary headers = response.AllHeaderFields;
							if (string.IsNullOrWhiteSpace (_behaviors.UserId))
								_behaviors.UserId = headers ["userid"].ToString ();
							if (string.IsNullOrWhiteSpace (_behaviors.UserEmail))
								_behaviors.UserEmail = headers ["email"].ToString ();
							;
							_behaviors.SaveUserSession ();

							if (File.Exists (filePath)) {
								fileStream = File.OpenRead (filePath);

								fileStream.Seek (0, SeekOrigin.Begin);
								int contentLength;
								if (!int.TryParse (headers ["unzippedcontentlength"].ToString (), out contentLength))
									contentLength = -1;					
								Stream responseStream = new ProgressStream (fileStream, contentLength, _behaviors.ReadProgressCallback);

								// Create the SyncReader
								_syncReader = (SyncReader)new ODataAtomReader (responseStream, _knownTypes);

								_wrapper.DownloadResponse = new ChangeSet ();

								// Read the response
								while (this._syncReader.Next ()) {
									switch (this._syncReader.ItemType) {
									case ReaderItemType.Entry:
										_wrapper.DownloadResponse.AddItem (_syncReader.GetItem ());
										break;
									case ReaderItemType.SyncBlob:
										_wrapper.DownloadResponse.ServerBlob = _syncReader.GetServerBlob ();
										break;
									case ReaderItemType.HasMoreChanges:
										_wrapper.DownloadResponse.IsLastBatch = !_syncReader.GetHasMoreChangesValue ();
										break;
									}
								}	
							} else {
								_wrapper.Error = new FileNotFoundException (String.Format ("Downloaded data file not found! {0}, Description: {1}", e.FilePath, response.Description));
							}
						} else
							_wrapper.Error = new CacheControllerWebException (string.Format ("Remote service returned error status. Status: {0}, Description: {1}", code, response.Description), code);
					} else
						_wrapper.Error = new CacheControllerException ("Response is null");
				} else {
					NSHttpUrlResponse response = _currentTask.Response as NSHttpUrlResponse;
					HandleError (e.Error, response);
				}

				// If we get here then it means we completed the request. Return to the original caller
				_workerManager.CompleteWorkRequest (_wrapper.WorkerRequest, _wrapper);
			
			} catch (Exception ex) {
				if (ExceptionUtility.IsFatal (ex)) {
					throw;
				}

				_wrapper.Error = ex;

				_workerManager.CompleteWorkRequest (_wrapper.WorkerRequest, _wrapper);
			} finally {
				if (fileStream != null) {
					fileStream.Close ();
				}

				if (filePath != null && File.Exists (filePath)) {
					File.Delete (filePath);
				}
			}
		}
		void OnUploadCompleted (object sender, NSUrlEventArgs e)
		{
			_wrapper.UploadResponse = new ChangeSetResponse ();

			FileStream fileStream = null;

			string filePath = null;

			try {
				if (e.Error == null) {
					string responseDescription = "response is  null";
					NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response;
				if (response != null)
						responseDescription = response.Description;

					filePath = e.FilePath.Replace ("file://", "").Replace ("%20", " ");
					if (File.Exists (filePath)) {
						fileStream = File.OpenRead (filePath);
						fileStream.Seek (0, SeekOrigin.Begin);

						// Create the SyncReader
						_syncReader = (SyncReader)new ODataAtomReader (fileStream, _knownTypes);

						// Read the response
						while (_syncReader.Next ()) {
							switch (_syncReader.ItemType) {
							case ReaderItemType.Entry:                                
								IOfflineEntity entity = _syncReader.GetItem ();
								IOfflineEntity ackedEntity = entity;                                
								string tempId = null;

								if (_syncReader.HasTempId () && _syncReader.HasConflictTempId ()) {
									throw new CacheControllerException (string.Format ("Service returned a TempId '{0}' in both live and conflicting entities.", 
										_syncReader.GetTempId ()));
								}

								if (_syncReader.HasTempId ()) {
									tempId = _syncReader.GetTempId ();
									CheckEntityServiceMetadataAndTempIds (entity, tempId);
								}

								if (_syncReader.HasConflict ()) {                                    
									Conflict conflict = _syncReader.GetConflict ();
									IOfflineEntity conflictEntity = (conflict is SyncConflict) ? 
									                                ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity;

									if (this._syncReader.HasConflictTempId ()) {
										tempId = _syncReader.GetConflictTempId ();
										CheckEntityServiceMetadataAndTempIds (conflictEntity, tempId);
									}
									                           
									_wrapper.UploadResponse.AddConflict (conflict);

									if (_syncReader.HasConflictTempId () && entity.ServiceMetadata.IsTombstone) {                                        
										conflictEntity.ServiceMetadata.IsTombstone = true;
										ackedEntity = conflictEntity;
									}
								}

								if (!String.IsNullOrEmpty (tempId)) {
									_wrapper.UploadResponse.AddUpdatedItem (ackedEntity);
								}
								                       
								break;

							case ReaderItemType.SyncBlob:
								_wrapper.UploadResponse.ServerBlob = _syncReader.GetServerBlob ();
								break;
							}
						}

						if (_wrapper.TempIdToEntityMapping != null && _wrapper.TempIdToEntityMapping.Count != 0) {
							StringBuilder builder = new StringBuilder ("Server did not acknowledge with a permanent Id for the following tempId's: ");
							builder.Append (string.Join (",", _wrapper.TempIdToEntityMapping.Keys.ToArray ()));
							throw new CacheControllerException (builder.ToString ());
						}
					} else
						_wrapper.Error = new FileNotFoundException (String.Format ("Downloaded data file not found! {0}, Description: {1}", e.FilePath, responseDescription));
				} else
				{
					NSHttpUrlResponse response = _currentTask.Response as NSHttpUrlResponse;
					HandleError (e.Error, response);
				}

				_workerManager.CompleteWorkRequest (_wrapper.WorkerRequest, _wrapper);
			} catch (Exception ex) {
				if (ExceptionUtility.IsFatal (ex)) {
					throw ex;
				}

				_wrapper.Error = ex;

				_workerManager.CompleteWorkRequest (_wrapper.WorkerRequest, _wrapper);
			} finally {
				if (fileStream != null) {
					fileStream.Close ();
				}

				if (filePath != null && File.Exists (filePath)) {
					File.Delete (filePath);
				}
			}
		}