@Override
		protected ReturnValue doInBackground() throws Exception {
			startTime = System.nanoTime();
			//clear out anything still left in the DB
			//  (note that we do this in a lazy manner)
			mStatement.execute("DROP ALL OBJECTS");

			// Unlike phase 1, the script is not given to us in a file,
			//  so we would have to write it to file in order to 
			//   execute RUNSCRIPT
			//  we can avoid the file using this function from the H2 api
			RunScript.execute(mConnection, new StringReader(mSchema));

			// see what tables are in the schema 
			//  (note that the user schema is called PUBLIC by default) 
			ResultSet rsTab = mStatement.executeQuery(
					"SELECT table_name "+
							"FROM information_schema.tables "+
					"WHERE table_schema = 'PUBLIC'");

			tableList = new ArrayList<Table>();
			while(rsTab.next()) {
				//note that column indexing starts from 1
				tableList.add(new Table(rsTab.getString(1), mConnection.createStatement()));
			}
			rsTab.close();
			
			for(Table table : tableList)
			{
				TupleGenerator tupleGenerator = new TupleGenerator(table);
				activeTupleGenerators.add(tupleGenerator);
			}
			
			String groupedQuery1 = getGroupedQuery(mQuery1);
			String groupedQuery2 = getGroupedQuery(mQuery2);

			
			// in this loop, we continually insert tuples into the tables until
			//  either the user cancels, 
			//  or we find differences in the result sets of our two queries
			while(!isCancelled()) {
				List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
				for(final TupleGenerator tupleGenerator : activeTupleGenerators)
				{
					tasks.add(Executors.callable(new Runnable()
					{
						@Override
						public void run()
						{
							try {
								tupleGenerator.generateTuples(mConnection.createStatement(), instanceSize.get());
							} catch (SQLException e) {
								System.err.println("Unable to generate tuples.");
								e.printStackTrace();
							}
						}
					}));
				}
				workers.invokeAll(tasks);
				

				ResultSet rsChk = mStatement.executeQuery(
					"SELECT ("+
							"SELECT COUNT(*) AS diff12 FROM ("+
							groupedQuery1+" EXCEPT "+groupedQuery2+"))" +
							" + "+
							"(SELECT COUNT(*) AS diff21 FROM ("+
							groupedQuery2+" EXCEPT "+groupedQuery1+"))");
				rsChk.next();
				int diffRows = rsChk.getInt(1);
				rsChk.close();
				if(diffRows > 0) 
				{
					endTime = System.nanoTime();
					//we have found an instance such 
					// that the two queries are different
					// let's return them to the user
					
					//like with RUNSCRIPT above, we want to avoid the use
					// of a file, so we can use Script.execute()
					ByteArrayOutputStream outputStream 
						= new ByteArrayOutputStream();
					Script.execute(DB_URL, DB_USER, DB_PASSWORD, outputStream);
					long elapsedTime = endTime - startTime;
					double seconds = (double)elapsedTime/1000000000.0;
					return new ReturnValue(Code.SUCCESS, new ResultInfo(outputStream.toString(), instanceSize.get(), seconds));
				}
				
				if(instanceSize.incrementAndGet() >= maxInstanceSize)
				{
					instanceSize.set(1);
				}
				for(TupleGenerator tupleGenerator : activeTupleGenerators)
				{
					tupleGenerator.clearTable(mStatement);
				}
				
					
			}
			//we are outside the loop, so the user must have canceled
			return new ReturnValue(Code.FAILURE, "No Results - Canceled");
		}