/// <summary>
        /// Initial method / factory instanciation.
        /// In case the call is successfully completed you will get back an
        /// envelope object that can be used to work with this envelope.
        /// In case the envelope is misconstructed an exception will be thrown
        /// The IDs on both the recipients and documents are going to be altered
        /// after the call and the Tabs will be linked to the appropriate document and
        /// recipient ids.
        /// </summary>
        /// <param name="signers">A collection of signer objects that describes who is going to
        /// recieve the documents.  You should have at least one signer.  Every signer
        /// must have at least one signature.</param>
        /// <param name="documents">A set of documents with tabs attached
        /// to them.  There should be at least one document in the envelope and there should be
        /// at least one tab on the envelope.</param>
        /// <param name="subject">Subject of the e-mail that the signers
        /// are going to receive</param>
        /// <param name="emailBlurb">e-mail blurb that will be inserted
        /// into the messages delivered to signers</param>
        /// <returns>An envelope object that can be used to work with this envelope.</returns>
        public static Envelope CreateEnvelopeFromTemplates(AccountCredentials accountCredentials,
                                                           DocuSignWeb.Recipient[] signers,
                                                           LinkedTemplateReferenceRoleAssignment[] roleAssignments,
                                                           string template,
                                                           string subject, string emailBlurb,
                                                           DocuSignWeb.CustomField[] fields)
        {
            //
            // Assign sequential IDs to all the recipients
            //
            int nextRecipientId = 1;

            foreach (DocuSignWeb.Recipient recipient in signers)
            {
                recipient.ID = nextRecipientId.ToString(System.Globalization.CultureInfo.InvariantCulture);
                nextRecipientId++;
            }

            //
            // update the template references
            //
            TemplateReferenceRoleAssignment[] finalRoleAssignments = new TemplateReferenceRoleAssignment[roleAssignments.Length];
            for (int i = 0; i < roleAssignments.Length; ++i)
            {
                roleAssignments[i].referenceRoleAssignment.RecipientID = roleAssignments[i].signer.ID;
                finalRoleAssignments[i] = roleAssignments[i].referenceRoleAssignment;
            }

            //
            // setting up the template
            //
            TemplateReference templateReference = new TemplateReference();

            templateReference.Template         = template;
            templateReference.TemplateLocation = TemplateLocationCode.SOAP;
            templateReference.RoleAssignments  = finalRoleAssignments;

            //
            // Envelope wide information
            //
            DocuSignWeb.EnvelopeInformation envelopeInfo = new EnvelopeInformation();
            envelopeInfo.AccountId    = accountCredentials.AccountId;
            envelopeInfo.CustomFields = fields;
            envelopeInfo.EmailBlurb   = emailBlurb;
            envelopeInfo.Subject      = subject;

            DocuSignWeb.APIServiceSoap apiService = CreateApiProxy(accountCredentials);
            DocuSignWeb.EnvelopeStatus envStatus  = apiService.CreateEnvelopeFromTemplates(
                new TemplateReference[] { templateReference },
                signers, envelopeInfo, true);
            return(new Envelope(envStatus.EnvelopeID, accountCredentials));
        }
        /// <summary>
        /// This method is used to create envelope besed on the give template
        /// </summary>
        /// <param name="identity"></param>
        /// <param name="signers"></param>
        /// <param name="roleAssignments"></param>
        /// <param name="template"></param>
        /// <param name="subject"></param>
        /// <param name="emailBlurb"></param>
        /// <param name="fields"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string CreateEnvelopeFromTemplates(Account identity,
                                                         Recipient[] signers,
                                                         string template, string subject, string emailBlurb, string password, string url, bool isEmbedded)
        {
            //
            // update the template references
            //
            List <TemplateReferenceRoleAssignment> finalRoleAssignments = new List <TemplateReferenceRoleAssignment>();

            foreach (Recipient recipient in signers)
            {
                TemplateReferenceRoleAssignment templateReferenceRoleAssignment = new TemplateReferenceRoleAssignment();
                templateReferenceRoleAssignment.RecipientID = recipient.ID;
                templateReferenceRoleAssignment.RoleName    = recipient.RoleName;
                finalRoleAssignments.Add(templateReferenceRoleAssignment);
            }

            //
            // setting up the template
            //
            TemplateReference templateReference = new TemplateReference();

            templateReference.Template         = template;
            templateReference.TemplateLocation = TemplateLocationCode.SOAP;
            templateReference.RoleAssignments  = finalRoleAssignments.ToArray();

            //
            // Envelope wide information
            //
            EnvelopeInformation envelopeInfo = new EnvelopeInformation();

            envelopeInfo.AccountId  = identity.AccountID;
            envelopeInfo.EmailBlurb = emailBlurb;
            envelopeInfo.Subject    = subject;

            APIServiceSoap apiService = CreateApiProxy(identity, password);
            EnvelopeStatus envStatus  = apiService.CreateEnvelopeFromTemplates(
                new TemplateReference[] { templateReference }, signers, envelopeInfo, true);

            if (!isEmbedded)
            {
                return(envStatus.EnvelopeID);
            }
            else
            {
                RequestRecipientTokenAuthenticationAssertion assert = new RequestRecipientTokenAuthenticationAssertion();
                assert.AssertionID           = System.DateTime.Now.Ticks.ToString();
                assert.AuthenticationInstant = System.DateTime.Now;
                assert.AuthenticationMethod  = RequestRecipientTokenAuthenticationAssertionAuthenticationMethod.Password;
                assert.SecurityDomain        = "TODO-replace-with-your-app-name";

                //These are Urls to which Docusign will redirect
                string retUrl = url.ToLower();
                RequestRecipientTokenClientURLs clientURLs = new RequestRecipientTokenClientURLs();
                clientURLs.OnSigningComplete  = retUrl + "?event=SignComplete&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnAccessCodeFailed = retUrl + "?event=AccessCode&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnCancel           = retUrl + "?event=Cancel&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnDecline          = retUrl + "?event=Decline&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnException        = retUrl + "?event=Exception&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnIdCheckFailed    = retUrl + "?event=IDCheck&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnSessionTimeout   = retUrl + "?event=Timeout&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnTTLExpired       = retUrl + "?event=TTLExpired&envelopeID=" + envStatus.EnvelopeID;
                clientURLs.OnViewingComplete  = retUrl + "?event=ViewComplete&envelopeID=" + envStatus.EnvelopeID;

                string token = apiService.RequestRecipientToken(envStatus.EnvelopeID, signers[0].CaptiveInfo.ClientUserId, signers[0].UserName, signers[0].Email, assert, clientURLs);
                return(token);
            }
        }