public static String decode(final String origin, final String key, int limit) {
        boolean unlimited = true;
        if (limit > 0) {
            unlimited = false;
        }
        final StringBuilder resultBuf = new StringBuilder();
        final LinkedList<Character> src = (LinkedList) preprocess(origin);

        final int mod = key.length();
        int index = -1;

        while (!src.isEmpty() && (unlimited || limit > 0)) {
            index = (index + 1) % mod;
            final Character current = src.pop();
            // 1 - on retire la valeur 'A' a chaque caractere (source et cle)
            // 2 - On soustrait la valeur du caratère clé
            // 3 - on calcul le resultat modulo 26 (nb lettres dans l'alphabet)
            // 4 - On rajoute 'A' pour obtenir une valeur de caractère valide
            int alphaIndex = (current.charValue() - key.charAt(index))
                    % ALPHABET_SIZE;
            if (alphaIndex < 0) {
                alphaIndex += ALPHABET_SIZE;
            }
            resultBuf.append((char) (alphaIndex + 'A'));
            
            if (!unlimited) {
                limit--;
            }
        }
        return resultBuf.toString();
    }