gt: 		int restCount = Util.getResultsSize(results);
context: /**
   * This Source Code Form is subject to the terms of the Mozilla Public License,
   * v. 2.0. If a copy of the MPL was not distributed with this file, You can
   * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
   * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
   *
   * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
   * graphic logo is a trademark of OpenMRS Inc.
   */
  package org.openmrs.module.webservices.rest.web.v1_0.controller.openmrs1_9;
  
  import java.util.Arrays;
  import java.util.Date;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.commons.beanutils.PropertyUtils;
  import org.junit.Before;
  import org.junit.Test;
  import org.openmrs.Person;
  import org.openmrs.PersonAddress;
  import org.openmrs.PersonAttribute;
  import org.openmrs.PersonName;
  import org.openmrs.api.PersonService;
  import org.openmrs.api.context.Context;
  import org.openmrs.module.webservices.rest.SimpleObject;
  import org.openmrs.module.webservices.rest.test.Util;
  import org.openmrs.module.webservices.rest.web.ConversionUtil;
  import org.openmrs.module.webservices.rest.web.RestConstants;
  import org.openmrs.module.webservices.rest.web.RestTestConstants1_8;
  import org.openmrs.module.webservices.rest.web.representation.Representation;
  import org.openmrs.module.webservices.rest.web.response.ConversionException;
  import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException;
  import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest;
  import org.springframework.mock.web.MockHttpServletRequest;
  import org.springframework.web.bind.annotation.RequestMethod;
  
  import static org.junit.Assert.*;
  
  /**
   * Tests CRUD operations for {@link Person}s via web service calls
   */
  public class PersonController1_9Test extends MainResourceControllerTest {
  	
  	private PersonService service;
  	
  	@Override
  	public String getURI() {
  		return "person";
  	}
  	
  	@Override
  	public String getUuid() {
  		return RestTestConstants1_8.PERSON_UUID;
  	}
  	
  	@Override
  	public long getAllCount() {
  		return 0;
  	}
  	
  	@Before
  	public void before() {
  		this.service = Context.getPersonService();
  	}
  	
  	@Override
  	@Test(expected = ResourceDoesNotSupportOperationException.class)
  	public void shouldGetAll() throws Exception {
  		super.shouldGetAll();
  	}
  	
  	@Test
  	public void shouldGetAPersonByUuid() throws Exception {
  		MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/" + getUuid());
  		SimpleObject result = deserialize(handle(req));
  		
  		Person person = service.getPersonByUuid(getUuid());
  		assertEquals(person.getUuid(), PropertyUtils.getProperty(result, "uuid"));
  		assertNotNull(PropertyUtils.getProperty(result, "preferredName"));
  		assertEquals(person.getGender(), PropertyUtils.getProperty(result, "gender"));
  		assertNull(PropertyUtils.getProperty(result, "auditInfo"));
  	}
  	
  	@Test
  	public void shouldGetPersonDateCreated() throws Exception {
  		Person person = service.getPersonByUuid(getUuid());
  		Date personDateCreated = new Date();
  		person.setPersonDateCreated(personDateCreated);
  		service.savePerson(person);
  		
  		MockHttpServletRequest req = newGetRequest(getURI() + "/" + getUuid(), new Parameter("v",
  		        RestConstants.REPRESENTATION_FULL));
  		SimpleObject result = deserialize(handle(req));
  		
  		Map<String, String> auditInfo = (Map<String, String>) PropertyUtils.getProperty(result, "auditInfo");
  		
  		assertEquals(ConversionUtil.convertToRepresentation(personDateCreated, Representation.FULL),
  		    auditInfo.get("dateCreated"));
  	}
  	
  	@Test
  	public void shouldReturnTheAuditInfoForTheFullRepresentation() throws Exception {
  		MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/" + getUuid());
  		req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL);
  		SimpleObject result = deserialize(handle(req));
  		
  		assertNotNull(PropertyUtils.getProperty(result, "auditInfo"));
  	}
  	
  	@Test
  	public void shouldCreateAPerson() throws Exception {
  		long originalCount = service.getPeople("", false).size();
  		String json = "{ \"names\": [{ \"givenName\":\"Helen\", \"familyName\":\"of Troy\" }, "
  		        + "{\"givenName\":\"Leda\", \"familyName\":\"Nemesis\"} ], "
  		        + "\"birthdate\":\"2003-01-01\", \"gender\":\"F\" }";
  		
  		SimpleObject newPerson = deserialize(handle(newPostRequest(getURI(), json)));
  		
  		String uuid = PropertyUtils.getProperty(newPerson, "uuid").toString();
  		Person person = Context.getPersonService().getPersonByUuid(uuid);
  		assertEquals(2, person.getNames().size());
  		assertEquals("Helen of Troy", person.getPersonName().getFullName());
  		assertEquals(++originalCount, service.getPeople("", false).size());
  	}
  	
  	@Test
  	public void shouldCreateAPersonWithAttributes() throws Exception {
  		long originalCount = service.getPeople("", false).size();
  		final String birthPlace = "Nsambya";
  		String json = "{ \"names\": [{ \"givenName\":\"Helen\", \"familyName\":\"of Troy\" }], "
  		        + "\"birthdate\":\"2003-01-01\", \"gender\":\"F\", \"attributes\":"
  		        + "[{\"attributeType\":\"54fc8400-1683-4d71-a1ac-98d40836ff7c\",\"value\": \"" + birthPlace + "\"}] }";
  		
  		SimpleObject newPerson = deserialize(handle(newPostRequest(getURI(), json)));
  		
  		String uuid = PropertyUtils.getProperty(newPerson, "uuid").toString();
  		Person person = Context.getPersonService().getPersonByUuid(uuid);
  		assertEquals(++originalCount, service.getPeople("", false).size());
  		assertEquals(birthPlace, person.getAttribute("Birthplace").getValue());
  	}
  	
  	@Test
  	public void shouldEditAPerson() throws Exception {
  		Person person = service.getPersonByUuid(getUuid());
  		assertFalse("F".equals(person.getGender()));
  		assertFalse(person.isDead());
  		assertNull(person.getCauseOfDeath());
  		String json = "{\"gender\":\"F\",\"dead\":true, \"causeOfDeath\":\"15f83cd6-64e9-4e06-a5f9-364d3b14a43d\"}";
  		SimpleObject response = deserialize(handle(newPostRequest(getURI() + "/" + getUuid(), json)));
  		assertNotNull(response);
  		Object responsePersonContents = PropertyUtils.getProperty(response, "person");
  		assertNotNull(responsePersonContents);
  		assertTrue("F".equals(PropertyUtils.getProperty(responsePersonContents, "gender").toString()));
  		assertEquals("F", person.getGender());
  		assertTrue(person.isDead());
  		assertNotNull(person.getCauseOfDeath());
  	}
  	
  	@Test(expected = ConversionException.class)
  	public void shouldNotAllowUpdatingNamesProperty() throws Exception {
  		handle(newPostRequest(getURI() + "/" + getUuid(), "{\"names\":\"[]\"}"));
  	}
  	
  	@Test(expected = ConversionException.class)
  	public void shouldNotAllowUpdatingAddressesProperty() throws Exception {
  		handle(newPostRequest(getURI() + "/" + getUuid(), "{\"addresses\":\"[]\"}"));
  	}
  	
  	@Test
  	public void shouldSetThePreferredAddressAndUnmarkTheOldOne() throws Exception {
  		executeDataSet("PersonControllerTest-otherPersonData.xml");
  		Person person = service.getPersonByUuid(getUuid());
  		PersonAddress preferredAddress = service.getPersonAddressByUuid("8a806d8c-822d-11e0-872f-18a905e044dc");
  		PersonAddress notPreferredAddress = service.getPersonAddressByUuid("3350d0b5-821c-4e5e-ad1d-a9bce331e118");
  		assertTrue(preferredAddress.isPreferred());
  		assertFalse(notPreferredAddress.isPreferred());
  		assertFalse(notPreferredAddress.isVoided());
  		//sanity check that the addresses belong to the person
  		assertEquals(person, preferredAddress.getPerson());
  		assertEquals(person, notPreferredAddress.getPerson());
  		
  		handle(newPostRequest(getURI() + "/" + getUuid(), "{ \"preferredAddress\":\"" + notPreferredAddress.getUuid()
  		        + "\" }"));
  		
  		assertEquals(notPreferredAddress, person.getPersonAddress());
  		assertTrue(notPreferredAddress.isPreferred());
  		assertFalse(preferredAddress.isPreferred());
  	}
  	
  	@Test
  	public void shouldSetThePreferredNameAndUnmarkTheOldOne() throws Exception {
  		executeDataSet("PersonControllerTest-otherPersonData.xml");
  		Person person = service.getPersonByUuid(getUuid());
  		PersonName preferredName = service.getPersonNameByUuid("399e3a7b-6482-487d-94ce-c07bb3ca3cc7");
  		PersonName notPreferredName = service.getPersonNameByUuid("499e3a7b-6482-487d-94ce-c07bb3ca3cc8");
  		assertTrue(preferredName.isPreferred());
  		assertFalse(notPreferredName.isPreferred());
  		assertFalse(notPreferredName.isVoided());
  		//sanity check that the names belong to the person
  		assertEquals(person, preferredName.getPerson());
  		assertEquals(person, notPreferredName.getPerson());
  		
  		handle(newPostRequest(getURI() + "/" + getUuid(), "{ \"preferredName\":\"" + notPreferredName.getUuid() + "\" }"));
  		
  		assertEquals(notPreferredName, person.getPersonName());
  		assertTrue(notPreferredName.isPreferred());
  		assertFalse(preferredName.isPreferred());
  	}
  	
  	@Test
  	public void shouldVoidAPerson() throws Exception {
  		Person person = service.getPersonByUuid(getUuid());
  		final String reason = "some random reason";
  		assertEquals(false, person.isVoided());
  		MockHttpServletRequest req = newDeleteRequest(getURI() + "/" + getUuid(), new Parameter("!purge", ""),
  		    new Parameter("reason", reason));
  		handle(req);
  		person = service.getPersonByUuid(getUuid());
  		assertTrue(person.isVoided());
  		assertEquals(reason, person.getVoidReason());
  	}
  	
  	@Test
  	public void shouldPurgeAPerson() throws Exception {
  		final String uuid = "86526ed6-3c11-11de-a0ba-001e378eb67e";
  		assertNotNull(service.getPersonByUuid(uuid));
  		MockHttpServletRequest req = newDeleteRequest(getURI() + "/" + uuid, new Parameter("purge", ""));
  		handle(req);
  		assertNull(service.getPersonByUuid(uuid));
  	}
  	
  	@Test
  	public void shouldSearchAndReturnAListOfPersonsMatchingTheQueryString() throws Exception {
  		MockHttpServletRequest req = request(RequestMethod.GET, getURI());
  		req.addParameter("q", "Horatio");
  		SimpleObject result = deserialize(handle(req));
  		assertEquals(1, Util.getResultsSize(result));
  		assertEquals(getUuid(), PropertyUtils.getProperty(Util.getResultsList(result).get(0), "uuid"));
  	}
  	
  	@Test(expected = ConversionException.class)
  	public void shouldFailIfThePreferreNameBeingSetIsNew() throws Exception {
  		String json = "{\"preferredName\":{ \"givenName\":\"Joe\", \"familyName\":\"Smith\" }}";
  		handle(newPostRequest(getURI() + "/" + getUuid(), json));
  	}
  	
  	@Test(expected = ConversionException.class)
  	public void shouldFailIfThePreferreAddressBeingSetIsNew() throws Exception {
  		String json = "{\"preferredAddress\":{ \"address1\":\"test address\", \"country\":\"USA\" }}";
  		handle(newPostRequest(getURI() + "/" + getUuid(), json));
  	}
  	
  	@SuppressWarnings("unchecked")
  	@Test
  	public void shouldNotShowVoidedNamesInFullRepresentation() throws Exception {
  		executeDataSet("PersonControllerTest-otherPersonData.xml");
  		Person person = service.getPersonByUuid(getUuid());
  		assertEquals(4, person.getNames().size());
  		PersonName nameToVoid = person.getNames().iterator().next();
  		String nameToVoidUuid = nameToVoid.getUuid();
  		if (!nameToVoid.isVoided()) {
  			//void the Name
  			handle(newDeleteRequest("person/" + getUuid() + "/name/" + nameToVoidUuid, new Parameter("!purge", ""),
  			    new Parameter("reason", "none")));
  		}
  		assertTrue(nameToVoid.isVoided());
  		
  		MockHttpServletRequest req = newGetRequest(getURI() + "/" + getUuid(), new Parameter(
  		        RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL));
  		req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL);
  		
  		SimpleObject result = deserialize(handle(req));
  		
  		List<SimpleObject> names = (List<SimpleObject>) PropertyUtils.getProperty(result, "names");
  		assertEquals(3, names.size());
  		assertFalse(nameToVoidUuid.equals(PropertyUtils.getProperty(names.get(0), "uuid")));
  	}
  	
  	@SuppressWarnings("unchecked")
  	@Test
  	public void shouldNotShowVoidedAddressesInFullRepresentation() throws Exception {
  		executeDataSet("PersonControllerTest-otherPersonData.xml");
  		Person person = service.getPersonByUuid(getUuid());
  		assertEquals(2, person.getAddresses().size());
  		PersonAddress voidedAddress = service.getPersonAddressByUuid("8a806d8c-822d-11e0-872f-18a905e044dc");
  		String voidedAddressUuid = voidedAddress.getUuid();
  		assertTrue(voidedAddress.isVoided());
  		
  		MockHttpServletRequest req = newGetRequest(getURI() + "/" + getUuid(), new Parameter(
  		        RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL));
  		req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL);
  		
  		SimpleObject result = deserialize(handle(req));
  		
  		List<SimpleObject> addresses = (List<SimpleObject>) PropertyUtils.getProperty(result, "addresses");
  		assertEquals(1, addresses.size());
  		assertFalse(voidedAddressUuid.equals(PropertyUtils.getProperty(addresses.get(0), "uuid")));
  	}
  	
  	@SuppressWarnings("unchecked")
  	@Test
  	public void shouldNotShowVoidedAttributesInFullRepresentation() throws Exception {
  		Person person = service.getPersonByUuid(getUuid());
  		PersonAttribute attributeToVoid = person.getActiveAttributes().get(0);
  		String attributeToVoidUuid = attributeToVoid.getUuid();
  		assertEquals(3, person.getActiveAttributes().size());
  		if (!attributeToVoid.isVoided()) {
  			//void the attribute
  			handle(newDeleteRequest("person/" + getUuid() + "/attribute/" + attributeToVoidUuid,
  			    new Parameter("!purge", ""), new Parameter("reason", "none")));
  		}
  		assertTrue(attributeToVoid.isVoided());
  		
  		MockHttpServletRequest req = newGetRequest(getURI() + "/" + getUuid(), new Parameter(
  		        RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL));
  		req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_REPRESENTATION, RestConstants.REPRESENTATION_FULL);
  		
  		SimpleObject result = deserialize(handle(req));
  		
  		List<SimpleObject> attributes = (List<SimpleObject>) PropertyUtils.getProperty(result, "attributes");
  		assertEquals(2, attributes.size());
  		List<Object> uuids = Arrays.asList(PropertyUtils.getProperty(attributes.get(0), "uuid"),
  		    PropertyUtils.getProperty(attributes.get(1), "uuid"));
  		assertFalse(uuids.contains(attributeToVoidUuid));
  	}
  	
  	@Test
  	public void shouldRespectStartIndexAndLimit() throws Exception {
  		MockHttpServletRequest req = newGetRequest(getURI());
  		req.setParameter("q", "Test");
  		SimpleObject results = deserialize(handle(req));
  		int fullCount = Util.getResultsSize(results);
  		assertTrue("This test assumes > 2 matching persons", fullCount > 2);
  		
  		req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_LIMIT, "2");
  		results = deserialize(handle(req));
  		int firstCount = Util.getResultsSize(results);
  		assertEquals(2, firstCount);
  		
  		req.removeParameter(RestConstants.REQUEST_PROPERTY_FOR_LIMIT);
  		req.addParameter(RestConstants.REQUEST_PROPERTY_FOR_START_INDEX, "2");
  		results = deserialize(handle(req));
  