Example usage for java.util Collections shuffle

List of usage examples for java.util Collections shuffle

Introduction

In this page you can find the example usage for java.util Collections shuffle.

Prototype

public static void shuffle(List<?> list) 

Source Link

Document

Randomly permutes the specified list using a default source of randomness.

Usage

From source file:com.cbsb.ftpserv.ProxyConnector.java

private String[] getProxyList() {
    SharedPreferences prefs = Globals.getContext().getSharedPreferences(PREFERRED_SERVER, 0);
    String preferred = prefs.getString(PREFERRED_SERVER, null);

    String[] allProxies;//from w ww . j a  va  2s. co m

    if (Defaults.release) {
        allProxies = new String[] { "c1.swiftp.org", "c2.swiftp.org", "c3.swiftp.org", "c4.swiftp.org",
                "c5.swiftp.org", "c6.swiftp.org", "c7.swiftp.org", "c8.swiftp.org", "c9.swiftp.org" };
    } else {
        //allProxies = new String[] {
        //   "cdev.swiftp.org"
        //};
        allProxies = new String[] { "c1.swiftp.org", "c2.swiftp.org", "c3.swiftp.org", "c4.swiftp.org",
                "c5.swiftp.org", "c6.swiftp.org", "c7.swiftp.org", "c8.swiftp.org", "c9.swiftp.org" };
    }

    // We should randomly permute the server list in order to spread
    // load between servers. Collections offers a shuffle() function 
    // that does this, so we'll convert to List and back to String[].
    List<String> proxyList = Arrays.asList(allProxies);
    Collections.shuffle(proxyList);
    allProxies = proxyList.toArray(new String[] {}); // arg used for type

    // Return preferred server first, followed by all others
    if (preferred == null) {
        return allProxies;
    } else {
        return Util.concatStrArrays(new String[] { preferred }, allProxies);
    }
}

From source file:com.twitter.graphjet.bipartite.edgepool.EdgePoolConcurrentTestHelper.java

/**
 * This helper method sets up a concurrent read-write situation with a single writer and multiple
 * readers that access the same underlying edgePool, and tests for correct edge access during
 * simultaneous edge writes. This helps test read consistency during arbitrary points of
 * inserting edges. Note that the exact read-write sequence here is non-deterministic and would
 * vary depending on the machine, but the hope is that given the large number of readers the reads
 * would be done at many different points of edge insertion. The test itself checks only for
 * partial correctness (it could have false positives) so this should only be used as a supplement
 * to other testing.//from w  ww . j  a  v a  2s .com
 *
 * @param edgePool           is the underlying
 *                           {@link com.twitter.graphjet.bipartite.edgepool.EdgePool}
 * @param numReadersPerNode  is the number of reader threads to use per node
 * @param leftSize           is the number of left nodes
 * @param rightSize          is the number of right nodes
 * @param edgeProbability    is the probability of an edge between a left-right node pair
 * @param random             is the random number generator to use for generating a random graph
 */
