	public JobStatus run() {
		UserPreferences userPrefs = new UserPreferences();
		SocrataConnectionInfo connectionInfo = userPrefs.getConnectionInfo();
		UpsertResult result = null;
		JobStatus runStatus = JobStatus.SUCCESS;
		JobStatus validationStatus = validate(connectionInfo);
		if(validationStatus.isError()) {
			runStatus = validationStatus;
		} else {
			final Soda2Producer producer = Soda2Producer.newProducer(connectionInfo.getUrl(), connectionInfo.getUser(), connectionInfo.getPassword(), connectionInfo.getToken());
			final SodaImporter importer = SodaImporter.newImporter(connectionInfo.getUrl(), connectionInfo.getUser(), connectionInfo.getPassword(), connectionInfo.getToken());
			File fileToPublishFile = new File(fileToPublish);
			File deleteRowsFile = null;
			if(!fileRowsToDelete.equals(DELETE_ZERO_ROWS)) {
				deleteRowsFile = new File(fileRowsToDelete);
			}
			String errorMessage = "";
			boolean noPublishExceptions = false;
			try {
				if(publishMethod.equals(PublishMethod.upsert)) {
                    if(fileToPublishFile.length() > FILESIZE_CHUNK_CUTOFF_BYTES) {
                        result = IntegrationUtility.upsertInChunks(
                                NUM_ROWS_PER_CHUNK, producer, importer, datasetID, deleteRowsFile, fileToPublishFile);
                    } else {
					    result = IntegrationUtility.upsert(producer, importer, datasetID, deleteRowsFile, fileToPublishFile);
                    }
                    noPublishExceptions = true;
				}
				else if(publishMethod.equals(PublishMethod.append)) {
                    if(fileToPublishFile.length() > FILESIZE_CHUNK_CUTOFF_BYTES) {
                        result = IntegrationUtility.appendInChunks(
                                NUM_ROWS_PER_CHUNK, producer, datasetID, fileToPublishFile);
                    } else {
                        result = IntegrationUtility.append(producer, datasetID, fileToPublishFile);
                    }
                    noPublishExceptions = true;
				}
				else if(publishMethod.equals(PublishMethod.replace)) {
					result = IntegrationUtility.replaceNew(producer, datasetID, fileToPublishFile);
					noPublishExceptions = true;
				} else {
					errorMessage = JobStatus.INVALID_PUBLISH_METHOD.toString();
				}
			}
			catch (IOException ioException) {
				errorMessage = ioException.getMessage();
			} 
			catch (SodaError sodaError) {
				errorMessage = sodaError.getMessage();
			} 
			catch (InterruptedException intrruptException) {
				errorMessage = intrruptException.getMessage();
			}
			catch (Exception other) {
				errorMessage = other.toString() + ": " + other.getMessage();
			}
			finally {
				if(noPublishExceptions) {
					if(result != null) {
						if(result.errorCount() > 0) {
							for (UpsertError upsertErr : result.getErrors()) {
								errorMessage += upsertErr.getError() + " (line "
										+ (upsertErr.getIndex() + 1) + " of file) \n";
							}
							runStatus = JobStatus.PUBLISH_ERROR;
							runStatus.setMessage(errorMessage);
						}
					} else {
						runStatus = JobStatus.SUCCESS;
					}
				} else {
					runStatus = JobStatus.PUBLISH_ERROR;
					runStatus.setMessage(errorMessage);
				}
			}
		}
		String adminEmail = userPrefs.getAdminEmail();
		String logDatasetID = userPrefs.getLogDatasetID();
		JobStatus logStatus = JobStatus.SUCCESS;
		if(!logDatasetID.equals("")) {
			logStatus = IntegrationUtility.addLogEntry(logDatasetID, connectionInfo, this, runStatus, result);
		}
		if(userPrefs.emailUponError() && !adminEmail.equals("")) {
			String errorEmailMessage = "";
			String urlToLogDataset = connectionInfo.getUrl() + "/d/" + logDatasetID;
			if(runStatus.isError()) {
				errorEmailMessage += "There was an error updating a dataset.\n"
						+ "\nDataset: " + connectionInfo.getUrl() + "/d/" + getDatasetID()
						+ "\nFile to be published: " + fileToPublish
						+ "\nPublish method: " + publishMethod
						+ "\nJob File: " + pathToSavedJobFile
						+ "\nError message: " + runStatus.getMessage()
						+ "\nLog dataset: " + urlToLogDataset + "\n\n";
			}
			if(logStatus.isError()) {
				errorEmailMessage += "There was an error updating the log dataset: "
						+ urlToLogDataset + "\n"
						+ "Error message: " + logStatus.getMessage() + "\n\n";
			}
			if(runStatus.isError() || logStatus.isError()) {
				try {
					SMTPMailer.send(adminEmail, "Socrata DataSync Error", errorEmailMessage);
				} catch (Exception e) {
					System.out.println("Error sending email to: " + adminEmail + "\n" + e.getMessage());
				}
			}
		}
		return runStatus;
	}

	public JobStatus run() {
		UserPreferences userPrefs = new UserPreferences();
		SocrataConnectionInfo connectionInfo = userPrefs.getConnectionInfo();
		UpsertResult result = null;
		JobStatus runStatus = JobStatus.SUCCESS;
		JobStatus validationStatus = validate(connectionInfo);
		if(validationStatus.isError()) {
			runStatus = validationStatus;
		} else {
			final Soda2Producer producer = Soda2Producer.newProducer(connectionInfo.getUrl(), connectionInfo.getUser(), connectionInfo.getPassword(), connectionInfo.getToken());
			final SodaImporter importer = SodaImporter.newImporter(connectionInfo.getUrl(), connectionInfo.getUser(), connectionInfo.getPassword(), connectionInfo.getToken());
			File fileToPublishFile = new File(fileToPublish);
			File deleteRowsFile = null;
			if(!fileRowsToDelete.equals(DELETE_ZERO_ROWS)) {
				deleteRowsFile = new File(fileRowsToDelete);
			}
			String errorMessage = "";
			boolean noPublishExceptions = false;
			try {
				if(publishMethod.equals(PublishMethod.upsert)) {
                    if(fileToPublishFile.length() > FILESIZE_CHUNK_CUTOFF_BYTES) {
                        result = IntegrationUtility.upsertInChunks(
                                NUM_ROWS_PER_CHUNK, producer, importer, datasetID, deleteRowsFile, fileToPublishFile);
                    } else {
					    result = IntegrationUtility.upsert(producer, importer, datasetID, deleteRowsFile, fileToPublishFile);
                    }
                    noPublishExceptions = true;
				}
				else if(publishMethod.equals(PublishMethod.append)) {
                    if(fileToPublishFile.length() > FILESIZE_CHUNK_CUTOFF_BYTES) {
                        result = IntegrationUtility.appendInChunks(
                                NUM_ROWS_PER_CHUNK, producer, datasetID, fileToPublishFile);
                    } else {
                        result = IntegrationUtility.append(producer, datasetID, fileToPublishFile);
                    }
                    noPublishExceptions = true;
				}
				else if(publishMethod.equals(PublishMethod.replace)) {
					result = IntegrationUtility.replaceNew(producer, datasetID, fileToPublishFile);
					noPublishExceptions = true;
				} else {
					errorMessage = JobStatus.INVALID_PUBLISH_METHOD.toString();
				}
			}
			catch (IOException ioException) {
				errorMessage = ioException.getMessage();
			} 
			catch (SodaError sodaError) {
                errorMessage = sodaError.getMessage();
			} 
			catch (InterruptedException intrruptException) {
				errorMessage = intrruptException.getMessage();
			}
			catch (Exception other) {
				errorMessage = other.toString() + ": " + other.getMessage();
			}
			finally {
				if(noPublishExceptions) {
					if(result != null) {
                        if(result.errorCount() > 0) {
							for (UpsertError upsertErr : result.getErrors()) {
								errorMessage += upsertErr.getError() + " (line "
										+ (upsertErr.getIndex() + 1) + " of file) \n";
							}
							runStatus = JobStatus.PUBLISH_ERROR;
							runStatus.setMessage(errorMessage);
						} else {
                        }
					} else {
						runStatus = JobStatus.SUCCESS;
					}
				} else {
					runStatus = JobStatus.PUBLISH_ERROR;
					runStatus.setMessage(errorMessage);
				}
			}
		}
		String adminEmail = userPrefs.getAdminEmail();
		String logDatasetID = userPrefs.getLogDatasetID();
		JobStatus logStatus = JobStatus.SUCCESS;
		if(!logDatasetID.equals("")) {
			logStatus = IntegrationUtility.addLogEntry(logDatasetID, connectionInfo, this, runStatus, result);
		}
		if(userPrefs.emailUponError() && !adminEmail.equals("")) {
			String errorEmailMessage = "";
			String urlToLogDataset = connectionInfo.getUrl() + "/d/" + logDatasetID;
			if(runStatus.isError()) {
				errorEmailMessage += "There was an error updating a dataset.\n"
						+ "\nDataset: " + connectionInfo.getUrl() + "/d/" + getDatasetID()
						+ "\nFile to be published: " + fileToPublish
						+ "\nPublish method: " + publishMethod
						+ "\nJob File: " + pathToSavedJobFile
						+ "\nError message: " + runStatus.getMessage()
						+ "\nLog dataset: " + urlToLogDataset + "\n\n";
			}
			if(logStatus.isError()) {
				errorEmailMessage += "There was an error updating the log dataset: "
						+ urlToLogDataset + "\n"
						+ "Error message: " + logStatus.getMessage() + "\n\n";
			}
			if(runStatus.isError() || logStatus.isError()) {
				try {
					SMTPMailer.send(adminEmail, "Socrata DataSync Error", errorEmailMessage);
				} catch (Exception e) {
					System.out.println("Error sending email to: " + adminEmail + "\n" + e.getMessage());
				}
			}
		}
		return runStatus;
	}
