internal static X509Certificate2 CreateCertificate(
            string applicationUri,
            string applicationName,
            string subjectName,
            IList <String> domainNames,
            ushort keySize,
            DateTime startTime,
            ushort lifetimeInMonths,
            ushort hashSizeInBits,
            bool isCA = false,
            X509Certificate2 issuerCAKeyCert = null,
            byte[] publicKey         = null,
            int pathLengthConstraint = 0)
        {
            ICertificateBuilder builder = null;

            if (isCA)
            {
                builder = CreateCertificate(subjectName);
            }
            else
            {
                builder = CreateCertificate(
                    applicationUri,
                    applicationName,
                    subjectName,
                    domainNames);
            }
            builder.SetNotBefore(startTime);
            builder.SetNotAfter(startTime.AddMonths(lifetimeInMonths));
            builder.SetHashAlgorithm(X509Utils.GetRSAHashAlgorithmName(hashSizeInBits));
            if (isCA)
            {
                builder.SetCAConstraint(pathLengthConstraint);
            }
            ICertificateBuilderCreateForRSA createBuilder;

            if (issuerCAKeyCert != null)
            {
                var issuerBuilder = builder.SetIssuer(issuerCAKeyCert);
                if (publicKey != null)
                {
                    createBuilder = issuerBuilder.SetRSAPublicKey(publicKey);
                }
                else
                {
                    createBuilder = issuerBuilder.SetRSAKeySize(keySize);
                }
            }
            else
            {
                createBuilder = builder.SetRSAKeySize(keySize);
            }
            return(createBuilder.CreateForRSA());
        }