/// <summary>
		/// Saves the information required to send this channel messages to the blob store,
		/// and returns the URL to share with senders.
		/// </summary>
		/// <param name="endpoint">The endpoint for which an address book entry should be created and published.</param>
		/// <param name="cancellationToken">A cancellation token to abort the publish.</param>
		/// <returns>A task whose result is the absolute URI to the address book entry.</returns>
		public async Task<Uri> PublishAddressBookEntryAsync(OwnEndpoint endpoint, CancellationToken cancellationToken = default(CancellationToken)) {
			Requires.NotNull(endpoint, "endpoint");

			var abe = endpoint.CreateAddressBookEntry(this.CryptoProvider);
			var abeWriter = new StringWriter();
			await Utilities.SerializeDataContractAsBase64Async(abeWriter, abe);
			var ms = new MemoryStream(Encoding.UTF8.GetBytes(abeWriter.ToString()));
			var location = await this.CloudBlobStorage.UploadMessageAsync(ms, DateTime.MaxValue, AddressBookEntry.ContentType, cancellationToken: cancellationToken);
			if (this.UrlShortener != null) {
				location = await this.UrlShortener.ShortenAsync(location);
			}

			var fullLocationWithFragment = new Uri(
				location,
				"#" + this.CryptoProvider.CreateWebSafeBase64Thumbprint(endpoint.PublicEndpoint.SigningKeyPublicMaterial));
			return fullLocationWithFragment;
		}
        /// <summary>
        /// Saves the information required to send this channel messages to the blob store,
        /// and returns the URL to share with senders.
        /// </summary>
        /// <param name="endpoint">The endpoint for which an address book entry should be created and published.</param>
        /// <param name="cancellationToken">A cancellation token to abort the publish.</param>
        /// <returns>A task whose result is the absolute URI to the address book entry.</returns>
        public async Task <Uri> PublishAddressBookEntryAsync(OwnEndpoint endpoint, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(endpoint, "endpoint");

            var abe       = endpoint.CreateAddressBookEntry(this.CryptoProvider);
            var abeWriter = new StringWriter();
            await Utilities.SerializeDataContractAsBase64Async(abeWriter, abe);

            var ms       = new MemoryStream(Encoding.UTF8.GetBytes(abeWriter.ToString()));
            var location = await this.CloudBlobStorage.UploadMessageAsync(ms, DateTime.MaxValue, AddressBookEntry.ContentType, cancellationToken : cancellationToken);

            if (this.UrlShortener != null)
            {
                location = await this.UrlShortener.ShortenAsync(location);
            }

            var fullLocationWithFragment = new Uri(
                location,
                "#" + this.CryptoProvider.CreateWebSafeBase64Thumbprint(endpoint.PublicEndpoint.SigningKeyPublicMaterial));

            return(fullLocationWithFragment);
        }
        /// <summary>
        /// Generates a new receiving endpoint.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The newly generated endpoint.
        /// </returns>
        /// <remarks>
        /// Depending on the length of the keys set in the provider and the amount of buffered entropy in the operating system,
        /// this method can take an extended period (several seconds) to complete.
        /// </remarks>
        private OwnEndpoint CreateEndpointWithKeys(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var encryptionKey = CryptoSettings.EncryptionAlgorithm.CreateKeyPair(this.CryptoProvider.AsymmetricKeySize);
            cancellationToken.ThrowIfCancellationRequested();
            var signingKey = CryptoSettings.SigningAlgorithm.CreateKeyPair(this.CryptoProvider.AsymmetricKeySize);

            var ownContact = new OwnEndpoint(signingKey, encryptionKey);
            return ownContact;
        }
 private Task SetEndpointAsync(OwnEndpoint endpoint, Uri addressBookEntry, CancellationToken cancellationToken = default(CancellationToken))
 {
     this.Channel.Endpoint = endpoint;
     this.PublicEndpointUrlTextBlock.Text = addressBookEntry.AbsoluteUri;
     this.OpenChatroom.IsEnabled = true;
     this.ChatWithAuthor.IsEnabled = true;
     return Task.FromResult<object>(null);
 }
		private async Task SetEndpointAsync(OwnEndpoint endpoint, Uri addressBookEntry, CancellationToken cancellationToken = default(CancellationToken)) {
			this.Channel.Endpoint = endpoint;
			this.PublicEndpointUrlTextBlock.Text = addressBookEntry.AbsoluteUri;
			this.OpenChatroom.IsEnabled = true;
		}
		/// <summary>
		/// Generates a new receiving endpoint.
		/// </summary>
		/// <returns>The newly generated endpoint.</returns>
		/// <remarks>
		/// Depending on the length of the keys set in the provider and the amount of buffered entropy in the operating system,
		/// this method can take an extended period (several seconds) to complete.
		/// </remarks>
		private OwnEndpoint CreateEndpointWithKeys() {
			byte[] privateEncryptionKey, publicEncryptionKey;
			byte[] privateSigningKey, publicSigningKey;

			this.CryptoProvider.GenerateEncryptionKeyPair(out privateEncryptionKey, out publicEncryptionKey);
			this.CryptoProvider.GenerateSigningKeyPair(out privateSigningKey, out publicSigningKey);

			var contact = new Endpoint() {
				EncryptionKeyPublicMaterial = publicEncryptionKey,
				SigningKeyPublicMaterial = publicSigningKey,
			};

			var ownContact = new OwnEndpoint(contact, privateSigningKey, privateEncryptionKey);
			return ownContact;
		}