private static void fillArray( final String s1, 
									final String s2, 
									final SubstitutionMatrix sm, 
									final float gapPenalty, 
									final int affinePenalty, 
									final boolean noPenaltyForBeginningOrEndingGaps,
									final AlignmentCell[][] cels )
		throws Exception
	{
		cels[0][0] = new AlignmentCell(START, 0); 
		
		if( noPenaltyForBeginningOrEndingGaps )
		{
			for( int x=1; x <= s1.length(); x++)
				cels[x][0] = new AlignmentCell(LEFT, 0);
			
			for( int x=1; x <= s2.length(); x++)
				cels[0][x] = new AlignmentCell(UP, 0);
		}
		else if( affinePenalty > 0) // linear gap
		{
			final CountDownLatch cdl1 = new CountDownLatch(2);
			
			new Thread( new Runnable()
			{
				
				@Override
				public void run()
				{
					for( int x=1; x <= s1.length(); x++)
						cels[x][0] = new AlignmentCell(LEFT, x * gapPenalty );
					
					cdl1.countDown();
				}
			}).start();;
			
		
			new Thread(
					
				new Runnable()
				{
					
					@Override
					public void run()
					{
						for( int x=1; x <= s2.length(); x++)
							cels[0][x] = new AlignmentCell(UP, x * gapPenalty);
						
						cdl1.countDown();
					}
				}).start();;
				
				cdl1.await();
		}
		else
		{
			cels[1][0] = new AlignmentCell(LEFT, gapPenalty);
			
			for( int x=2; x <= s1.length(); x++)
				cels[x][0] = new AlignmentCell(LEFT, gapPenalty  + x * affinePenalty);
			
			cels[0][1] = new AlignmentCell(UP, gapPenalty);
			for( int x=2; x <= s2.length(); x++)
				cels[0][x] = new AlignmentCell(UP, gapPenalty + x * affinePenalty);
		
		}
		
		
		Semaphore semaphore = new Semaphore(2);
		AtomicInteger lastX = new AtomicInteger(1);
		AtomicInteger lastY = new AtomicInteger(1);
		
		AlignmentCell cel = getACel(1, 1, affinePenalty, cels, gapPenalty, sm, s1, s2);
			
		cels[1][1] = cel;
			
		semaphore.acquire();
		semaphore.acquire();
			
		new Thread(new RunAStrip(
					affinePenalty, gapPenalty, cels, s1, s2, sm, semaphore,
					true, lastX, lastY)).start();
			
		new Thread(new RunAStrip(
					affinePenalty, gapPenalty, cels, s1, s2, sm, semaphore,
					false, lastX, lastY)).start();
		
		// wait for both threads to finish
		semaphore.acquire();
		semaphore.acquire();
		
		synchronized(cels) {};  // make visible all our published changes to this thread
			
	}