@SuppressWarnings({ "unchecked" })
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String studyPath = req.getPathInfo();

		if (studyPath == null) {
			resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
					"Must specify study path.");
		}

		InputStream in = req.getInputStream();
		OutputStream out = resp.getOutputStream();

		ZOutputStream zOut = null;

		DataInputStream dataIn = null;
		DataOutputStream dataOut = null;

		resp.setContentType("application/octet-stream");

		log.info("Creating streams");

		zOut = new ZOutputStream(out, JZlib.Z_BEST_COMPRESSION);
		dataIn = new DataInputStream(in);
		dataOut = new DataOutputStream(zOut);

		log.info("Starting persistence manager");
		PersistenceManager pm = PMF.get().getPersistenceManager();

		log.info("Creating query");
		Query query = pm.newQuery(Form.class);
		query.setFilter("path == pathParam");
		query.declareParameters("String pathParam");
		query.setRange(0, 1);

		log.info("Building study");
		StudyDefList studyDefList = new StudyDefList();
		StudyDef studyDef = new StudyDef(1, "A study", "varName");
		studyDefList.addStudy(studyDef);

		log.info("Reading download header from client");
		String username = dataIn.readUTF();
		String password = dataIn.readUTF();
		String serializer = dataIn.readUTF();
		String locale = dataIn.readUTF();
		String action = req.getParameter("action");

		log.info("Header received: username=" + username + ", password="
				+ password + ", serializer=" + serializer + ", locale="
				+ locale + ", action=" + action);

		try {

			log.info("Reading action");
			byte actionByte = dataIn.readByte();

			if (actionByte == ACTION_DOWNLOAD_USERS) {
				log.info("Downloading users");
				dataOut.writeByte(STATUS_SUCCESS);
				writeUserList(dataOut);
			} else if (actionByte == ACTION_DOWNLOAD_STUDY_LIST) {
				log.info("Downloading study list");
				dataOut.writeByte(STATUS_SUCCESS);
				studyDefList.write(dataOut);
			} else if (actionByte == ACTION_DOWNLOAD_USERS_AND_FORMS) {
				log.info("Downloading users and forms");
				dataOut.writeByte(STATUS_SUCCESS);
				writeUserList(dataOut);
				try {
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					DataOutputStream mdos = new DataOutputStream(baos);
					mdos.writeInt(studyDef.getId());
					mdos.writeUTF(studyDef.getName());
					mdos.writeUTF(studyDef.getVariableName());
					mdos.writeShort(1);

					List<Form> forms = (List<Form>) query.execute(studyPath);
					if (!forms.isEmpty()) {
						byte[] formContent = forms.get(0).getFormContent()
								.getBytes();
						mdos.write(formContent);
					}

					byte[] studyBytes = baos.toByteArray();
					dataOut.writeInt(studyBytes.length);
					dataOut.write(studyBytes);

				} finally {
					pm.close();
				}
			} else {
				log.warning("Unknown action received. Action=" + actionByte);
			}
		} catch (Exception e) {
			log.log(Level.WARNING,
					"Failed to download form for path " + req.getPathInfo(), e);
		} finally {
			if (dataOut != null)
				dataOut.flush();
			if (zOut != null)
				zOut.finish();
			resp.flushBuffer();
		}
	}