protected async void HandleRegistration(Context context, Intent intent)
		{
			string registrationId = intent.GetStringExtra("registration_id");
			string error = intent.GetStringExtra("error");
			string unregistration = intent.GetStringExtra("unregistered");

			var nMgr = (NotificationManager)GetSystemService (NotificationService);

			if (!String.IsNullOrEmpty (registrationId)) {
				NativeRegistration = await Hub.RegisterNativeAsync (registrationId, new[] {"Native"});

				var notificationNativeRegistration = new Notification (Resource.Drawable.Icon, "Native Registered");
				var pendingIntentNativeRegistration = PendingIntent.GetActivity (this, 0, new Intent (this, typeof(MainActivity)), 0);
				notificationNativeRegistration.SetLatestEventInfo (this, "Native Reg.-ID", NativeRegistration.RegistrationId, pendingIntentNativeRegistration);
				nMgr.Notify (_messageId, notificationNativeRegistration);
				_messageId++;
			}
			else if (!String.IsNullOrEmpty (error)) {
				var notification = new Notification (Resource.Drawable.Icon, "Gcm Registration Failed.");
				var pendingIntent = PendingIntent.GetActivity (this, 0, new Intent (this, typeof(MainActivity)), 0);
				notification.SetLatestEventInfo (this, "Gcm Registration Failed", error, pendingIntent);
				nMgr.Notify (_messageId, notification);
				_messageId++;
			}
			else if (!String.IsNullOrEmpty (unregistration)) {
				if (NativeRegistration != null)
					await Hub.UnregisterAsync (NativeRegistration);

				var notification = new Notification (Resource.Drawable.Icon, "Unregistered successfully.");
				var pendingIntent = PendingIntent.GetActivity (this, 0, new Intent (this, typeof(MainActivity)), 0);
				notification.SetLatestEventInfo (this, "MyIntentService", "Unregistered successfully.", pendingIntent);
				nMgr.Notify (_messageId, notification);
				_messageId++;
			}
		}
		private void ProcessXmlRegistration(Registration registration, XmlDocument registrationXml)
		{
			DateTime dateTime;

			registration.Raw = registrationXml.OuterXml;

            var nodes = registrationXml.GetElementsByTagName("ETag");
			if (nodes.Count > 0) registration.ETag = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("published");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.PublishedAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("updated");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.UpdatedAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("ExpirationTime");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.ExpiresAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("RegistrationId");
			if (nodes.Count > 0) registration.RegistrationId = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("Tags");
			registration.Tags = nodes.Count > 0 ? nodes[0].InnerText.Split(',') : null;

			nodes = registrationXml.GetElementsByTagName("BodyTemplate");
			registration.BodyTemplate = nodes.Count > 0 ? nodes[0].InnerText : null;

			nodes = registrationXml.GetElementsByTagName("TemplateName");
			registration.TemplateName = nodes.Count > 0 ? nodes[0].InnerText : null;
		}
		public async override void RegisteredForRemoteNotifications (UIApplication application, NSData deviceToken)
		{
			try {
				NativeRegistration = await Hub.RegisterNativeAsync(deviceToken);
				new UIAlertView("Notification Hub Registration", "Registration ID: " + NativeRegistration.RegistrationId, null, "OK", null).Show();
			} catch (Exception ex) {
				new UIAlertView("Error registering push notifications", ex.Message, null, "OK", null).Show();
			}
		}
		public void StoreRegistrationToLocal(Registration registration)
		{
			var registrationsPath = System.IO.Path.Combine (Environment.CurrentDirectory, 
			                                                "NotificationHubs", 
			                                                _endpoint.Replace ("https://", ""),
			                                                Path);
			if (!Directory.Exists (registrationsPath))
				Directory.CreateDirectory (registrationsPath);
			var filename = System.IO.Path.Combine(registrationsPath, 
			    String.IsNullOrEmpty(registration.TemplateName)
					? "$native.xml"
					: registration.TemplateName + ".xml");

			using (TextWriter writer = new StreamWriter(filename)) {
				var serializer = new XmlSerializer(typeof(Registration));
				serializer.Serialize(writer, registration);
			}
		}
		private void ProcessXmlRegistration(Registration registration, XmlDocument registrationXml)
		{
			DateTime dateTime;
			double expiry;

			registration.Raw = registrationXml.OuterXml;

			var nodes = registrationXml.GetElementsByTagName("DeviceToken");
			if (nodes.Count > 0) registration.PnsToken = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("ETag");
			if (nodes.Count > 0) registration.ETag = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("published");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.PublishedAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("updated");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.UpdatedAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("ExpirationTime");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.ExpiresAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("RegistrationId");
			if (nodes.Count > 0) registration.RegistrationId = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("Tags");
			registration.Tags = nodes.Count > 0 ? nodes[0].InnerText.Split(',') : new string[0];

			nodes = registrationXml.GetElementsByTagName("BodyTemplate");
			registration.BodyTemplate = nodes.Count > 0 ? nodes[0].InnerText : null;

			nodes = registrationXml.GetElementsByTagName("TemplateName");
			registration.TemplateName = nodes.Count > 0 ? nodes[0].InnerText : null;

			nodes = registrationXml.GetElementsByTagName("Expiry");
			if (nodes.Count > 0 && double.TryParse(nodes[0].InnerText, out expiry))
				registration.ApnsExpiry = TimeSpan.FromSeconds(expiry);
			else
				registration.ApnsExpiry = null;
		}
		private async Task<Registration> UpdateRegistration(Registration registration)
		{
			try
			{
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentNullException("registration");
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentException("RegistrationId missing.", "registration");

				var registrationPayload = BuildCreatePayload(registration);
				var serverUrl = _endpoint + '/' + Path + "/registrations/" + registration.RegistrationId + "?api-version=2013-04";
				Debug.WriteLine("Updating Registration (" + registration.RegistrationId + ") ...");
				Debug.WriteLine("url:" + serverUrl);
				Debug.WriteLine("payload:" + registrationPayload);

				var registrationXml = new XmlDocument();
				//string location;
				using (var client = new WebClient())
				{
					AddWebClientHeaders(client, serverUrl);
					client.Headers.Add("If-Match", String.IsNullOrEmpty(registration.ETag) ? "*" : registration.ETag);
					var result = await client.UploadStringTaskAsync(serverUrl, "PUT", registrationPayload);
					Debug.WriteLine("registration result:" + result);
					registrationXml.LoadXml(result);
					//location = client.ResponseHeaders["Content-Location"];
				}

				ProcessXmlRegistration(registration, registrationXml);

				return registration;
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex.Message);
				throw;
			}
		}
		private async Task<Registration> ReadRegistration(Registration registration)
		{
			try
			{
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentNullException("registration");
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentException("RegistrationId missing.", "registration");

				var serverUrl = _endpoint + '/' + Path + "/registrations/" + registration.RegistrationId + "?api-version=2013-04";
				Debug.WriteLine("Reading Registration (" + registration.RegistrationId + ") ...");
				Debug.WriteLine("url:" + serverUrl);

				var registrationXml = new XmlDocument();
				using (var client = new WebClient())
				{
					AddWebClientHeaders(client, serverUrl);
					var result = await client.DownloadStringTaskAsync(serverUrl);
					Debug.WriteLine("registration result:" + result);
					registrationXml.LoadXml(result);
				}

				ProcessXmlRegistration(registration, registrationXml);

				return registration;
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex.Message);
				throw;
			}
		}
		private async Task<Registration> CreateRegistration(Registration registration)
		{
			try
			{
				if (registration == null)
					throw new ArgumentNullException("registration");

				var registrationPayload = BuildCreatePayload(registration);
				var serverUrl = _endpoint + '/' + Path + "/registrations?api-version=2013-04";
				Debug.WriteLine("Creating Registration...");
				Debug.WriteLine("url:" + serverUrl);
				Debug.WriteLine("payload:" + registrationPayload);

				var registrationXml = new XmlDocument();
				//string location;

				using (var client = new WebClient())
				{
					AddWebClientHeaders(client, serverUrl);
					var result = await client.UploadStringTaskAsync(serverUrl, "POST", registrationPayload);
					Debug.WriteLine("registration result:" + result);
					registrationXml.LoadXml(result);
					//location = client.ResponseHeaders["Content-Location"];
				}

				ProcessXmlRegistration(registration, registrationXml);

				return registration;
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex.Message);
				throw;
			}
		}
		private List<Registration> ProcessXmlRegistrations(string pnsToken, XmlDocument registrationsXml)
		{
			var registrations = new List<Registration>();

			var registrationXml = new XmlDocument();
			foreach (XmlNode entry in registrationsXml.GetElementsByTagName("entry"))
			{
				var registration = new Registration(pnsToken, Path);
				registrationXml.LoadXml(entry.OuterXml);
				ProcessXmlRegistration(registration, registrationXml);
				registrations.Add(registration);
			}

			return registrations;
		}
		private void ProcessXmlRegistration(Registration registration, XmlDocument registrationXml)
		{
			/*
            <entry a:etag="W/&quot;1&quot;" xmlns="http://www.w3.org/2005/Atom" xmlns:a="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
                <id>https://blogdemo.servicebus.windows.net/myhub/registrations/3750328172024393254-9075900229351105338?api-version=2013-04</id>
                <title type="text">3750328172024393254-9075900229351105338</title>
                <published>2013-07-11T13:26:57Z</published>
                <updated>2013-07-11T13:26:57Z</updated>
                <link rel="self" href="https://blogdemo.servicebus.windows.net/myhub/registrations/3750328172024393254-9075900229351105338?api-version=2013-04" />
                <content type="application/xml">
                    <WindowsRegistrationDescription xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                        <ETag>1</ETag>
                        <ExpirationTime>2013-10-09T13:26:57.704Z</ExpirationTime>
                        <RegistrationId>3750328172024393254-9075900229351105338</RegistrationId>
                        <ChannelUri>https://db3.notify.windows.com/?token=AgYAAAAMPgO7SXlTLbPKhpM34G%2beIqsZJYuT4pylZiloHUm3%2fVnWxotWlMdOLUhiHPeckuYZ6EAGDuQ2gznwsfkXLSUFSuzO3R1HmUuyy48PH%2f6yQoWUNc8zWIJaey0Cytef6p4%3d</ChannelUri>
                    </WindowsRegistrationDescription>
                </content>
            </entry>
             * 
            <entry a:etag="W/&quot;1&quot;" xmlns:a="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
                <id>https://blogdemo.servicebus.windows.net/myhub/tags/Both/registrations/280030996932335216-2707426160592076072?api-version=2013-04</id>
                <title type="text">280030996932335216-2707426160592076072</title>
                <published>2013-07-17T09:59:51Z</published>
                <updated>2013-07-17T09:59:51Z</updated>
                <link rel="self" href="https://blogdemo.servicebus.windows.net/myhub/tags/Both/registrations/280030996932335216-2707426160592076072?api-version=2013-04" />
                <content type="application/xml">
                    <AppleRegistrationDescription xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                    <ETag>1</ETag>
                    <ExpirationTime>2013-10-14T11:36:35.805Z</ExpirationTime>
                    <RegistrationId>280030996932335216-2707426160592076072</RegistrationId>
                    <Tags>Both,Toast</Tags>
                    <DeviceToken>0D5066BE84F13FE7D1A935A9922C9BCA0890C9FDF57DDD1DB4FD8642331184C2</DeviceToken>
                    </AppleRegistrationDescription></content>
             </entry> 
            */
			DateTime dateTime;

			registration.Raw = registrationXml.OuterXml;

			var nodes = registrationXml.GetElementsByTagName("GcmRegistrationId");
			if (nodes.Count > 0) registration.PnsToken = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("ETag");
			if (nodes.Count > 0) registration.ETag = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("published");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.PublishedAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("updated");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.UpdatedAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("ExpirationTime");
			if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
				registration.ExpiresAt = dateTime;

			nodes = registrationXml.GetElementsByTagName("RegistrationId");
			if (nodes.Count > 0) registration.RegistrationId = nodes[0].InnerText;

			nodes = registrationXml.GetElementsByTagName("Tags");
			registration.Tags = nodes.Count > 0 ? nodes[0].InnerText.Split(',') : null;

			nodes = registrationXml.GetElementsByTagName("BodyTemplate");
			registration.BodyTemplate = nodes.Count > 0 ? nodes[0].InnerText : null;

			nodes = registrationXml.GetElementsByTagName("TemplateName");
			registration.TemplateName = nodes.Count > 0 ? nodes[0].InnerText : null;
		}
		private string BuildCreatePayload(Registration registration)
		{
			string registrationPayload;

			var tagstring = String.Empty;
			if (registration.Tags != null)
			{
				tagstring = "<Tags>" + String.Join(",", registration.Tags) + "</Tags>";
			}

			if (!String.IsNullOrEmpty(registration.BodyTemplate))
			{
				registrationPayload = String.Format(
					ApnsTemplateCreate,
					tagstring,
					registration.PnsToken,
					registration.BodyTemplate,
					registration.TemplateName,
					registration.ApnsExpiry.HasValue
						? "<Expiry>" + registration.ApnsExpiry.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture) + "</Expiry>"
						: "");
			}
			else // native
			{
				registrationPayload = String.Format(
					ApnsNativeCreate,
					tagstring,
					registration.PnsToken);
			}

			return registrationPayload;
		}
 public Task <Registration> RegisterAsync(Registration registration)
 {
     return(Register(registration));
 }
 public Task <Registration> GetRegistrationAsync(Registration registration)
 {
     return(ReadRegistration(registration));
 }
		private string BuildCreatePayload(Registration registration)
		{
			return String.Empty;
		}
		private async Task DeleteRegistration(Registration registration)
		{
			try
			{
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentNullException("registration");
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentException("RegistrationId missing.", "registration");

				var serverUrl = _endpoint + '/' + Path + "/registrations/" + registration.RegistrationId + "?api-version=2013-04";
				Debug.WriteLine("url:" + serverUrl);

				using (var client = new WebClient())
				{
					AddWebClientHeaders(client, serverUrl);
					client.Headers.Add(
						"If-Match",
						String.IsNullOrEmpty(registration.ETag) ? "*" : registration.ETag);
					await client.UploadStringTaskAsync(serverUrl, "DELETE", "");
				}
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex.Message);
				throw;
			}
		}
		public Task<Registration> RegisterAsync(Registration registration)
		{
			return Register(registration);
		}
		public Task UnregisterAsync(Registration registration)
		{
			try
			{
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentNullException("registration");
				if (String.IsNullOrEmpty(registration.RegistrationId))
					throw new ArgumentException("RegistrationId missing.", "registration");

				registration.ETag = "*";
				return DeleteRegistration(registration);
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex.Message);
				throw;
			}
		}
		public Task<Registration> GetRegistrationAsync(Registration registration)
		{
			return ReadRegistration(registration);
		}
		private async Task<Registration> Register(Registration registration)
		{
			var localRegistration = LoadRegistrationFromLocal(registration.TemplateName);
			var forceCreate = false;

			if (localRegistration != null) {
				try {
					localRegistration.ETag = "*";
					registration = await UpdateRegistration (localRegistration);
				} catch (WebException ex) {
					if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
						forceCreate = true;
					else
						throw ex;
				}
			}

			if (localRegistration == null || forceCreate)
				registration = await CreateRegistration(registration);

			StoreRegistrationToLocal(registration);

			return registration;
		}
		private string BuildCreatePayload(Registration registration)
		{
			/*
            assuming:  
            tags,
            channelUri

            if template registration:
            assumes bodyTemplate AND wnsHeaders
            */

			string registrationPayload;

			var tagstring = String.Empty;
			if (registration.Tags != null)
			{
				tagstring = "<Tags>" + String.Join(",", registration.Tags) + "</Tags>";
			}

			if (!String.IsNullOrEmpty(registration.BodyTemplate))
			{
				registrationPayload = String.Format(
					GcmTemplateCreate,
					tagstring,
					registration.PnsToken,
					registration.BodyTemplate,
					registration.TemplateName);
			}
			else // native
			{
				registrationPayload = String.Format(
					GcmNativeCreate,
					tagstring,
					registration.PnsToken);
			}

			return registrationPayload;
		}
        private void ProcessXmlRegistration(Registration registration, XmlDocument registrationXml)
        {
            DateTime dateTime;
            double   expiry;

            registration.Raw = registrationXml.OuterXml;

            var nodes = registrationXml.GetElementsByTagName("DeviceToken");

            if (nodes.Count > 0)
            {
                registration.PnsToken = nodes[0].InnerText;
            }

            nodes = registrationXml.GetElementsByTagName("ETag");
            if (nodes.Count > 0)
            {
                registration.ETag = nodes[0].InnerText;
            }

            nodes = registrationXml.GetElementsByTagName("published");
            if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
            {
                registration.PublishedAt = dateTime;
            }

            nodes = registrationXml.GetElementsByTagName("updated");
            if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
            {
                registration.UpdatedAt = dateTime;
            }

            nodes = registrationXml.GetElementsByTagName("ExpirationTime");
            if (nodes.Count > 0 && DateTime.TryParse(nodes[0].InnerText, out dateTime))
            {
                registration.ExpiresAt = dateTime;
            }

            nodes = registrationXml.GetElementsByTagName("RegistrationId");
            if (nodes.Count > 0)
            {
                registration.RegistrationId = nodes[0].InnerText;
            }

            nodes             = registrationXml.GetElementsByTagName("Tags");
            registration.Tags = nodes.Count > 0 ? nodes[0].InnerText.Split(',') : new string[0];

            nodes = registrationXml.GetElementsByTagName("BodyTemplate");
            registration.BodyTemplate = nodes.Count > 0 ? nodes[0].InnerText : null;

            nodes = registrationXml.GetElementsByTagName("TemplateName");
            registration.TemplateName = nodes.Count > 0 ? nodes[0].InnerText : null;

            nodes = registrationXml.GetElementsByTagName("Expiry");
            if (nodes.Count > 0 && double.TryParse(nodes[0].InnerText, out expiry))
            {
                registration.ApnsExpiry = TimeSpan.FromSeconds(expiry);
            }
            else
            {
                registration.ApnsExpiry = null;
            }
        }