private Entity createMetadata(
     final String digestString,
     final String filename,
     final String contentType,
     final byte[] bytes)
     throws IOException {
   Updater<Entity> updater =
       new Updater<Entity>() {
         @Override
         protected Entity update() throws IOException {
           DS ds = DS.get();
           Entity metadata = ds.getMetadata(digestString);
           log(metadata.toString());
           if (metadata.getProperties().isEmpty()) {
             metadata.setProperty(LocationProperty, null);
             metadata.setUnindexedProperty(FilenameProperty, filename);
             metadata.setUnindexedProperty(ContentTypeProperty, contentType);
             metadata.setUnindexedProperty(TimestampProperty, new Date());
             try {
               if (contentType.startsWith("image/jpeg")) {
                 ExifParser exif = new ExifParser(bytes);
                 Date timestamp = exif.getTimestamp();
                 if (timestamp != null) {
                   exif.populate(metadata);
                 }
               }
             } catch (Exception ex) {
             }
             ds.put(metadata);
           }
           return metadata;
         }
       };
   return updater.start();
 }
 private Entity updateBlog(
     final String messageId,
     final MimeMessage message,
     final String htmlBody,
     final boolean publishImmediately,
     final Email senderEmail)
     throws IOException {
   Updater<Entity> updater =
       new Updater<Entity>() {
         @Override
         protected Entity update() throws IOException {
           try {
             String subject = (String) getHeader(message, SubjectProperty);
             if (subject.startsWith("//WL2K ")) {
               subject = subject.substring(7);
             }
             DS ds = DS.get();
             Settings settings = ds.getSettings();
             Entity blog = ds.getBlogEntity(messageId, subject);
             if (subject == null
                 || subject.length() < 2
                 || htmlBody == null
                 || ContentCounter.countChars(htmlBody) < 5) {
               ds.deleteWithChilds(blog.getKey());
               return null;
             }
             int idx = subject.indexOf('{');
             if (idx != -1) {
               Set<String> keywords = getKeywords(subject.substring(idx + 1));
               subject = subject.substring(0, idx - 1).trim();
               if (!keywords.isEmpty()) {
                 blog.setProperty(KeywordsProperty, keywords);
               }
             }
             blog.setProperty(SubjectProperty, subject);
             blog.setProperty(PublishProperty, publishImmediately);
             blog.setProperty(SubjectProperty, subject);
             blog.setProperty(SenderProperty, senderEmail);
             setProperty(message, DateProperty, blog, true);
             blog.setUnindexedProperty(HtmlProperty, new Text(htmlBody));
             blog.setProperty(TimestampProperty, new Date());
             Entity placemark = ds.fetchLastPlacemark(settings);
             if (placemark != null) {
               GeoPt location = (GeoPt) placemark.getProperty(LocationProperty);
               if (location != null) {
                 blog.setProperty(LocationProperty, location);
               }
             }
             ds.put(blog);
             return blog;
           } catch (MessagingException ex) {
             throw new IOException(ex);
           }
         }
       };
   return updater.start();
 }
 private void replaceBlogRef(
     final Entity origBlog,
     final String cidStr,
     final String sha1,
     final int width,
     final int height,
     final String alt)
     throws IOException {
   if (origBlog != null) {
     final Key blogKey = origBlog.getKey();
     Updater<Object> updater =
         new Updater<Object>() {
           @Override
           protected Object update() throws IOException {
             DS ds = DS.get();
             Entity blog;
             try {
               blog = ds.get(blogKey);
             } catch (EntityNotFoundException ex) {
               throw new IOException(ex);
             }
             Collection<Key> attachments = (Collection<Key>) blog.getProperty(AttachmentsProperty);
             if (attachments == null) {
               attachments = new HashSet<Key>();
               blog.setUnindexedProperty(AttachmentsProperty, attachments);
             }
             attachments.add(ds.getMetadataKey(sha1));
             String cid = cidStr;
             if (cid.startsWith("<") && cid.endsWith(">")) {
               cid = cid.substring(1, cid.length() - 1);
             }
             Text text = (Text) blog.getProperty(HtmlProperty);
             String body = text.getValue();
             int start = body.indexOf("cid:" + cid);
             if (start != -1) {
               int end = body.indexOf(">", start);
               start = body.lastIndexOf("<img", start);
               if (start != -1 && end != -1) {
                 StringBuilder sb = new StringBuilder();
                 sb.append(body.substring(0, start));
                 sb.append(
                     "<img src=\"/blob?"
                         + Sha1Parameter
                         + "="
                         + sha1
                         + "\" alt=\""
                         + alt
                         + "\" style=\"width:"
                         + width
                         + "px;height:"
                         + height
                         + "px\">");
                 sb.append(body.substring(end + 1));
                 blog.setUnindexedProperty(HtmlProperty, new Text(sb.toString()));
               }
             }
             ds.put(blog);
             return null;
           }
         };
     updater.start();
   }
 }