void run(fiftyoneDegreesProvider* provider, char* properties[],
         int propertiesCount, const char *inputFile) {
	char userAgent[1000];
	const char* value;
	int i, j;
	fiftyoneDegreesWorkset *ws = NULL;

	// Get a workset from the pool to perform this match.
	ws = fiftyoneDegreesProviderWorksetGet(provider);

	printf("Starting Offline Processing Example.\n");

	// Opens input and output files.
	char* outputFile = "offlineProcessingOutput.csv";
	FILE* fin = fopen(inputFile, "r");
	FILE* fout = fopen(outputFile, "w");

	// Print CSV headers to output file.
	fprintf(fout, "User-Agent");
	for (j=0;j<propertiesCount;j++) {
		fprintf(fout, "|%s", properties[j]);
	}
	fprintf(fout, "\n");

	// Carries out match for first 20 User-Agents and prints results to
	// output file.
	for (i=0;i<20;i++) {
		fgets(userAgent, sizeof(userAgent), fin);
		userAgent[strlen(userAgent)-1] = '\0';
		fprintf(fout, "%s", userAgent);
		fiftyoneDegreesMatch(ws, userAgent);
		for (j=0;j<propertiesCount;j++) {
			value = getValue(ws, properties[j]);
			fprintf(fout, "|%s", value);
		}
		fprintf(fout, "\n");
	}

	printf("Output Written to %s\n", outputFile);

	// Release workset after match complete and workset no longer required.
	fiftyoneDegreesWorksetRelease(ws);
}
/**
* Demonstrates the dataset, pool and cache reload functionality in a multi
* threaded environment. When a workset is returned to the pool of worksets
* a check is carried out to see if the pool is now inactive and all of the
* worksets have been returned. If both conditions are met the pool is
* freed along with the underlying dataset and cache.
*
* @param inputFile containing HTTP User-Agent strings.
*/
static void runRequests(void* inputFile) {
	fiftyoneDegreesWorkset *ws = NULL;
	unsigned long hashCode = 0;
	char userAgent[1000];
	FILE* fin = fopen((const char*)inputFile, "r");

	while (fgets(userAgent, sizeof(userAgent), fin) != NULL) {
		ws = fiftyoneDegreesProviderWorksetGet(&provider);
		fiftyoneDegreesMatch(ws, userAgent);
		hashCode ^= getHashCode(ws);
		fiftyoneDegreesWorksetRelease(ws);
	}

	fclose(fin);
	printf("Finished with hashcode '%lu'\r\n", hashCode);
	FIFTYONEDEGREES_MUTEX_LOCK(&lock);
	threadsFinished++;
	FIFTYONEDEGREES_MUTEX_UNLOCK(&lock);
}
/**
* Demonstrates the dataset, pool and cache reload functionality in a single
* threaded environment. Since only one thread is available the reload will
* be done as part of the program flow and detection will not be available for
* the very short time that the dataset, pool and cache are being reloaded.
*
* The reload happens every 500 requests. The total number of dataset reloads
* is then returned.
*
* @param inputFile containing HTTP User-Agent strings to use with device
*		  detection.
* @return number of times the dataset, pool and cache were reloaded.
*/
static int runRequest(const char *inputFile) {
	fiftyoneDegreesWorkset *ws = NULL;
	unsigned long hashCode = 0;
	int count = 0, numberOfReloads = 0;
	char userAgent[1000];
	char *fileInMemory;
	char *pathToFileInMemory;
	long currentFileSize;
	FILE* fin = fopen((const char*)inputFile, "r");
	// In this example the same data file is reloaded from.
	// Store path for use with reloads.
	pathToFileInMemory = (char*)malloc(sizeof(char) *
						(strlen(provider.activePool->dataSet->fileName) + 1));
	memcpy(pathToFileInMemory,
		provider.activePool->dataSet->fileName,
		strlen(provider.activePool->dataSet->fileName) + 1);

	while (fgets(userAgent, sizeof(userAgent), fin) != NULL) {
		ws = fiftyoneDegreesProviderWorksetGet(&provider);
		fiftyoneDegreesMatch(ws, userAgent);
		hashCode ^= getHashCode(ws);
		fiftyoneDegreesWorksetRelease(ws);
		count++;

		if (count % 1000 == 0) {
			// Load file into memory.
			currentFileSize = loadFile(pathToFileInMemory, &fileInMemory);
			// Refresh the current dataset.
			fiftyoneDegreesProviderReloadFromMemory(&provider, (void*)fileInMemory, currentFileSize);

			fiftyoneDegreesDataSet *ds = (fiftyoneDegreesDataSet*)provider.activePool->dataSet;
			// Tell the API to free the memory occupied by the data file.
			ds->memoryToFree = (void*)fileInMemory;
			numberOfReloads++;
		}
	}

	fclose(fin);
	free(pathToFileInMemory);
	printf("Finished with hashcode '%lu'\r\n", hashCode);
	return numberOfReloads;
}