def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options,
											files):
		"""Uploads the base files (and if necessary, the current ones as well)."""

		def UploadFile(filename, file_id, content, is_binary, status, is_base):
			"""Uploads a file to the server."""
			set_status("uploading " + filename)
			file_too_large = False
			if is_base:
				type = "base"
			else:
				type = "current"
			if len(content) > MAX_UPLOAD_SIZE:
				print ("Not uploading the %s file for %s because it's too large." %
							(type, filename))
				file_too_large = True
				content = ""
			checksum = md5(content).hexdigest()
			if options.verbose > 0 and not file_too_large:
				print "Uploading %s file for %s" % (type, filename)
			url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id)
			form_fields = [
				("filename", filename),
				("status", status),
				("checksum", checksum),
				("is_binary", str(is_binary)),
				("is_current", str(not is_base)),
			]
			if file_too_large:
				form_fields.append(("file_too_large", "1"))
			if options.email:
				form_fields.append(("user", options.email))
			ctype, body = EncodeMultipartFormData(form_fields, [("data", filename, content)])
			response_body = rpc_server.Send(url, body, content_type=ctype)
			if not response_body.startswith("OK"):
				StatusUpdate("  --> %s" % response_body)
				sys.exit(1)

		# Don't want to spawn too many threads, nor do we want to
		# hit Rietveld too hard, or it will start serving 500 errors.
		# When 8 works, it's no better than 4, and sometimes 8 is
		# too many for Rietveld to handle.
		MAX_PARALLEL_UPLOADS = 4

		sema = threading.BoundedSemaphore(MAX_PARALLEL_UPLOADS)
		upload_threads = []
		finished_upload_threads = []
		
		class UploadFileThread(threading.Thread):
			def __init__(self, args):
				threading.Thread.__init__(self)
				self.args = args
			def run(self):
				UploadFile(*self.args)
				finished_upload_threads.append(self)
				sema.release()

		def StartUploadFile(*args):
			sema.acquire()
			while len(finished_upload_threads) > 0:
				t = finished_upload_threads.pop()
				upload_threads.remove(t)
				t.join()
			t = UploadFileThread(args)
			upload_threads.append(t)
			t.start()

		def WaitForUploads():			
			for t in upload_threads:
				t.join()

		patches = dict()
		[patches.setdefault(v, k) for k, v in patch_list]
		for filename in patches.keys():
			base_content, new_content, is_binary, status = files[filename]
			file_id_str = patches.get(filename)
			if file_id_str.find("nobase") != -1:
				base_content = None
				file_id_str = file_id_str[file_id_str.rfind("_") + 1:]
			file_id = int(file_id_str)
			if base_content != None:
				StartUploadFile(filename, file_id, base_content, is_binary, status, True)
			if new_content != None:
				StartUploadFile(filename, file_id, new_content, is_binary, status, False)
		WaitForUploads()