public static void testRandomConcurrentReadWriteThreads(EdgePool edgePool, int numReadersPerNode, int leftSize,
        int rightSize, double edgeProbability, Random random) {
    int maxWaitingTimeForThreads = 20; // in milliseconds
    int numReaders = leftSize * numReadersPerNode;
    CountDownLatch readersDoneLatch = new CountDownLatch(numReaders);
    // First, construct a random set of edges to insert in the graph
    Set<Pair<Integer, Integer>> edges = Sets
            .newHashSetWithExpectedSize((int) (leftSize * rightSize * edgeProbability));
    List<EdgePoolReader> readers = Lists.newArrayListWithCapacity(numReaders);
    Int2ObjectMap<IntSet> leftSideGraph = new Int2ObjectOpenHashMap<IntSet>(leftSize);
    int averageLeftDegree = (int) (rightSize * edgeProbability);
    for (int i = 0; i < leftSize; i++) {
        IntSet nodeEdges = new IntOpenHashSet(averageLeftDegree);
        for (int j = 0; j < rightSize; j++) {
            if (random.nextDouble() < edgeProbability) {
                nodeEdges.add(j);
                edges.add(Pair.of(i, j));
            }
        }
        leftSideGraph.put(i, nodeEdges);
    }

    // Create a bunch of leftReaders per node that'll read from the graph at random
    for (int i = 0; i < leftSize; i++) {
        for (int j = 0; j < numReadersPerNode; j++) {
            readers.add(new EdgePoolReader(edgePool, new CountDownLatch(0), readersDoneLatch, i,
                    random.nextInt(maxWaitingTimeForThreads)));
        }
    }

    // Create a single writer that will insert these edges in random order
    List<WriterInfo> writerInfo = Lists.newArrayListWithCapacity(edges.size());
    List<Pair<Integer, Integer>> edgesList = Lists.newArrayList(edges);
    Collections.shuffle(edgesList);
    CountDownLatch writerDoneLatch = new CountDownLatch(edgesList.size());
    for (Pair<Integer, Integer> edge : edgesList) {
        writerInfo.add(new WriterInfo(edge.getLeft(), edge.getRight(), new CountDownLatch(0), writerDoneLatch));
    }

    ExecutorService executor = Executors.newFixedThreadPool(numReaders + 1); // single writer
    List<Callable<Integer>> allThreads = Lists.newArrayListWithCapacity(numReaders + 1);
    // First, we add the writer
    allThreads.add(Executors.callable(new EdgePoolWriter(edgePool, writerInfo), 1));
    // then the readers
    for (int i = 0; i < numReaders; i++) {
        allThreads.add(Executors.callable(readers.get(i), 1));
    }
    // these will execute in some non-deterministic order
    Collections.shuffle(allThreads, random);

    // Wait for all the processes to finish
    try {
        List<Future<Integer>> results = executor.invokeAll(allThreads, 10, TimeUnit.SECONDS);
        for (Future<Integer> result : results) {
            assertTrue(result.isDone());
            assertEquals(1, result.get().intValue());
        }
    } catch (InterruptedException e) {
        throw new RuntimeException("Execution for a thread was interrupted: ", e);
    } catch (ExecutionException e) {
        throw new RuntimeException("Execution issue in an executor thread: ", e);
    }

    // confirm that these worked as expected
    try {
        readersDoneLatch.await();
        writerDoneLatch.await();
    } catch (InterruptedException e) {
        throw new RuntimeException("Execution for last reader was interrupted: ", e);
    }

    // Check that all readers' read info is consistent with the graph
    for (EdgePoolReader reader : readers) {
        IntSet expectedEdges = leftSideGraph.get(reader.queryNode);
        assertTrue(reader.getQueryNodeDegree() <= expectedEdges.size());
        if (reader.getQueryNodeDegree() == 0) {
            assertNull(reader.getQueryNodeEdges());
        } else {
            for (int edge : reader.getQueryNodeEdges()) {
                assertTrue(expectedEdges.contains(edge));
            }
        }
    }
}

From source file:net.sourceforge.kalimbaradio.androidapp.service.DownloadServiceImpl.java

@Override
public synchronized void shuffle() {
    Collections.shuffle(downloadList);
    if (currentPlaying != null) {
        downloadList.remove(getCurrentPlayingIndex());
        downloadList.add(0, currentPlaying);
    }/* w w  w.  ja v  a2 s . com*/
    revision++;
    lifecycleSupport.serializeDownloadQueue();
    updateJukeboxPlaylist();
}

From source file:com.pinterest.teletraan.worker.HealthChecker.java

/**
 * Step 1. Launch new instance with latest ami
 * If AWS Launch Instance API call failed, send wanring message and move the state to completed to skip terminate instance process
 * If launch successfully, update hostDAO
 *///  w w  w. ja  v a 2 s .c om
