public FileInfo uploadMultiFile(boolean overwrite, File data) throws MultiCloudException, OAuth2SettingsException, InterruptedException {
		synchronized (lock) {
			if (op != null) {
				throw new MultiCloudException("Concurrent operation forbidden.");
			}
		}
		if (fileMultiUploadDestinations.size() == 0) {
			throw new MultiCloudException("No destination supplied.");
		}
		if (data.isDirectory()) {
			throw new MultiCloudException("Source must be a file.");
		}
		for (FileCloudSource destination: fileMultiUploadDestinations) {
			if (destination.getToken().isExpired()) {
				refreshAccount(destination.getAccountName(), null);
			}
		}
		synchronized (lock) {
			op = new FileUploadOp(fileMultiUploadDestinations, overwrite, data, listener);
		}
		try {
			op.execute();
		} catch (MultiCloudException e) {
			fileMultiUploadDestinations.clear();
			synchronized (lock) {
				op = null;
			}
			throw e;
		}
		fileMultiUploadDestinations.clear();
		lastError = op.getError();
		if (op.isAborted()) {
			synchronized (lock) {
				op = null;
			}
			throw new AbortedException("Operation aborted.");
		}
		FileInfo result = ((FileUploadOp) op).getResult();
		if (!((FileUploadOp) op).isDone()) {
			synchronized (lock) {
				op = null;
			}
			throw new MultiCloudException("Failed to upload the file to one or more destinations.");
		}
		synchronized (lock) {
			op = null;
		}
		return result;
	}