/**
   * Calling clearLogs posits that these EventLogs were successfully saved, and so this method may
   * raise an event signalling such. This could eventually be reworked to be fully within the
   * security system.
   */
  void saveLogs(boolean readOnly, Session session) {

    // Grabbing a copy to prevent ConcurrentModificationEx
    final List<EventLog> logs = new ArrayList<EventLog>(secSys.getLogs());
    secSys.clearLogs();

    if (logs == null || logs.size() == 0) {
      return; // EARLY EXIT
    }

    if (readOnly) {
      // If we reach here, we have logs when we shouldn't.
      StringBuilder sb = new StringBuilder();
      sb.append("EventLogs in readOnly transaction:\n");
      for (EventLog eventLog : logs) {
        sb.append(eventLog.getAction());
        sb.append(" ");
        sb.append(eventLog);
        sb.append(eventLog.getEntityType());
        sb.append(" ");
        sb.append(eventLog.getEntityId());
        sb.append("\b");
      }
      throw new InternalException(sb.toString());
    }

    try {
      long lastValue = sql.nextValue("seq_eventlog", logs.size());
      long id = lastValue - logs.size() + 1;
      List<Object[]> batchData = new ArrayList<Object[]>();
      for (EventLog l : logs) {
        Event e = l.getEvent();
        if (e.getId() == null) {
          throw new RuntimeException("Transient event");
        }
        batchData.add(
            new Object[] {
              id++, -35L, l.getEntityId(), l.getEntityType(), l.getAction(), l.getEvent().getId()
            });
      }

      sql.insertLogs(batchData);

    } catch (Exception ex) {
      log.error("Error saving event logs: " + logs, ex);
    }

    if (secSys.getLogs().size() > 0) {
      throw new InternalException("More logs present after saveLogs()");
    }
  }
  public Event newEvent(Session session, EventType type, TokenHolder tokenHolder) {
    BasicEventContext c = current();
    Event e = new Event();
    e.setType(type);
    e.setTime(new Timestamp(System.currentTimeMillis()));
    tokenHolder.setToken(e.getGraphHolder());
    e.getDetails().setPermissions(Permissions.READ_ONLY);
    // Proxied if necessary
    e.setExperimenter(c.getOwner());
    e.setExperimenterGroup(c.getGroup());
    e.setSession(session);

    c.setEvent(e);
    return e;
  }