private static String linearCongruenceSteps(int a, int b, final int n) {
        Algorithms.positiveCheck(n);
        StringBuilder lineEnd = buildModLineEnd(n);
        final StringBuilder result = buildLinearCongruence(a, 'x', b, lineEnd);
        final int originalA = a;
        final int originalB = b;
        if (normalizeIntModuloChanges(a, b, n)) {
            a = Algorithms.normalizeIntModulo(a, n);
            b = Algorithms.normalizeIntModulo(b, n);
            result.append(buildLinearCongruence(a, 'x', b, lineEnd));
        }
        if (a == 1)
            return result.toString();
        if ((a == 0) && (b == 0))
            return result.append(INFINITE_SOLUTIONS).toString();
        if ((a == 0) && (b != 0))
            return result.append(NO_SOLUTION).toString();
        
        // Natural solution
        StringBuilder naturalSolution = linearCongruenceStepsNatural(
                originalA, originalB, n, new StringBuilder(128));
        if (naturalSolution.length() != 0)
            return naturalSolution.toString();
        
        // Bezout's identity solution
        final int numberOfSolutions = Algorithms.gcd(a, n);
        result.append(buildGCDEquals(a, n)).append(numberOfSolutions);
        if (b % numberOfSolutions != 0) {
            result.append(NOT_DIVIDES).append(b).append(NEWLINE);
            return result.append(NO_SOLUTION).toString();
        }
        result.append(" | ").append(b).append(NEWLINE);
        result.append(numberOfSolutions).append(" = ").append(a);
        result.append("r + ").append(n).append("s").append(NEWLINE);
        int bezoutCoefficientA; // coeffient r such that ra + sn = gcd(a, n)
        if (a > n) {
            bezoutCoefficientA = Algorithms.bezout(a, n).get(1);
        } else {
            bezoutCoefficientA = Algorithms.bezout(n, a).get(2);
        }
        final int shiftedModulus = n / numberOfSolutions;
        int x = (bezoutCoefficientA * b) / numberOfSolutions;
        x = Algorithms.normalizeIntModulo(x, shiftedModulus);
        result.append("r = ").append(bezoutCoefficientA).append(NEWLINE);
        lineEnd = buildModLineEnd(shiftedModulus);
        result.append("x").append(CONG).append(b).append("r / ");
        result.append(numberOfSolutions).append(lineEnd);
        result.append(buildLinearCongruence(1, 'x', x, lineEnd));
        return result.toString();
    }