str we are interested in.
      (re-search-forward po-any-msgstr-form-regexp)
      (setq po-start-of-msgstr-form (match-beginning 0)
            po-end-of-msgstr-form (match-end 0)))
    ;; Classify the entry.
    (setq po-entry-type
          (if (eq (following-char) ?#)
              'obsolete
            (goto-char po-start-of-entry)
            (if (re-search-forward po-fuzzy-regexp po-start-of-msgctxt t)
                'fuzzy
              (goto-char po-start-of-msgstr-block)
              (if (looking-at po-untranslated-regexp)
                  'untranslated
                'translated))))
    ;; Put the cursor back where it was.
    (goto-char here)))

(defun po-add-attribute (name)
  "Add attribute NAME to the current entry, unless it is already there."
  (save-excursion
    (let ((buffer-read-only po-read-only))
      (goto-char po-start-of-entry)
      (if (re-search-forward "\n#, .*" po-start-of-msgctxt t)
          (save-restriction
            (narrow-to-region (match-beginning 0) (match-end 0))
            (goto-char (point-min))
            (if (re-search-forward (concat "\\b" name "\\b") nil t)
                nil
              (goto-char (point-max))
              (insert ", " name)))
        (skip-chars-forward "\n")
        (while (eq (following-char) ?#)
          (forward-line 1))
        (insert "#, " name "\n")))))

(defun po-delete-attribute (name)
  "Delete attribute NAME from the current entry, if any."
  (save-excursion
    (let ((buffer-read-only po-read-only))
      (goto-char po-start-of-entry)
      (if (re-search-forward "\n#, .*" po-start-of-msgctxt t)
          (save-restriction
            (narrow-to-region (match-beginning 0) (match-end 0))
            (goto-char (point-min))
            (if (re-search-forward
                 (concat "\\(\n#, " name "$\\|, " name "$\\| " name ",\\)")
                 nil t)
                (replace-match "" t t)))))))
