public virtual AtomEntry Annotate(Id entryId, AtomEntry entry, string slug)
    {
      LogService.Info("AnnotateService.Annotate entryId={0} slug={1}", entryId, slug);

      //authorization
      if (!AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.Annotate))
        throw new UserNotAuthorizedException(GetUser().Name, AuthAction.Annotate.ToString());

      AppCollection coll = AppService.GetCollection(entryId);

      //make sure type is accepted
      if (!coll.CanAccept(Atom.ContentTypeEntry))
        throw new InvalidContentTypeException(Atom.ContentTypeEntry);

      entry.SetNamespaces(); //TODO: is there a better place for this?

      //build id onto parent's id
      AtomEntry parent = AtomPubService.GetEntry(entryId);
      entry.Id = new Id(parent.Id.Owner, parent.Id.Date, parent.Id.Collection, entry.BuildPath(parent.Id.EntryPath, slug));
      
      var url = new UrlHelper(Container.GetInstance<RequestContext>());
      //this annotation is a reply to the parent entry, TODO: leave off href for later calc based on id?
      entry.InReplyTo = new ThreadInReplyTo()
      {
        Ref = parent.Id,
        Href = parent.IsExternal ? parent.Content.Src : url.RouteIdUri("AtomPubEntry", entry.Id, AbsoluteMode.Force),
        Type = parent.IsExternal ? parent.Content.Type : Atom.ContentTypeEntry
      };

      if (!entry.Published.HasValue) entry.Published = DateTimeOffset.UtcNow;
      entry.Updated = DateTimeOffset.UtcNow;
      entry.Edited = DateTimeOffset.UtcNow;

      if (entry.Authors.Count() == 0) entry.SetPerson(AuthorizeService, true);

      //entry.IdChanged += (e) => e.UpdateLinks(UrlHelper.RouteIdUri);

      //OnAnnotate(parent, entryId, entry, slug);
      if (AnnotatingEntry != null) AnnotatingEntry(entryId, entry, slug);

      if (entry.Authors.Count() == 0 || entry.Authors.First().Name == null)
        throw new AnnotationNotAllowedException(entry.Id, entry.AnnotationType, "the author cannot be determined");

      entry = AtomEntryRepository.CreateEntry(entry);
      if (EntryAnnotated != null) EntryAnnotated(entry);
      return entry;
    }