private static string WriteConnectPackageParametersXml(
            ConnectPackageCreationParameters creationParameters,
            PasswordProtectedPackage package)
        {
            StringBuilder request = new StringBuilder(512);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;

            using (XmlWriter writer = XmlWriter.Create(request, settings))
            {
                if (creationParameters.IdentityCode != null)
                {
                    writer.WriteElementString("identity-code", creationParameters.IdentityCode);
                }

                writer.WriteElementString("friendly-name", creationParameters.FriendlyName);
                writer.WriteElementString("question", creationParameters.SecurityQuestion);
                writer.WriteElementString("external-id", creationParameters.ApplicationPatientId);
                writer.WriteRaw(package.GetItemXml("package"));
                WritePackageBlobRefUrls(creationParameters.PackageBlobReferenceUrls, writer);
            }

            return request.ToString();
        }
        /// <summary>
        /// Asks HealthVault to create a pending package for the application specified
        /// by the connection with the specified user specific parameters and the pre-allocated
        /// identity code.
        /// </summary>
        /// 
        /// <remarks>
        /// The password protected package supports 2 encryption algorithms, AES256 (recommended)
        /// and TripleDES. 
        /// <br/><br/>
        /// For AES256, the supported key size is 256 bits, the blocksize is 256 bits, the IV 
        /// length is 32 bytes.
        /// <br/><br/>
        /// For TripleDES, the supported key size is 192 bits, the blocksize is 64 bits, the IV 
        /// length is 8 bytes.
        /// <br/><br/>
        /// The encryption key should be derived using the answer, the salt, and the number of hash 
        /// iterations. The decryption will generate this key via the 
        /// <see cref="Rfc2898DeriveBytes"/> class, hence, encryption should use a similar or 
        /// identical process. To ensure case-insensitivity, the answer should be converted to its
        /// lower cased form using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) 
        /// prior to generating the derived key.
        /// <br/><br/>
        /// The algorithm used has the following parameters:
        /// <ul>
        ///    <li>Mode = CipherMode.CBC</li>
        ///    <li>Padding = PaddingMode.ISO10126</li>
        /// </ul>
        /// <br/><br/>
        /// The salt supplied is used as the salt to the derived key as well as the key to the 
        /// supplied HMAC. The salt should be at least 8 bytes long.
        /// <br/><br/>
        /// It is recommended that the number of hash iterations be at least 10000.
        /// </remarks>
        /// 
        /// <param name="creationParameters">
        /// The parameters to use when creating the package. 
        /// </param>
        /// 
        /// <param name="connectPackage">
        /// The pending connect package that the user will add to his/her record. 
        /// This package's
        /// <see cref="HealthRecordItem"/>'s <see cref="BlobStore"/> must be an encrypted 
        /// blob of xml that represents a list of HealthRecordItems. This xml blob
        /// must be a sequence of <thing/> elements, each wrapping the XML representation of a 
        /// single HealthRecordItem. Each <thing/> element may be generated by calling 
        /// <see cref="HealthRecordItem.GetItemXml()"/>.
        /// </param>
        ///         
        /// <returns>
        /// A token that the application must give to the patient to use when validating the
        /// connection request.
        /// </returns>
        /// 
        /// <exception cref="HealthServiceException">
        /// If an error occurs when contacting HealthVault.
        /// </exception>
        ///
        public virtual string CreateConnectPackage(
            ConnectPackageCreationParameters creationParameters,
            PasswordProtectedPackage connectPackage)
        {
            Validator.ThrowIfArgumentNull(
                connectPackage,
                "connectPackage",
                "PackageCreatePPPMissingMandatory");

            HealthServiceRequest request =
                new HealthServiceRequest(creationParameters.Connection, "CreateConnectPackage", 2);

            request.Parameters =
                WriteConnectPackageParametersXml(
                    creationParameters,
                    connectPackage);

            request.Execute();

            XPathExpression infoPath =
                SDKHelper.GetInfoXPathExpressionForMethod(
                    request.Response.InfoNavigator,
                    "CreateConnectPackage");

            XPathNavigator infoNav = request.Response.InfoNavigator.SelectSingleNode(infoPath);
            return infoNav.SelectSingleNode("identity-code").Value;
        }
 /// <summary>
 /// Asks HealthVault to create a pending package for the application specified
 /// by the connection with the specified user specific parameters and the pre-allocated
 /// identity code.
 /// </summary>
 /// 
 /// <remarks>
 /// The password protected package supports 2 encryption algorithms, AES256 (recommended)
 /// and TripleDES. 
 /// <br/><br/>
 /// For AES256, the supported key size is 256 bits, the blocksize is 256 bits, the IV 
 /// length is 32 bytes.
 /// <br/><br/>
 /// For TripleDES, the supported key size is 192 bits, the blocksize is 64 bits, the IV 
 /// length is 8 bytes.
 /// <br/><br/>
 /// The encryption key should be derived using the answer, the salt, and the number of hash 
 /// iterations. The decryption will generate this key via the 
 /// <see cref="Rfc2898DeriveBytes"/> class, hence, encryption should use a similar or 
 /// identical process. To ensure case-insensitivity, the answer should be converted to its
 /// lower cased form using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) 
 /// prior to generating the derived key.
 /// <br/><br/>
 /// The algorithm used has the following parameters:
 /// <ul>
 ///    <li>Mode = CipherMode.CBC</li>
 ///    <li>Padding = PaddingMode.ISO10126</li>
 /// </ul>
 /// <br/><br/>
 /// The salt supplied is used as the salt to the derived key as well as the key to the 
 /// supplied HMAC. The salt should be at least 8 bytes long.
 /// <br/><br/>
 /// It is recommended that the number of hash iterations be at least 10000.
 /// </remarks>
 /// 
 /// <param name="creationParameters">
 /// The parameters to use when creating the package. 
 /// </param>
 /// 
 /// <param name="connectPackage">
 /// The pending connect package that the user will add to his/her record. 
 /// This package's
 /// <see cref="HealthRecordItem"/>'s <see cref="BlobStore"/> must be an encrypted 
 /// blob of xml that represents a list of HealthRecordItems. This xml blob
 /// must be a sequence of <thing/> elements, each wrapping the XML representation of a 
 /// single HealthRecordItem. Each <thing/> element may be generated by calling 
 /// <see cref="HealthRecordItem.GetItemXml()"/>.
 /// </param>
 ///         
 /// <returns>
 /// A token that the application must give to the patient to use when validating the
 /// connection request.
 /// </returns>
 /// 
 /// <exception cref="HealthServiceException">
 /// If an error occurs when contacting HealthVault.
 /// </exception>
 ///
 public static string CreateConnectPackage(
     ConnectPackageCreationParameters creationParameters,
     PasswordProtectedPackage connectPackage)
 {
     return HealthVaultPlatformPatientConnect.Current.CreateConnectPackage(
         creationParameters,
         connectPackage);
 }
        private static string CreatePackageWithContentsAllParameters(
            ConnectPackageCreationParameters creationParameters,
            IList<HealthRecordItem> packageContents)
        {
            // Obtain the data to encrypt
            StringBuilder xmlContents = new StringBuilder();

            Validator.ThrowArgumentExceptionIf(
                packageContents == null || packageContents.Count == 0,
                "packageContents",
                "PackageCreateHRIMissingMandatory");

            for (int i = 0; i < packageContents.Count; ++i)
            {
                Validator.ThrowArgumentExceptionIf(
                    packageContents[i] == null,
                    "packageContents",
                    "PackageCreateHRIMissingMandatory");

                foreach (Blob blob
                            in packageContents[i].GetBlobStore(
                                default(HealthRecordAccessor)).Values)
                {
                    if (blob.Url != null)
                    {
                        if (packageContents[i].HealthRecordItemSignatures.Count > 0)
                        {
                            throw Validator.NotSupportedException("PackageCreateSignedWithStreamedBlobsNotSupported");
                        }

                        creationParameters.PackageBlobReferenceUrls.Add(blob.Url);
                    }
                }

                xmlContents.Append(packageContents[i].GetItemXml());
            }

            string dataToEncrypt = xmlContents.ToString();

            // Uses AES256 by default
            PasswordProtectedPackage connectPackage =
                new PasswordProtectedPackage(
                    creationParameters.PasswordProtectAlgorithm,
                    creationParameters.Salt,
                    creationParameters.ConnectPackageEncryptionAlgorithm.KeySize);

            byte[] encryptedData =
                SignAndEncrypt(
                    dataToEncrypt,
                    creationParameters.ConnectPackageHMACAlgorithm,
                    creationParameters.ConnectPackageEncryptionAlgorithm);

            BlobStore store = connectPackage.GetBlobStore(default(HealthRecordAccessor));
            store.WriteInline(String.Empty, "application/octet-stream", encryptedData);

            return HealthVaultPlatform.CreateConnectPackage(
                    creationParameters,
                    connectPackage);
        }
        /// <summary>
        /// Asks HealthVault to create a pending package for the application specified
        /// by the connection with the specified user specific parameters and the pre-allocated
        /// identity code.
        /// </summary>
        /// 
        /// <remarks>
        /// The password protected package supports 2 encryption algorithms, AES256 (recommended)
        /// and TripleDES. 
        /// <br/><br/>
        /// For AES256, the supported key size is 256 bits, the blocksize is 256 bits, the IV 
        /// length is 32 bytes.
        /// <br/><br/>
        /// For TripleDES, the supported key size is 192 bits, the blocksize is 64 bits, the IV 
        /// length is 8 bytes.
        /// <br/><br/>
        /// The encryption key should be derived using the answer, the salt, and the number of hash 
        /// iterations. The decryption will generate this key via the 
        /// <see cref="Rfc2898DeriveBytes"/> class, hence, encryption should use a similar or 
        /// identical process. To ensure case-insensitivity, the answer should be converted to its
        /// lower cased form using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) 
        /// prior to generating the derived key.
        /// <br/><br/>
        /// The algorithm used has the following parameters:
        /// <ul>
        ///    <li>Mode = CipherMode.CBC</li>
        ///    <li>Padding = PaddingMode.ISO10126</li>
        /// </ul>
        /// <br/><br/>
        /// The salt supplied is used as the salt to the derived key as well as the key to the 
        /// supplied HMAC. The salt should be at least 8 bytes long.
        /// <br/><br/>
        /// It is recommended that the number of hash iterations be at least 10000.
        /// </remarks>
        /// 
        /// <param name="connection">
        /// The application connection to HealthVault. The application ID in the connection is used
        /// when making the patient connection.
        /// </param>
        /// 
        /// <param name="identityCode">
        /// A package identity token previously obtained from <see cref="ConnectPackage.AllocatePackageId"/>.  
        /// </param>
        /// 
        /// <param name="friendlyName">
        /// A friendly name for the patient connection which will be shown to the user when they
        /// go to HealthVault Shell to validate the connection.
        /// </param>
        /// 
        /// <param name="securityQuestion">
        /// A question (usually provided by the patient) to which the patient must provide the 
        /// answer when they go to validate the connection in the 
        /// HealthVault Shell.
        /// </param>
        /// 
        /// <param name="applicationPatientId">
        /// The application specific identifier for the user. This identifier is used to uniquely
        /// identify the user in the application data storage whereas the HealthVault person ID is
        /// used to identify the person in HealthVault.
        /// </param>
        /// 
        /// <param name="connectPackage">
        /// The pending connect package that the user will add to his/her record. 
        /// This package's
        /// <see cref="HealthRecordItem"/>'s <see cref="BlobStore"/> must be an encrypted 
        /// blob of xml that represents a list of HealthRecordItems. This xml blob
        /// must be a sequence of <thing/> elements, each wrapping the XML representation of a 
        /// single HealthRecordItem. Each <thing/> element may be generated by calling 
        /// <see cref="HealthRecordItem.GetItemXml()"/>.
        /// </param>
        ///         
        /// <returns>
        /// A token that the application must give to the patient to use when validating the
        /// connection request.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="connection"/> is <b>null</b>.
        /// </exception>
        /// 
        /// <exception cref="ArgumentException">
        /// If <paramref name="identityCode"/>, <paramref name="friendlyName"/>, 
        /// <paramref name="securityQuestion"/>,
        /// <paramref name="applicationPatientId"/>, or <paramref name="connectPackage"/> is
        /// <b>null</b> or empty.
        /// </exception>
        /// 
        /// <exception cref="HealthServiceException">
        /// If an error occurs when contacting HealthVault.
        /// </exception>
        ///
        public static string Create(
            OfflineWebApplicationConnection connection,
            string identityCode,
            string friendlyName,
            string securityQuestion,
            string applicationPatientId,
            PasswordProtectedPackage connectPackage)
        {
            Validator.ThrowIfStringNullOrEmpty(identityCode, "identityCode");

            ConnectPackageCreationParameters creationParameters =
                new ConnectPackageCreationParameters(
                    connection,
                    identityCode,
                    friendlyName,
                    securityQuestion,
                    null,
                    applicationPatientId,
                    false,
                    true);

            return HealthVaultPlatform.CreateConnectPackage(
                    creationParameters,
                    connectPackage);
        }
        /// <summary>
        /// Asks HealthVault to create a pending package for the application specified
        /// by the connection with the specified user specific parameters.
        /// </summary>
        /// 
        /// <remarks>
        /// The password protected package supports 2 encryption algorithms, AES256 (recommended)
        /// and TripleDES. 
        /// <br/><br/>
        /// For AES256, the supported key size is 256 bits, the blocksize is 256 bits, the IV 
        /// length is 32 bytes.
        /// <br/><br/>
        /// For TripleDES, the supported key size is 192 bits, the blocksize is 64 bits, the IV 
        /// length is 8 bytes.
        /// <br/><br/>
        /// The encryption key should be derived using the answer, the salt, and the number of hash 
        /// iterations. The decryption will generate this key via the 
        /// <see cref="Rfc2898DeriveBytes"/> class, hence, encryption should use a similar or 
        /// identical process. To ensure case-insensitivity, the answer should be converted to its
        /// lower cased form using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) 
        /// prior to generating the derived key.
        /// <br/><br/>
        /// The algorithm used has the following parameters:
        /// <ul>
        ///    <li>Mode = CipherMode.CBC</li>
        ///    <li>Padding = PaddingMode.ISO10126</li>
        /// </ul>
        /// <br/><br/>
        /// The salt supplied is used as the salt to the derived key as well as the key to the 
        /// supplied HMAC. The salt should be at least 8 bytes long.
        /// <br/><br/>
        /// It is recommended that the number of hash iterations be at least 10000.
        /// </remarks>
        /// 
        /// <param name="connection">
        /// The application connection to HealthVault. The application ID in the connection is used
        /// when making the patient connection.
        /// </param>
        /// 
        /// <param name="friendlyName">
        /// A friendly name for the patient connection which will be shown to the user when they
        /// go to HealthVault Shell to validate the connection.
        /// </param>
        /// 
        /// <param name="securityQuestion">
        /// A question (usually provided by the patient) to which the patient must provide the 
        /// answer when they go to validate the connection in the 
        /// HealthVault Shell.
        /// </param>
        /// 
        /// <param name="applicationPatientId">
        /// The application specific identifier for the user. This identifier is used to uniquely
        /// identify the user in the application data storage whereas the HealthVault person ID is
        /// used to identify the person in HealthVault.
        /// </param>
        /// 
        /// <param name="connectPackage">
        /// The pending connect package that the user will add to his/her record. This package's
        /// <see cref="Blob"/> must be an encrypted and Base64 
        /// encoded blob of xml that represents a list of HealthRecordItems. This xml blob
        /// must be a sequence of <thing/> elements, each wrapping the XML representation of a 
        /// single HealthRecordItem. Each <thing/> element may be generated by calling 
        /// <see cref="HealthRecordItem.GetItemXml()"/>.
        /// </param>
        /// 
        /// <returns>
        /// A token that the application must give to the patient to use when validating the
        /// connection request.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="connection"/> is <b>null</b>.
        /// </exception>
        /// 
        /// <exception cref="ArgumentException">
        /// If <paramref name="friendlyName"/>, <paramref name="securityQuestion"/>,
        /// <paramref name="applicationPatientId"/>, or <paramref name="connectPackage"/> is
        /// <b>null</b> or empty.
        /// </exception>
        /// 
        /// <exception cref="HealthServiceException">
        /// If an error occurs when contacting HealthVault.
        /// </exception>
        /// 
        public static string Create(
            OfflineWebApplicationConnection connection,
            string friendlyName,
            string securityQuestion,
            string applicationPatientId,
            PasswordProtectedPackage connectPackage)
        {
            ConnectPackageCreationParameters creationParameters =
                new ConnectPackageCreationParameters(
                    connection,
                    null,
                    friendlyName,
                    securityQuestion,
                    null,
                    applicationPatientId,
                    false,
                    false);

            return HealthVaultPlatform.CreateConnectPackage(
                    creationParameters,
                    connectPackage);
        }