public override int GetHashCode()
        {
            var hash = 3;

            hash = (hash * 2) + EnableLdapAuthentication.GetHashCode();
            hash = (hash * 2) + StartTls.GetHashCode();
            hash = (hash * 2) + Ssl.GetHashCode();
            hash = (hash * 2) + SendWelcomeEmail.GetHashCode();
            hash = (hash * 2) + Server.GetHashCode();
            hash = (hash * 2) + UserDN.GetHashCode();
            hash = (hash * 2) + PortNumber.GetHashCode();
            hash = (hash * 2) + UserFilter.GetHashCode();
            hash = (hash * 2) + LoginAttribute.GetHashCode();
            hash = (hash * 2) + GroupMembership.GetHashCode();
            hash = (hash * 2) + GroupDN.GetHashCode();
            hash = (hash * 2) + GroupNameAttribute.GetHashCode();
            hash = (hash * 2) + GroupFilter.GetHashCode();
            hash = (hash * 2) + UserAttribute.GetHashCode();
            hash = (hash * 2) + GroupAttribute.GetHashCode();
            hash = (hash * 2) + Authentication.GetHashCode();
            hash = (hash * 2) + Login.GetHashCode();

            foreach (var pair in LdapMapping)
            {
                hash = (hash * 2) + pair.Value.GetHashCode();
            }

            foreach (var pair in AccessRights)
            {
                hash = (hash * 2) + pair.Value.GetHashCode();
            }

            return(hash);
        }
        public override int GetHashCode()
        {
            var hash = 3;

            hash = (hash * 2) + EnableLdapAuthentication.GetHashCode();
            hash = (hash * 2) + StartTls.GetHashCode();
            hash = (hash * 2) + Server.GetHashCode();
            hash = (hash * 2) + UserDN.GetHashCode();
            hash = (hash * 2) + PortNumber.GetHashCode();
            hash = (hash * 2) + UserFilter.GetHashCode();
            hash = (hash * 2) + LoginAttribute.GetHashCode();
            hash = (hash * 2) + FirstNameAttribute.GetHashCode();
            hash = (hash * 2) + SecondNameAttribute.GetHashCode();
            hash = (hash * 2) + MailAttribute.GetHashCode();
            hash = (hash * 2) + TitleAttribute.GetHashCode();
            hash = (hash * 2) + MobilePhoneAttribute.GetHashCode();
            hash = (hash * 2) + LocationAttribute.GetHashCode();
            hash = (hash * 2) + GroupMembership.GetHashCode();
            hash = (hash * 2) + GroupDN.GetHashCode();
            hash = (hash * 2) + GroupNameAttribute.GetHashCode();
            hash = (hash * 2) + GroupFilter.GetHashCode();
            hash = (hash * 2) + UserAttribute.GetHashCode();
            hash = (hash * 2) + GroupAttribute.GetHashCode();
            hash = (hash * 2) + Authentication.GetHashCode();
            hash = (hash * 2) + Login.GetHashCode();
            return(hash);
        }
        /// <summary>
        /// Create user access
        /// </summary>
        /// <returns>access id</returns>
        public string CreateUserAccess(string userTitle, string userName, string userFirstname, string userPhoneNumber, string backUrl)
        {
            try
            {
                //#3- Ouverture d'un acces pour utilisateur
                //Data from certificate
                UserDN userDN = new UserDN()
                {
                    countryName = "FR",
                    organizationName = "UPSIDEO",
                    organizationalUnitName = "0002 538 768 003",
                    //emailAddress = "<Ne pas valoriser>",
                    commonName = "UPSIDEO", //<Prénom Nom>
                };

                SignatureInfo signatureInfo = new SignatureInfo()
                {
                    title = userTitle,
                    lastName = (!string.IsNullOrEmpty(userName)) ? userName : "******",
                    firstName = (!string.IsNullOrEmpty(userFirstname)) ? userFirstname : " ",
                    userDN = userDN
                };

                AuthenticationInfo authenticationInfo = new AuthenticationInfo()
                {
                    phoneNumber = this.GetCorrectDictaoMobile(userPhoneNumber),
                };

                string userId = System.Guid.NewGuid().ToString();

                PersonalInfo personalInfo = new PersonalInfo()
                {
                    userId = userId,
                    signatureInfo = signatureInfo,
                    authenticationInfo = authenticationInfo                    
                };

                //string consent = "J'ai bien lu les documents ci-contre que j'accepte de signer selon les termes des conditions générales et de la convention de preuve. J'ai connaissance du fait que la signature des documents au moyen d'une signature électronique manifeste mon consentement aux droits et obligations qui en découlent, au même titre qu'une signature manuscrite. J'accepte la ${TermAndConditionsUrl}."; // et la convention de preuve
                //Appendix doc
                List<string> appendixDocs = new List<string>();
                for (int i = 1; i <= AppendixCount; i++)
                {
                    appendixDocs.Add(string.Format("{0}{1}", APPENDIX, i));
                }

                createUserAccess createUserAccess = new createUserAccess()
                {
                    transactionId = TransactionId,
                    userInfo = personalInfo,
                    timeout = (long)3600000, //ms
                    userType = userId,
                    //authorizedDocTypes = new List<string>() { DocumentTypes.CONTRACT.ToString(), DocumentTypes.APPENDIX1.ToString(), DocumentTypes.APPENDIX2.ToString(), DocumentTypes.APPENDIX3.ToString() }.ToArray(), //TODO => list of appendixes : 3 appendixes
                    authorizedDocTypes = new List<string>() { DocumentTypes.CONTRACT.ToString() }.Concat(appendixDocs).ToArray(),
                    metadata = null
                };

                createUserAccessResponse createUserAccessResponse = _TransactionPortClient.createUserAccess(createUserAccess);
                string accessId = createUserAccessResponse.accessId;

                return accessId;
            }
            catch (Exception ex)
            {
                //string errorMessage = "Il est impossible de signer électroniquement votre document car le numéro de mobile indiqué n'est pas valide.";
                string errorMessage = ex.Message;

                if (!string.IsNullOrEmpty(errorMessage) && !errorMessage.Contains("mobile"))
                {
                    errorMessage = "Une erreur inattendue est survenue lors de la signature. Veuillez réessayer ultérieurement.";
                }
                              
                throw new Exception(errorMessage);
            }
        }
        /// <summary>
        /// Create user access
        /// </summary>
        /// <returns>access id</returns>
        public string CreateUserAccess(string userTitle, string userName, string userFirstname, string userPhoneNumber, string backUrl, bool isMainContractor, string termAndConditionsUrl, bool isCustomer)
        {
            try
            {
                //#3- Ouverture d'un acces pour utilisateur
                //TODO : Data from certificate
                UserDN userDN = new UserDN()
                {
                    countryName = "FR",
                    organizationName = "Dictao Trust Services Application CA",
                    organizationalUnitName = "AnySign",
                    //emailAddress = "TODO",
                    commonName = "SAAS QA DTP UPSIDEO Client",
                };

                string user = (isCustomer) ? "USER-CUSTOMER" : "USER-ADVISER";
                PersonalInfo personalInfo = new PersonalInfo()
                {
                    user = user,
                    mainContractor = isMainContractor,
                    title = userTitle,
                    firstName = userFirstname,
                    lastName = userName,
                    userDN = userDN
                };


                string consent = "J'ai bien lu les documents ci-contre que j'accepte de signer selon les termes des conditions générales et de la convention de preuve. J'ai connaissance du fait que la signature des documents au moyen d'une signature électronique manifeste mon consentement aux droits et obligations qui en découlent, au même titre qu'une signature manuscrite. J'accepte la ${TermAndConditionsUrl}."; // et la convention de preuve
                UIInfo uiInfo = new UIInfo()
                {
                    ui = "standard",
                    backUrl = backUrl,
                    consent = consent,
                    termAndConditionsUrl = termAndConditionsUrl
                };

                // Check phone number
                // After DICTAO update, this checking is outdated
                /*Match match = Regex.Match(userPhoneNumber, @"[0-9]{10}", RegexOptions.IgnoreCase);

                if (!match.Success)
                {
                    throw new Exception(string.Format(@"La signature électronique requiert un numéro de téléphone valide composé exactement de 10 chiffres. <br />
                                        Le numéro &laquo;{0}&raquo; est incorrect.", userPhoneNumber));
                }*/

                //Phone number should be composed only with [0-9]+
                userPhoneNumber = this.GetCorrectDictaoMobile(userPhoneNumber);

                AuthenticationInfo authentificationInfo = new AuthenticationInfo()
                {
                    //phoneNumber = (!string.IsNullOrEmpty(userPhoneNumber)) ? userPhoneNumber : "0000000000",
                    phoneNumber = userPhoneNumber,
                    userId = System.Guid.NewGuid().ToString()
                };

                addUserAccess addUserAccess = new addUserAccess()
                {
                    transactionId = TransactionId,
                    userInfo = personalInfo,
                    uiInfo = uiInfo,
                    authenticationInfo = authentificationInfo,
                    externalAccessId = null,
                    singleUsage = true,
                    timeout = (long)3600000, //ms
                    metadata = null
                };

                addUserAccessResponse addUserAccessResponse = _TransactionPortCli.addUserAccess(addUserAccess);
                string accessId = addUserAccessResponse.accessId;

                return accessId;
            }
            catch (Exception ex)
            {
                //this.CancelTransaction();
                string errorMessage = "Il est impossible de signer électroniquement votre document car le numéro de mobile indiqué n'est pas valide.";

                string showError = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ShowErrors"]);
                if (!string.IsNullOrEmpty(showError) && showError == "1")
                {
                    errorMessage = string.Format("{0} : {1}", ex.Message, ex.StackTrace);
                }
                throw new Exception(errorMessage);
            }
        }