@SuppressWarnings("unchecked")
  @Override
  public Set<Person> getTopAncestors() {
    Set<Person> topAncestors = new HashSet<Person>();
    // Find all the parents
    // If a person is in the childrenmap as a key,
    // then they are registered as a parent to somebody
    em.getTransaction().begin();
    TypedQuery q = em.createQuery("select p.parents from Birth p", Person.class);
    List<Person> people = (List<Person>) q.getResultList();
    em.getTransaction().commit();

    for (Person person : people) {
      // If a person doesn't have a birth record,
      // then there's no record of a parent
      System.out.println("Found " + person);
      Birth birthRecord = findBirthRecord(person);
      if (birthRecord == null || birthRecord.getParents().isEmpty()) {
        System.out.println("Adding " + person + " to top ancestors list");
        topAncestors.add(person);
      }
    }

    return topAncestors;
  }
  @Override
  public void addParent(Person child, Person parent) {
    em.getTransaction().begin();
    TypedQuery<Birth> q =
        em.createQuery("select b from Birth b where b.person.id = :idParam", Birth.class);
    q.setParameter("idParam", child.getId());

    List<Birth> results = (List<Birth>) q.getResultList();
    Birth b = (results != null && results.size() > 0) ? results.get(0) : null;
    if (b != null) {
      b.addParent(parent);
      em.merge(b);
    }
    em.getTransaction().commit();
  }
  @Override
  public List<Event> getChildrenBirths(Person person) {
    // get the birth records of the children of this parent
    List<Birth> birthRecords = new ArrayList<Birth>();
    em.getTransaction().begin();
    Query q = em.createQuery("select b from Birth b, IN(b.parents) p WHERE p.id = :idParam");
    q.setParameter("idParam", person.getId());

    birthRecords.addAll((Collection<? extends Birth>) q.getResultList());

    List<Event> childrenBirths = new ArrayList<Event>();
    for (Birth b : birthRecords) {
      if (b != null) {
        ChildRecord cr = new ChildRecord();
        cr.setEventDate(b.getEventDate());
        cr.setPerson(person);
        cr.setChild(b.getPerson());
        cr.setTown(b.getTown());
        cr.setState_province(b.getState_province());
        cr.setCountry(b.getCountry());
        childrenBirths.add(cr);
      }
    }
    em.getTransaction().commit();
    return childrenBirths;
  }
  private void initialize() {

    Person JohnLennon = newPerson("John", "Lennon", Person.Gender.MALE);
    JohnLennon.setNotes("Famous songwriter and member of the Beatles musical group.");

    Person yoko = newPerson("Yoko", "Ono", Person.Gender.FEMALE);
    Person cynthia = newPerson("Cynthia", "Powell", Person.Gender.FEMALE);
    Person julian = newPerson("Julian", "Lennon", Person.Gender.MALE);

    Birth b = new Birth();
    b.setEventDate(new GregorianCalendar(1963, 3, 8).getTime());
    b.setPerson(julian);
    b.addParent(JohnLennon);
    b.addParent(cynthia);
    b.setTown("Liverpool");
    b.setCountry("England");
    addBirth(b);

    Person sean = newPerson("Sean", "Lennon", Person.Gender.MALE);
    b = new Birth();
    b.setEventDate(new GregorianCalendar(1975, 9, 9).getTime());
    b.setPerson(sean);
    b.setTown("Liverpool");
    b.setCountry("England");
    b.addParent(JohnLennon);
    b.addParent(yoko);
    addBirth(b);

    Person mimi = newPerson("Mary Elizabeth", "Smith", Person.Gender.FEMALE);

    mimi.setMiddle("Mimi");
    mimi.setNotes("Mimi became nephew John's guardian");

    Person Isoko = newPerson("Isoko", "Ono", Person.Gender.FEMALE);
    Person Yeisuke = newPerson("Yeisuke", "Ono", Person.Gender.MALE);

    // Get person JohnLennon
    Person person = getPerson(JohnLennon.getId());
    person.setMiddle("Winston");
    mydisplay(person.toString());

    mydisplay(JohnLennon.getMiddle());

    // birth = October 9, 1940
    // death = December 8, 1980
    b = new Birth();
    b.setEventDate(new GregorianCalendar(1940, 9, 9).getTime());
    b.setPerson(JohnLennon);
    b.setTown("Liverpool");
    b.setCountry("England");
    addBirth(b);

    Death dd = new Death();
    dd.setPerson(JohnLennon);
    dd.setEventDate(new GregorianCalendar(1980, 11, 8).getTime());
    dd.setTown("New York");
    dd.setState_province("New York");
    dd.setCountry("USA");
    addDeath(dd);

    // add more people to John Lennon's ancestry
    Person julia = newPerson("Julia", "Stanley", Person.Gender.FEMALE);

    Person alf = newPerson("Alfred", "Lennon", Person.Gender.MALE);
    addParent(JohnLennon, alf);
    addParent(JohnLennon, julia);

    Adoption a = new Adoption();
    a.setEventDate(new GregorianCalendar(1946, 6, 1).getTime());
    a.setPerson(JohnLennon);
    a.setTown("Liverpool");
    a.setCountry("England");
    // a.addParent(mimi);
    addAdoption(a);
    addAdoptedParent(JohnLennon, mimi);

    dd = new Death();
    dd.setPerson(mimi);
    dd.setEventDate(new GregorianCalendar(1991, 11, 6).getTime());
    dd.setTown("Poole");
    dd.setState_province("Dorset");
    dd.setCountry("England");
    addDeath(dd);

    b = new Birth();
    b.setEventDate(new GregorianCalendar(1933, 1, 18).getTime());
    b.setPerson(yoko);
    b.setTown("Tokyo");
    b.setCountry("Japan");
    addBirth(b);

    Marriage m = new Marriage();
    m.setEventDate(new GregorianCalendar(1969, 2, 20).getTime());
    m.setPerson(JohnLennon);
    m.setSpouse(yoko);
    m.setTown("Gilbraltar");
    m.setCountry("Gibraltar");
    addMarriage(m);

    addParent(yoko, Isoko);
    addParent(yoko, Yeisuke);
    List<Person> thesepeople = getAllPeople();
    mydisplay("\nGetting All People");
    for (Person p : thesepeople) {
      mydisplay(p.toString());
    }

    Set<Person> thesechildren = getChildren(JohnLennon);
    mydisplay("\nGetting Children of " + JohnLennon);
    for (Person p : thesechildren) {
      mydisplay(p.toString());
    }

    thesechildren = getChildren(JohnLennon, yoko);
    mydisplay("\nGetting Children of both " + JohnLennon + " and " + yoko);
    for (Person p : thesechildren) {
      mydisplay(p.toString());
    }

    thesechildren = getChildrenAll(JohnLennon, yoko);
    mydisplay("\nGetting Children of either " + JohnLennon + " and " + yoko);
    for (Person p : thesechildren) {
      mydisplay(p.toString());
    }

    // Events stuff
    List<Event> events = findAllEvents(JohnLennon);
    mydisplay("Finding all events for " + JohnLennon);
    for (Event e : events) {
      if (e != null) {
        mydisplay(e.toString());
      }
    }

    events = findAllEvents(yoko);
    mydisplay("Finding all events for " + yoko);
    for (Event e : events) {
      if (e != null) {
        mydisplay(e.toString());
      }
    }

    events = findAllEvents(cynthia);

    mydisplay("Finding all events for " + cynthia);
    for (Event e : events) {
      if (e != null) {
        mydisplay(e.toString());
      }
    }
  }
 @Override
 public void updateBirth(Birth b) {
   em.getTransaction().begin();
   Birth target = em.find(Birth.class, b.getId());
   target.setCountry(b.getCountry());
   target.setEventDate(b.getEventDate());
   target.setPerson(b.getPerson());
   target.setState_province(b.getState_province());
   target.setTown(b.getTown());
   target.setParents(b.getParents());
   em.merge(target);
   em.getTransaction().commit();
 }