public static Alignment align(Sequence s1, Sequence s2, Matrix matrix,
			float o, float e) {
		logger.info("Started...");
		long start = System.currentTimeMillis();
		float[][] scores = matrix.getScores();

		int m = s1.length() + 1;
		int n = s2.length() + 1;

		byte[] pointers = new byte[m * n];

		// Initializes the boundaries of the traceback matrix to STOP.
		for (int i = 0, k = 0; i < m; i++, k += n) {
			pointers[k] = Directions.STOP;
		}
		for (int j = 1; j < n; j++) {
			pointers[j] = Directions.STOP;
		}

		short[] sizesOfVerticalGaps = new short[m * n];
		short[] sizesOfHorizontalGaps = new short[m * n];
		for (int i = 0, k = 0; i < m; i++, k += n) {
			for (int j = 0; j < n; j++) {
				sizesOfVerticalGaps[k + j] = sizesOfHorizontalGaps[k + j] = 1;
			}
		}

		Cell cell = SmithWatermanGotoh.construct(s1, s2, scores, o, e,
				pointers, sizesOfVerticalGaps, sizesOfHorizontalGaps);
		Alignment alignment = SmithWatermanGotoh.traceback(s1, s2, matrix,
				pointers, cell, sizesOfVerticalGaps, sizesOfHorizontalGaps);
		alignment.setOriginalSequence1(s1);
		alignment.setOriginalSequence2(s2);
		alignment.setMatrix(matrix);
		alignment.setOpen(o);
		alignment.setExtend(e);
		if (s1.getId() != null) {
			alignment.setName1(s1.getId());
		}
		if (s2.getId() != null) {
			alignment.setName2(s2.getId());
		}
                String msg = "Finished in " + (System.currentTimeMillis() - start) + " milliseconds";
		logger.info(msg);
		return alignment;
	}