code: @SuppressWarnings("unchecked") // cast to generic Map will always be okay in this case
      private void validateEvent(Map<String, Object> event, int depth) {
          if (depth == 0) {
              if (event == null || event.size() == 0) {
                  throw new InvalidEventException("You must specify a non-null, non-empty event.");
              }
              if (event.containsKey("keen")) {
                  throw new InvalidEventException("An event cannot contain a root-level property named 'keen'.");
              }
          } else if (depth > KeenConstants.MAX_EVENT_DEPTH) {
              throw new InvalidEventException("An event's depth (i.e. layers of nesting) cannot exceed " +
                      KeenConstants.MAX_EVENT_DEPTH);
          }
  
          for (Map.Entry<String, Object> entry : event.entrySet()) {
              String key = entry.getKey();
              if (key.contains(".")) {
                  throw new InvalidEventException("An event cannot contain a property with the period (.) character in " +
                          "it.");
              }
              if (key.length() > 256) {
                  throw new InvalidEventException("An event cannot contain a property name longer than 256 characters.");
              }
  
              validateEventValue(entry.getValue(), depth);
          }
      }
docs: Validates an event.
  
  @param event The event to validate.
  @param depth The number of layers of the map structure that have already been traversed; this
  should be 0 for the initial call and will increment on each recursive call.