private void processInitState(HealthCheckBean healthCheckBean, GroupBean groupBean) throws Exception {
    String groupName = groupBean.getGroup_name();
    LOG.info("Start to launch instance for group {} and healthCheck id {} at health check state {}", groupName,
            healthCheckBean.getId(), healthCheckBean.getState().toString());

    // Randomly pick a subnet to launch instance to
    List<String> subnets = Arrays.asList(groupBean.getSubnets().split(","));
    Collections.shuffle(subnets);
    String subnet = subnets.get(0);

    LOG.info("Start to launch instance with AMI ID {} to Subnet {} for group {}", healthCheckBean.getAmi_id(),
            subnet, groupName);
    groupBean.setImage_id(healthCheckBean.getAmi_id());
    List<HostBean> hosts = hostInfoDAO.launchEC2Instances(groupBean, 1, subnet);
    if (hosts.isEmpty()) {
        LOG.error("Failed to launch instance with AMI ID {} to Subnet {} for group {}",
                healthCheckBean.getAmi_id(), subnet, groupName);
        String subject = String.format("Health Check Warning - Launch Instance Failed in group <%s>",
                groupName);
        String errorMessage = String.format(
                "AWS Launch Instance API call failed (AMI Id: %s, Subnet: %s) in group %s",
                healthCheckBean.getAmi_id(), subnet, groupName);
        failedHealthCheckAlertJob(healthCheckBean, groupBean, subject, errorMessage);
        return;
    }

    HostBean host = hosts.get(0);
    LOG.info("Successfully launched host id {} for group {}", host.getHost_id(), groupName);
    try {
        hostDAO.insert(host);
    } catch (Exception e) {
        LOG.error("Failed to insert new host id {} to hostDAO", host.getHost_id(), e);
    }

    healthCheckBean.setHost_id(host.getHost_id());
    healthCheckBean.setHost_launch_time(host.getCreate_date());
    healthCheckBean.setHost_terminated(false);
    transistionState(healthCheckBean, HealthCheckState.LAUNCHING, HealthCheckStatus.SUCCEEDED, "");
    LOG.info("Health Check Succeeded: id {}, group {}, state {}", healthCheckBean.getId(), groupName,
            healthCheckBean.getState());
}

From source file:malware_classification.Malware_Classification.java

private double cross_validation(double[][] all_data, int k) {
    ArrayList<Integer> all_indices = new ArrayList<>();
    for (int i = 0; i < all_data.length; i++) {
        all_indices.add(i);/*from  w  w w  .ja  va  2  s.c  o m*/
    }
    Collections.shuffle(all_indices);
    int entries_per_trial = all_data.length / k;
    TestResults test_results = new TestResults();
    TestResults train_results = new TestResults();
    for (int i = 0; i < k; i++) {
        logger.log(Level.INFO, "Beginning cross validation " + i + " of " + k);
        int min_index = entries_per_trial * i;
        int max_index = (i == k - 1) ? all_data.length : entries_per_trial * (i + 1);
        double[][] test_data = get_indices_from_array_inclusive(all_data, min_index, max_index, all_indices);
        double[][] train_data = get_indices_from_array_exclusive(all_data, min_index, max_index, all_indices);

        logger.log(Level.INFO, "Beginning training");
        svm_model model = svm_train(train_data);
        logger.log(Level.INFO, "Beginning testing");
        svm_evaluate(test_data, model, test_results);
        svm_evaluate(train_data, model, train_results);
    }
    logger.info("Test results (proportion incorrect):\n" + test_results.toString());
    logger.info("Train results (proportion incorrect):\n" + train_results.toString());
    double full_result = 1 - ((double) test_results.wrong_benign + test_results.wrong_malicious)
            / (test_results.total_benign + test_results.total_malicious);
    logger.info("Proportion CORRECT (both classes, training) = " + full_result);
    return full_result;
}

From source file:forge.quest.BoosterUtils.java

