/**
  * add organizer to properties
  *
  * @param appointment
  * @param properties
  */
 private void addOrganizer(
     Appointment appointment, PropertyList properties, boolean doExportAsMeeting) {
   // means we do not export attendees so we do not have a meeting
   if (!doExportAsMeeting) return;
   final User owner = appointment.getReservation().getOwner();
   try {
     Organizer organizer = null;
     if (owner.getEmail() != null && owner.getEmail().trim().length() > 0) {
       try {
         final URI uri = new URI("MAILTO:" + owner.getEmail().trim());
         organizer = new Organizer(uri);
       } catch (URISyntaxException e) {
       }
     }
     if (organizer == null) {
       organizer = new Organizer("MAILTO:" + URLEncoder.encode(owner.getUsername(), "UTF-8"));
     }
     if (!"".equals(owner.getName())) organizer.getParameters().add(new Cn(owner.getName()));
     properties.add(organizer);
   } catch (URISyntaxException e) {
     throw new IllegalArgumentException(e);
   } catch (UnsupportedEncodingException e) {
     throw new IllegalArgumentException(e);
   }
 }
  /** {@inheritDoc} */
  public VEvent createEvent(CalendarEvent event, List<User> attendees) {

    if (!isIcsEnabled()) {
      log.debug(
          "ExternalCalendaringService is disabled. Enable via calendar.ics.generation.enabled=true in sakai.properties");
      return null;
    }

    // timezone. All dates are in GMT so we need to explicitly set that
    TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
    TimeZone timezone = registry.getTimeZone("GMT");
    VTimeZone tz = timezone.getVTimeZone();

    // start and end date
    DateTime start = new DateTime(getStartDate(event.getRange()).getTime());
    DateTime end = new DateTime(getEndDate(event.getRange()).getTime());

    // create event incl title/summary
    VEvent vevent = new VEvent(start, end, event.getDisplayName());

    // add timezone
    vevent.getProperties().add(tz.getTimeZoneId());

    // add uid to event
    // could come from the vevent_uuid field in the calendar event, otherwise from event ID.
    String uuid = null;
    if (StringUtils.isNotBlank(event.getField("vevent_uuid"))) {
      uuid = event.getField("vevent_uuid");
    } else {
      uuid = event.getId();
    }
    vevent.getProperties().add(new Uid(uuid));

    // add sequence to event
    // will come from the vevent_sequnece field in the calendar event, otherwise skip it
    String sequence = null;
    if (StringUtils.isNotBlank(event.getField("vevent_sequence"))) {
      sequence = event.getField("vevent_sequence");
      vevent.getProperties().add(new Sequence(sequence));
    }

    // add description to event
    vevent.getProperties().add(new Description(event.getDescription()));

    // add location to event
    vevent.getProperties().add(new Location(event.getLocation()));

    // add organiser to event
    if (StringUtils.isNotBlank(event.getCreator())) {

      String creatorEmail = sakaiProxy.getUserEmail(event.getCreator());

      URI mailURI = createMailURI(creatorEmail);
      Cn commonName = new Cn(sakaiProxy.getUserDisplayName(event.getCreator()));

      Organizer organizer = new Organizer(mailURI);
      organizer.getParameters().add(commonName);
      vevent.getProperties().add(organizer);
    }

    // add attendees to event with 'required participant' role
    vevent = addAttendeesToEvent(vevent, attendees);

    // add URL to event, if present
    String url = null;
    if (StringUtils.isNotBlank(event.getField("vevent_url"))) {
      url = event.getField("vevent_url");
      Url u = new Url();
      try {
        u.setValue(url);
        vevent.getProperties().add(u);
      } catch (URISyntaxException e) {
        // it doesnt matter, ignore it
      }
    }

    if (log.isDebugEnabled()) {
      log.debug("VEvent:" + vevent);
    }

    return vevent;
  }