private static Cell construct(Sequence s1, Sequence s2, float[][] matrix,
            float o, float e, byte[] pointers, short[] lengths) {

        logger.info("Started...");

        char[] a1 = s1.toArray();
        char[] a2 = s2.toArray();

        int m = s1.length() + 1; // number of rows in similarity matrix
        int n = s2.length() + 1; // number of columns in similarity matrix

        float[] v = new float[n];
        float vDiagonal = 0;// Float.NEGATIVE_INFINITY; // best score in cell
        float f = Float.NEGATIVE_INFINITY; // score from diagonal
        float h = Float.NEGATIVE_INFINITY; // best score ending with gap from
        // left
        float[] g = new float[n]; // best score ending with gap from above

        // Initialization of v and g
        g[0] = Float.NEGATIVE_INFINITY;
        for (int j = 1; j < n; j++) {
            v[j] = 0;// -o - (j - 1) * e;
            g[j] = Float.NEGATIVE_INFINITY;
        }

        int lengthOfHorizontalGap = 0;
        int[] lengthOfVerticalGap = new int[n];

        float similarityScore;
        float maximumScore = Float.NEGATIVE_INFINITY;
        int maxi = 0;
        int maxj = 0;

        // Fill the matrices
        for (int i = 1, k = n; i < m; i++, k += n) { // for all rows
            v[0] = -o - (i - 1) * e;
            for (int j = 1, l = k + 1; j < n; j++, l++) { // for all columns

                similarityScore = matrix[a1[i - 1]][a2[j - 1]];

                f = vDiagonal + similarityScore;// from diagonal

                // Which cell from the left?
                if (h - e >= v[j - 1] - o) {
                    h -= e;
                    lengthOfHorizontalGap++;
                } else {
                    h = v[j - 1] - o;
                    lengthOfHorizontalGap = 1;
                }

                // Which cell from above?
                if (g[j] - e >= v[j] - o) {
                    g[j] = g[j] - e;
                    lengthOfVerticalGap[j] = lengthOfVerticalGap[j] + 1;
                } else {
                    g[j] = v[j] - o;
                    lengthOfVerticalGap[j] = 1;
                }

                vDiagonal = v[j];
                v[j] = maximum(f, g[j], h); // best one
                if (v[j] > maximumScore) {
                    maximumScore = v[j];
                    maxi = i;
                    maxj = j;
                }

                // Determine the traceback direction
                if (v[j] == f) {
                    pointers[l] = Directions.DIAGONAL;
                } else if (v[j] == g[j]) {
                    pointers[l] = Directions.UP;
                    lengths[l] = (short) lengthOfVerticalGap[j];
                } else if (v[j] == h) {
                    pointers[l] = Directions.LEFT;
                    lengths[l] = (short) lengthOfHorizontalGap;
                }

            } // loop columns

            // Reset
            h = Float.NEGATIVE_INFINITY;
            vDiagonal = 0;// -o - (i - 1) * e;

            lengthOfHorizontalGap = 0;

        } // loop rows

        Cell cell = new Cell();
        cell.set(maxi, maxj, v[n - 1]);

        logger.info("Finished.");

        return cell;
    }