private static Cell construct(Sequence s1, Sequence s2, float[][] matrix,
			float o, float e, byte[] pointers, int[] 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] = lengthOfVerticalGap[j];
				} else if (v[j] == h) {
					pointers[l] = Directions.LEFT;
					lengths[l] = 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;
	}