public SimulatedLoginAttempt(SimulatedAccount account,
            string password,
            bool isFromAttacker,
            bool isGuess,
            IPAddress clientAddress,
            string cookieProvidedByBrowser,
            string mistakeType,
            DateTimeOffset eventTime
        )
        {
            string accountId = account != null ? account.UniqueId : StrongRandomNumberGenerator.Get64Bits().ToString();
            bool isPasswordValid = account != null && account.Password == password;

            Attempt = new LoginAttempt
            {
                UsernameOrAccountId = accountId,
                AddressOfClientInitiatingRequest = clientAddress,
                AddressOfServerThatInitiallyReceivedLoginAttempt = new IPAddress(new byte[] {127, 1, 1, 1}),
                TimeOfAttempt = eventTime,
                Api = "web",
                CookieProvidedByBrowser = cookieProvidedByBrowser
            };
            Password = password;
            IsPasswordValid = isPasswordValid;
            IsFromAttacker = isFromAttacker;
            IsGuess = isGuess;
            MistakeType = mistakeType;
        }
        /// <summary>
        /// Create accounts, generating passwords, primary IP
        /// </summary>
        public void GenerateSimulatedAccounts()
        {
            CommonPasswordSelector =
                PasswordSelector.TrimToInitialItems(
                    (int) MyExperimentalConfiguration.NumberOfPopularPasswordsForAttackerToExploit);
            OrderedListOfMostCommonPasswords =
                PasswordSelector.GetItems((int) MyExperimentalConfiguration.NumberOfPopularPasswordsForAttackerToExploit);

            int totalAccounts = 0;

            // Generate benign accounts
            for (uint i = 0; i < MyExperimentalConfiguration.NumberOfBenignAccounts; i++)
            {
                SimulatedAccount account = new SimulatedAccount()
                {
                    UniqueId = (totalAccounts++).ToString(),
                    Password = PasswordSelector.GetItemByWeightedRandom()
                };
                account.ClientAddresses.Add(GetNewRandomBenignIp(account.UniqueId));
                account.Cookies.Add(StrongRandomNumberGenerator.Get64Bits().ToString());
                BenignAccounts.Add(account);
                double inverseFrequency = Distributions.GetLogNormal(0, 1);
                if (inverseFrequency < 0.01d)
                    inverseFrequency = 0.01d;
                if (inverseFrequency > 50d)
                    inverseFrequency = 50d;
                double frequency = 1/inverseFrequency;
                BenignAccountSelector.AddItem(account, frequency);
            }


            // Right after creating benign accounts we can create malicious ones. 
            // (we'll needed to wait for the the benign IPs to be generated create some overlap)
            GenerateMaliciousIps();

            // Generate attacker accounts
            for (ulong i = 0; i < MyExperimentalConfiguration.NumberOfAttackerControlledAccounts; i++)
            {
                SimulatedAccount account = new SimulatedAccount()
                {
                    UniqueId = (totalAccounts++).ToString(),
                    Password = PasswordSelector.GetItemByWeightedRandom(),
                };
                account.ClientAddresses.Add(GetRandomMaliciousIp());
                MaliciousAccounts.Add(account);
            }
        }
        /// <summary>
        /// Create accounts, generating passwords, primary IP
        /// </summary>
        public void GenerateSimulatedAccounts()
        {
            PasswordSelector = new WeightedSelector<string>();
            CommonPasswordSelector = new WeightedSelector<string>();
            uint lineNumber = 0;
            // Created a weighted-random selector for paasswords based on the RockYou database.
            using (System.IO.StreamReader file =
                new System.IO.StreamReader(MyExperimentalConfiguration.PasswordFrequencyFile))
            {
                string lineWithCountFollowedBySpaceFollowedByPassword;
                while ((lineWithCountFollowedBySpaceFollowedByPassword = file.ReadLine()) != null)
                {
                    lineWithCountFollowedBySpaceFollowedByPassword =
                        lineWithCountFollowedBySpaceFollowedByPassword.Trim();
                    int indexOfFirstSpace = lineWithCountFollowedBySpaceFollowedByPassword.IndexOf(' ');
                    if (indexOfFirstSpace < 0 ||
                        indexOfFirstSpace + 1 >= lineWithCountFollowedBySpaceFollowedByPassword.Length)
                        continue; // The line is invalid as it doesn't have a space with a password after it
                    string countAsString = lineWithCountFollowedBySpaceFollowedByPassword.Substring(0, indexOfFirstSpace);
                    ulong count;
                    if (!ulong.TryParse(countAsString, out count))
                        continue; // The count field is invalid as it doesn't parse to an unsigned number
                    string password = lineWithCountFollowedBySpaceFollowedByPassword.Substring(indexOfFirstSpace + 1);
                    PasswordSelector.AddItem(password, count);
                    if (lineNumber++ < MyExperimentalConfiguration.NumberOfPopularPasswordsForAttackerToExploit)
                    {
                        CommonPasswordSelector.AddItem(password, count);
                        OrderedListOfMostCommonPasswords.Add(password);
                    }
                }
            }

            int totalAccounts = 0;

            // Generate benign accounts
            foreach (
                ExperimentalConfiguration.BenignUserAccountGroup group in MyExperimentalConfiguration.BenignUserGroups)
            {
                for (ulong i = 0; i < group.GroupSize; i++)
                {
                    SimulatedAccount account = new SimulatedAccount()
                    {
                        UniqueId = (totalAccounts++).ToString(),
                        Password = PasswordSelector.GetItemByWeightedRandom()
                    };
                    account.ClientAddresses.Add(GetNewRandomBenignIp());
                    account.Cookies.Add(StrongRandomNumberGenerator.Get64Bits().ToString());
                    BenignAccounts.Add(account);
                    BenignAccountSelector.AddItem(account, group.LoginsPerYear);
                }
            }

            // Right after creating benign accounts we can create malicious ones.
            // (we'll needed to wait for the the benign IPs to be generated create some overlap)
            GenerateMaliciousIps();

            // Generate attacker accounts
            for (ulong i = 0; i < MyExperimentalConfiguration.NumberOfAttackerControlledAccounts; i++)
            {
                SimulatedAccount account = new SimulatedAccount()
                {
                    UniqueId = (totalAccounts++).ToString(),
                    Password = PasswordSelector.GetItemByWeightedRandom(),
                };
                account.ClientAddresses.Add(GetRandomMaliciousIp());
                MaliciousAccounts.Add(account);
            }
        }