@POST
  @UnitOfWork
  @Path("add_view/{personId}")
  @Produces(MediaType.APPLICATION_JSON)
  @Consumes(MediaType.APPLICATION_JSON)
  public synchronized Person addProfileView(
      @PathParam("personId") LongParam personId, Viewer viewer)
      throws JsonParseException, JsonMappingException, IOException {
    // load person object
    Person person = findSafely(personId.get());
    LinkedList<Viewer> viewers;

    // Pending: make sure the viewer Id exists in db

    if (viewer.getId() == personId.get())
      throw new BadRequestException("Viewer & viewee id's are same");

    if (person.getViewers() != null) {
      // de-serialise viewers object to list from json
      viewers = mapper.readValue(person.getViewers(), new TypeReference<LinkedList<Viewer>>() {});

      // filter invalid/obsolete views
      LinkedList<Viewer> tmp = new LinkedList<Viewer>();
      for (Viewer vr : viewers) {
        // if viewer is valid and not same as current one
        if (vr.getId() != viewer.getId() && isValid(vr)) tmp.add(vr);
      }

      // if max viewers are present; remove last one
      if (tmp.size() == maxViewers) tmp.removeLast();

      viewers = tmp;
    } else {
      viewers = new LinkedList<Viewer>();
    }

    // add new viewer
    viewers.addFirst(viewer);

    person.setViewers(mapper.writeValueAsString(viewers));

    personDAO.update(person);

    return person;
  }
  // if viewer is valid
  private boolean isValid(Viewer viewer) {
    // view is more than maxTTLms old
    if (System.currentTimeMillis() - viewer.getTimestamp() > maxTTLms) return false;

    return true;
  }