/**
 * Create the list of card names at random from the given pool.
 *
 * @param source//from   ww w  .ja  v a2  s  . c om
 *            an Iterable<CardPrinted>
 * @param filter
 *            Predicate<CardPrinted>
 * @param cntNeeded
 *            an int
 * @param allowedColors
 *            a List<Predicate<CardRules>>
 * @param allowDuplicates
 *            If true, multiple copies of the same card will be allowed to be generated.
 * @return a list of card names
 */
private static List<PaperCard> generateCards(final Iterable<PaperCard> source,
        final Predicate<PaperCard> filter, final int cntNeeded, final List<Predicate<CardRules>> allowedColors,
        final boolean allowDuplicates) {

    //If color is null, use colorOrder progression to grab cards
    final List<PaperCard> result = new ArrayList<>();

    final int size = allowedColors == null ? 0 : allowedColors.size();
    if (allowedColors != null) {
        Collections.shuffle(allowedColors);
    }

    int cntMade = 0, iAttempt = 0;

    //This will prevent endless loop @ wh
    int allowedMisses = (size + 4) * cntNeeded;
    int nullMisses = 0;

    while (cntMade < cntNeeded && allowedMisses > 0) {
        PaperCard card = null;

        if (size > 0) {
            final Predicate<CardRules> color2 = allowedColors.get(iAttempt % size);
            int colorMisses = 0;
            //Try a few times to get a card using the available filter. This is important for sets with only a small
            //handful of multi-colored cards.
            do {
                if (color2 != null) {
                    Predicate<PaperCard> color2c = Predicates.compose(color2, PaperCard.FN_GET_RULES);
                    card = Aggregates.random(Iterables.filter(source, Predicates.and(filter, color2c)));
                }
            } while (card == null && colorMisses++ < 10);
        }

        if (card == null) {
            //We can't decide on a color. We're going to try very hard to pick a color within the current filters.
            if (nullMisses++ < 10) {
                iAttempt++;
                continue;
            }
            nullMisses = 0;
            //Still no luck. We're going to skip generating this card. This will very, very rarely result in fewer
            //cards than expected; however, it will keep unselected colors out of the pool.
        }

        if ((card != null) && (allowDuplicates || !result.contains(card))) {
            result.add(card);
            cntMade++;
        } else {
            allowedMisses--;
        }
        iAttempt++;
    }

    return result;
}

From source file:clummy.classes.DataHandlingClass.java

/**
 * return list of domain names in string
 * @param firstname//  ww  w . j av  a  2 s.  c  o  m
 * @param lastname
 * @return 
 */
public String getEmailAddress(String firstname, String lastname) {
    firstname.replaceAll("\\s+", "");
    lastname.replaceAll("\\s+", "");
    String divider = null;
    List<String> listDomainNames = defaultList.getListOfEmailDomain();
    Collections.shuffle(listDomainNames);
    Collections.shuffle(listDomainNames);
    switch (randBetween(1, 3)) {
    case 1:
        divider = ".";
        break;
    case 2:
        divider = "_";
        break;
    case 3:
        divider = "";
        break;
    case 4:
        if (random.nextBoolean())
            divider = randBetween(0, 999) + "";
        break;
    }
    if (random.nextBoolean())
        if (random.nextBoolean())
            if (random.nextBoolean())
                lastname = lastname + randBetween(0, 999);
    return (firstname + divider + lastname + "@"
            + listDomainNames.get(randBetween(0, listDomainNames.size() - 1))).toLowerCase().replaceAll("\\s+",
                    "");
}

From source file:gdsc.smlm.ij.plugins.FIRE.java

