public function generate($iGroupId)
    {
        $aPwRules = $this->getRules($iGroupId);
        $aPwOut   = [];

        // --------------------------------------------------------------------------

        /**
         * We're generating a password, define all the charsets to use, at the very
         * ;east have the lower_alpha charset.
         */

        $aCharsets   = [];
        $aCharsets[] = $this->aCharset['lower_alpha'];

        if (!empty($aPwRules['requirements'])) {
            foreach ($aPwRules['requirements'] as $sRequirement => $bValue) {

                switch ($sRequirement) {
                    case 'symbol':
                        $aCharsets[] = $this->aCharset['symbol'];
                        break;

                    case 'number':
                        $aCharsets[] = $this->aCharset['number'];
                        break;

                    case 'upper_alpha':
                        $aCharsets[] = $this->aCharset['upper_alpha'];
                        break;
                }
            }
        }

        // --------------------------------------------------------------------------

        //  Work out the min length
        $iMin = getFromArray('min', $aPwRules);
        if (empty($iMin)) {
            $iMin = 8;
        }

        //  Work out the max length
        $iMax = getFromArray('max', $aPwRules);
        if (empty($iMax) || $iMin > $iMax) {
            $iMax = $iMin + count($aCharsets) * 2;
        }

        // --------------------------------------------------------------------------

        //  We now have a max_length and all our chars, generate password!
        $bPwValid = true;
        do {
            do {
                foreach ($aCharsets as $sCharset) {
                    $sCharacter = rand(0, strlen($sCharset) - 1);
                    $aPwOut[]   = $sCharset[$sCharacter];
                }
            } while (count($aPwOut) < $iMax);

            //  Check password isn't a prohibited string
            if (!empty($aPwRules['banned'])) {
                foreach ($aPwRules['banned'] as $sString) {
                    if (strtolower(implode('', $aPwOut)) == strtolower($sString)) {
                        $bPwValid = false;
                        break;
                    }
                }
            }

        } while (!$bPwValid);

        // --------------------------------------------------------------------------

        //  Shuffle the string and return
        shuffle($aPwOut);
        return implode('', $aPwOut);
    }