void OnDownloadCompleted(object sender, NSUrlEventArgs e)
        {
            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.ResourceVersion = headers["resourceversion"].ToString();

                            _behaviors.SaveUserSession();

                            IIOContext io = IOContext.Current;
                            if (io.Exists(_filePath))
                            {
                                FileStream fileStream = io.FileStream(_filePath, FileMode.Open);

                                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);

                                // CreateInstance the SyncReader
                                if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled)
                                    _syncReader = new ODataAtomReader(responseStream, _knownTypes);
                                else
                                    _syncReader = new BMReader(responseStream, _knownTypes);

                                _wrapper.DownloadResponse = new ChangeSet();
                                _wrapper.DownloadResponse.Data = GetDownloadedValues(_wrapper);

                            }
                            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
                {
                    var 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);
            }
        }
        /// <summary>
        /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to
        /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that.
        /// </summary>
        /// <param name="asyncResult">IAsyncResult object</param>
        void OnDownloadGetResponseCompleted(IAsyncResult asyncResult)
        {
            AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper;

            wrapper.DownloadResponse = new ChangeSet();

            HttpWebResponse response = null;
            try
            {
                try
                {
                    response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse;
                    if (String.IsNullOrEmpty(behaviors.UserId))
                        behaviors.UserId = response.Headers["userid"];
                    if (string.IsNullOrWhiteSpace(behaviors.UserEmail))
                        behaviors.UserEmail = response.Headers["email"];
                    behaviors.ResourceVersion = response.Headers["resourceversion"];
                }
                catch (WebException we)
                {
                    wrapper.Error = we;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }
                catch (SecurityException se)
                {
                    wrapper.Error = se;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    behaviors.SaveUserSession();

                    int contentLength = (int)response.ContentLength;

                    if (response.Headers.AllKeys.Contains("unzippedcontentlength"))
                    {
                        string value = response.Headers["unzippedcontentlength"];
                        if (!int.TryParse(value, out contentLength))
                            throw new WebException("Invalid value of header unzippedcontentlength: " + value);
                    }
                    
                    Stream responseStream = new ProgressStream(response.GetResponseStream()
                    , contentLength
                    , behaviors.ReadProgressCallback);

                    // CreateInstance the SyncReader
                    if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled)
                        _syncReader = new ODataAtomReader(responseStream, _knownTypes);
                    else
                        _syncReader = new BMReader(responseStream, _knownTypes);

                    // Read the response
                    wrapper.DownloadResponse.Data = GetDownloadedValues(wrapper);

                    wrapper.WebResponse = response;
                    // Invoke user code on the correct synchronization context.
                    this.FirePostResponseHandler(wrapper);
                }
                else
                {
                    wrapper.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                       response.StatusCode,
                                       response.StatusDescription));
                }

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

                wrapper.Error = e;
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
        }
		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);
				}
			}
		}