public ImageProcessor[] createImages(float fourierImageScale, int imageSize) {
    ip1 = ip2 = null;//from   ww  w .  j a v a 2  s .  com
    if (results == null || results.size() == 0)
        return null;

    ResultsImage imageType = (results.getResults().get(0).getSignal() > 0) ? ResultsImage.SIGNAL_INTENSITY
            : ResultsImage.LOCALISATIONS;

    // Draw images using the existing IJ routines.
    // TODO - This could be speeded up using a simple 2D-histogram
    Rectangle bounds = results.getBounds(true);
    boolean weighted = true;
    boolean equalised = false;
    if (fourierImageScale == 0)
        this.imageScale = imageSize / (float) FastMath.max(bounds.x + bounds.width, bounds.y + bounds.height);
    else
        // TODO - The coordinates should be adjusted if the max-min can fit inside a smaller power of 2
        this.imageScale = fourierImageScale;

    IJImagePeakResults image1 = ImagePeakResultsFactory.createPeakResultsImage(imageType, weighted, equalised,
            "IP1", bounds, results.getNmPerPixel(), results.getGain(), imageScale, 0, ResultsMode.ADD);
    image1.setDisplayImage(false);
    image1.begin();

    IJImagePeakResults image2 = ImagePeakResultsFactory.createPeakResultsImage(imageType, weighted, equalised,
            "IP2", bounds, results.getNmPerPixel(), results.getGain(), imageScale, 0, ResultsMode.ADD);
    image2.setDisplayImage(false);
    image2.begin();

    List<PeakResult> list = results.getResults();
    if (randomSplit) {
        @SuppressWarnings("unchecked")
        ArrayList<PeakResult> dest = (ArrayList<PeakResult>) ((ArrayList<PeakResult>) list).clone();
        Collections.shuffle(dest);
        list = dest;
    }

    // Split alternating
    int i = 0;
    for (PeakResult p : list) {
        if (i++ % 2 == 0)
            image1.add(p.peak, p.origX, p.origY, p.origValue, p.error, p.noise, p.params, p.paramsStdDev);
        else
            image2.add(p.peak, p.origX, p.origY, p.origValue, p.error, p.noise, p.params, p.paramsStdDev);
    }

    image1.end();
    ip1 = image1.getImagePlus().getProcessor();

    image2.end();
    ip2 = image2.getImagePlus().getProcessor();

    return new ImageProcessor[] { ip1, ip2 };
}

From source file:mase.spec.StochasticHybridExchanger.java

protected MetaPopulation fork(MetaPopulation parent, EvolutionState state) {
    List<Integer> forkAgents = new ArrayList<>();

    if (splitProportion == SplitAgentsProportion.one || parent.agents.size() <= 2) { // A random one is split
        int ag = state.random[0].nextInt(parent.agents.size());
        forkAgents.add(parent.agents.get(ag));
    } else if (splitProportion == SplitAgentsProportion.half) { // A random sample of size = half of agents
        int num = parent.agents.size() / 2;
        List<Integer> copy = new ArrayList<>(parent.agents);
        Collections.shuffle(copy);
        for (int i = 0; i < num; i++) {
            forkAgents.add(copy.get(i));
        }/*from   w  w w.jav a  2  s  .  com*/
    } else if (splitProportion == SplitAgentsProportion.random) { // A random sample of random size
        int num = 1 + state.random[0].nextInt(parent.agents.size() - 1);
        List<Integer> copy = new ArrayList<>(parent.agents);
        Collections.shuffle(copy);
        for (int i = 0; i < num; i++) {
            forkAgents.add(copy.get(i));
        }
    }

    parent.age = 0;
    parent.agents.removeAll(forkAgents);

    MetaPopulation child = new MetaPopulation();
    child.agents.addAll(forkAgents);
    child.pop = (Subpopulation) parent.pop.emptyClone();
    child.pop.individuals = new Individual[parent.pop.individuals.length];
    for (int k = 0; k < parent.pop.individuals.length; k++) {
        child.pop.individuals[k] = (Individual) parent.pop.individuals[k].clone();
    }
    return child;
}

From source file:com.evolveum.midpoint.common.policy.ValuePolicyGenerator.java

public static String generate(StringPolicyType policy, int defaultLength, boolean generateMinimalSize,
        OperationResult inputResult) {//from   www . j  a v  a  2  s  .c o m

    if (null == policy) {
        throw new IllegalArgumentException("Provided password policy can not be null.");
    }

    if (null == inputResult) {
        throw new IllegalArgumentException("Provided operation result cannot be null");
    }
    // Define result from generator
    OperationResult generatorResult = new OperationResult(
            "Password generator running policy :" + policy.getDescription());
    inputResult.addSubresult(generatorResult);

    // if (policy.getLimitations() != null &&
    // policy.getLimitations().getMinLength() != null){
    // generateMinimalSize = true;
    // }
    // setup default values where missing
    // PasswordPolicyUtils.normalize(pp);

    // Optimize usage of limits ass hashmap of limitas and key is set of
    // valid chars for each limitation
    HashMap<StringLimitType, ArrayList<String>> lims = new HashMap<StringLimitType, ArrayList<String>>();
    for (StringLimitType l : policy.getLimitations().getLimit()) {
        if (null != l.getCharacterClass().getValue()) {
            lims.put(l, StringPolicyUtils.stringTokenizer(l.getCharacterClass().getValue()));
        } else {
            lims.put(l, StringPolicyUtils.stringTokenizer(StringPolicyUtils
                    .collectCharacterClass(policy.getCharacterClass(), l.getCharacterClass().getRef())));
        }
    }

    // Get global limitations
    int minLen = policy.getLimitations().getMinLength() == null ? 0
            : policy.getLimitations().getMinLength().intValue();
    if (minLen != 0 && minLen > defaultLength) {
        defaultLength = minLen;
    }
    int maxLen = (policy.getLimitations().getMaxLength() == null ? 0
            : policy.getLimitations().getMaxLength().intValue());
    int unique = policy.getLimitations().getMinUniqueChars() == null ? minLen
            : policy.getLimitations().getMinUniqueChars().intValue();

    // test correctness of definition
    if (unique > minLen) {
        minLen = unique;
        OperationResult reportBug = new OperationResult("Global limitation check");
        reportBug.recordWarning(
                "There is more required uniq characters then definied minimum. Raise minimum to number of required uniq chars.");
    }

    if (minLen == 0 && maxLen == 0) {
        minLen = defaultLength;
        maxLen = defaultLength;
        generateMinimalSize = true;
    }

    if (maxLen == 0) {
        if (minLen > defaultLength) {
            maxLen = minLen;
        } else {
            maxLen = defaultLength;
        }
    }

    // Initialize generator
    StringBuilder password = new StringBuilder();

    /* **********************************
     * Try to find best characters to be first in password
     */
    HashMap<StringLimitType, ArrayList<String>> mustBeFirst = new HashMap<StringLimitType, ArrayList<String>>();
    for (StringLimitType l : lims.keySet()) {
        if (l.isMustBeFirst() != null && l.isMustBeFirst()) {
            mustBeFirst.put(l, lims.get(l));
        }
    }

    // If any limitation was found to be first
    if (!mustBeFirst.isEmpty()) {
        HashMap<Integer, ArrayList<String>> posibleFirstChars = cardinalityCounter(mustBeFirst, null, false,
                false, generatorResult);
        int intersectionCardinality = mustBeFirst.keySet().size();
        ArrayList<String> intersectionCharacters = posibleFirstChars.get(intersectionCardinality);
        // If no intersection was found then raise error
        if (null == intersectionCharacters || intersectionCharacters.size() == 0) {
            generatorResult
                    .recordFatalError("No intersection for required first character sets in password policy:"
                            + policy.getDescription());
            // Log error
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error(
                        "Unable to generate password: No intersection for required first character sets in password policy: ["
                                + policy.getDescription()
                                + "] following character limitation and sets are used:");
                for (StringLimitType l : mustBeFirst.keySet()) {
                    StrBuilder tmp = new StrBuilder();
                    tmp.appendSeparator(", ");
                    tmp.appendAll(mustBeFirst.get(l));
                    LOGGER.error("L:" + l.getDescription() + " -> [" + tmp + "]");
                }
            }
            // No more processing unrecoverable conflict
            return null; // EXIT
        } else {
            if (LOGGER.isDebugEnabled()) {
                StrBuilder tmp = new StrBuilder();
                tmp.appendSeparator(", ");
                tmp.appendAll(intersectionCharacters);
                LOGGER.trace("Generate first character intersection items [" + tmp + "] into password.");
            }
            // Generate random char into password from intersection
            password.append(intersectionCharacters.get(rand.nextInt(intersectionCharacters.size())));
        }
    }

    /* **************************************
     * Generate rest to fulfill minimal criteria
     */

    boolean uniquenessReached = false;

    // Count cardinality of elements
    HashMap<Integer, ArrayList<String>> chars;
    for (int i = 0; i < minLen; i++) {

        // Check if still unique chars are needed
        if (password.length() >= unique) {
            uniquenessReached = true;
        }
        // Find all usable characters
        chars = cardinalityCounter(lims, StringPolicyUtils.stringTokenizer(password.toString()), false,
                uniquenessReached, generatorResult);
        // If something goes badly then go out
        if (null == chars) {
            return null;
        }

        if (chars.isEmpty()) {
            LOGGER.trace("Minimal criterias was met. No more characters");
            break;
        }
        // Find lowest possible cardinality and then generate char
        for (int card = 1; card < lims.keySet().size(); card++) {
            if (chars.containsKey(card)) {
                ArrayList<String> validChars = chars.get(card);
                password.append(validChars.get(rand.nextInt(validChars.size())));
                //               LOGGER.trace(password.toString());
                break;
            }
        }
    }

    // test if maximum is not exceeded
    if (password.length() > maxLen) {
        generatorResult
                .recordFatalError("Unable to meet minimal criteria and not exceed maximxal size of password.");
        return null;
    }

    /* ***************************************
     * Generate chars to not exceed maximal
     */

    for (int i = 0; i < minLen; i++) {
        // test if max is reached
        if (password.length() == maxLen) {
            // no more characters maximal size is reached
            break;
        }

        if (password.length() >= minLen && generateMinimalSize) {
            // no more characters are needed
            break;
        }

        // Check if still unique chars are needed
        if (password.length() >= unique) {
            uniquenessReached = true;
        }
        // find all usable characters
        chars = cardinalityCounter(lims, StringPolicyUtils.stringTokenizer(password.toString()), true,
                uniquenessReached, generatorResult);

        // If something goes badly then go out
        if (null == chars) {
            // we hope this never happend.
            generatorResult
                    .recordFatalError("No valid characters to generate, but no all limitation are reached");
            return null;
        }

        // if selection is empty then no more characters and we can close
        // our work
        if (chars.isEmpty()) {
            if (i == 0) {
                password.append(RandomStringUtils.randomAlphanumeric(minLen));

            }
            break;
            //            if (!StringUtils.isBlank(password.toString()) && password.length() >= minLen) {
            //               break;
            //            }
            // check uf this is a firs cycle and if we need to user some
            // default (alphanum) character class.

        }

        // Find lowest possible cardinality and then generate char
        for (int card = 1; card <= lims.keySet().size(); card++) {
            if (chars.containsKey(card)) {
                ArrayList<String> validChars = chars.get(card);
                password.append(validChars.get(rand.nextInt(validChars.size())));
                //               LOGGER.trace(password.toString());
                break;
            }
        }
    }

    if (password.length() < minLen) {
        generatorResult.recordFatalError(
                "Unable to generate password and meet minimal size of password. Password lenght: "
                        + password.length() + ", required: " + minLen);
        LOGGER.trace(
                "Unable to generate password and meet minimal size of password. Password lenght: {}, required: {}",
                password.length(), minLen);
        return null;
    }

    generatorResult.recordSuccess();

    // Shuffle output to solve pattern like output
    StrBuilder sb = new StrBuilder(password.substring(0, 1));
    ArrayList<String> shuffleBuffer = StringPolicyUtils.stringTokenizer(password.substring(1));
    Collections.shuffle(shuffleBuffer);
    sb.appendAll(shuffleBuffer);

    return sb.toString();
}