emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 536ef75: * externals-list: Convert excorporate to :externa


From: Stefan Monnier
Subject: [elpa] master 536ef75: * externals-list: Convert excorporate to :external
Date: Sun, 29 Nov 2020 15:43:20 -0500 (EST)

branch: master
commit 536ef75e77446cd44f6a738d74c600510ce5b4f9
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * externals-list: Convert excorporate to :external
---
 externals-list                               |    3 +-
 packages/excorporate/NEWS                    |  132 ---
 packages/excorporate/README                  |   40 -
 packages/excorporate/dir                     |   18 -
 packages/excorporate/excorporate-calendar.el |   46 -
 packages/excorporate/excorporate-calfw.el    |  151 ----
 packages/excorporate/excorporate-diary.el    |  322 -------
 packages/excorporate/excorporate-org.el      |  364 --------
 packages/excorporate/excorporate.el          | 1212 --------------------------
 packages/excorporate/excorporate.info        |  746 ----------------
 packages/excorporate/excorporate.texi        |  798 -----------------
 11 files changed, 2 insertions(+), 3830 deletions(-)

diff --git a/externals-list b/externals-list
index 9b2b310..b1ee27a 100644
--- a/externals-list
+++ b/externals-list
@@ -86,6 +86,7 @@
  ("emms"               :external "https://git.savannah.gnu.org/git/emms.git";)
  ("enwc"               :external 
"hg::https://hg.savannah.nongnu.org/hgweb/enwc/";)
  ("ergoemacs-mode"     :external 
"https://github.com/ergoemacs/ergoemacs-mode.git";)
+ ("excorporate" :external nil)
  ("expand-region"      :external "https://github.com/magnars/expand-region.el";)
  ("exwm"               :external "https://github.com/ch11ng/exwm.git";)
  ("f90-interface-browser" :external "https://github.com/wence-/f90-iface";)
@@ -99,7 +100,7 @@
  ("gnome-c-style"      :external "https://github.com/ueno/gnome-c-style.git";)
  ("gnorb"               :external nil) ;; Was "https://github.com/girzel/gnorb";
  ("gnu-elpa"           :external nil)
- ("gnugo" :external nil)
+ ("gnugo"              :external nil)
  ("gpastel"            :external 
"https://gitlab.petton.fr/DamienCassou/gpastel";)
  ("greader"            :external 
"https://gitlab.com/michelangelo-rodriguez/greader";)
  ("guess-language"     :external 
"https://github.com/tmalsburg/guess-language.el";)
diff --git a/packages/excorporate/NEWS b/packages/excorporate/NEWS
deleted file mode 100644
index 8b73280..0000000
--- a/packages/excorporate/NEWS
+++ /dev/null
@@ -1,132 +0,0 @@
-GNU Emacs Excorporate NEWS -- history of user-visible changes.
-
-* Excorporate 0.9.1
-
-Released 2020-10-05
-
-** Change default behaviour of decline, accept and tenatitvely-accept functions
-
-Always prompt for a response message in
-exco-org-decline-meeting-request, exco-org-accept-meeting-request, and
-exco-org-tentatively-accept-meeting-request, unless a prefix argument
-is specified.
-
-** Allow force-deleting calendar items
-
-Take a prefix argument to exco-org-delete-appointment to force-delete
-the calendar item at point in the *Excorporate* Org buffer.
-
-* Excorporate 0.9.0
-
-Released 2020-09-30
-
-** Add interactive exco-org meeting and appointment cancellation functions
-
-** Add interactive exco-org meeting reply functions
-
-** Add meeting and appointment creation functions
-
-** Add meeting organizer to Org entries
-
-** Add API Usage section to the manual, with several examples
-
-* Excorporate 0.8.3
-
-Released 2019-06-18
-
-** Fix appt percent-encoded URL printing
-
-** Update HTTP debugging steps in Info manual
-
-* Excorporate 0.8.2
-
-Released 2019-06-14
-
-** Enable multiple connections
-
-The excorporate-configuration variable can now be a list representing
-multiple servers.  The excorporate function will create one connection
-per server configured.  Connections to additional servers can be
-dynamically created by passing a prefix argument to the excorporate
-function.
-
-* Excorporate 0.8.1
-
-Released 2018-09-15
-
-** Depend on nadvice 0.3
-
-This fixes excorporate-diary-enable on Emacs 24.1, 24.2, and 24.3.
-
-* Excorporate 0.8.0
-
-Released 2018-09-13
-
-** Add functions for retrieving meeting details
-
-** Add diary support
-
-M-x excorporate
-M-x excorporate-diary-enable
-M-x calendar
-Press `d'
-
-** Add appt support
-
-After you've retrieved today's meetings, several minutes before the
-start of the next meeting a reminder window will pop up.
-
-If Emacs is left running overnight, it will display tomorrow's
-meetings at 12:01 AM.
-
-* Excorporate 0.7.7
-
-Released 2018-09-04
-
-** Enable calfw support
-
-* Excorporate 0.7.6
-
-Released 2016-10-05
-
-** Require some NTLM compatibility fixes via updated dependencies
-
-* Excorporate 0.7.5
-
-Released 2016-06-16
-
-** Interoperate with `save-some-buffers'
-
-* Excorporate 0.7.4
-
-Released 2016-06-15
-
-** Interoperate with `org-startup-with-latex-preview'
-
-* Excorporate 0.7.3
-
-Released 2016-04-01
-
-** Bind q to quit-window in Org mode backend
-
-* Excorporate 0.7.2
-
-Released 2016-03-16
-
-** Support Office 365 and Exchange 2010_SP1
-
-* Excorporate 0.7.1
-
-Released 2016-02-26
-
-** Add Info manual
-
-* Excorporate 0.7.0
-
-Released 2016-02-21
-
-** First release in GNU ELPA
-
-Local variables:
-mode: outline
-end:
diff --git a/packages/excorporate/README b/packages/excorporate/README
deleted file mode 100644
index 9dbf599..0000000
--- a/packages/excorporate/README
+++ /dev/null
@@ -1,40 +0,0 @@
-Excorporate provides Exchange integration for Emacs.
-
-Most Recent Improvements
-------------------------
-
-New in Excorporate 0.9.1, released 2020-10-05:
-
-** Change default behaviour of decline, accept and tenatitvely-accept functions
-
-Always prompt for a response message in
-exco-org-decline-meeting-request, exco-org-accept-meeting-request, and
-exco-org-tentatively-accept-meeting-request, unless a prefix argument
-is specified.
-
-** Allow force-deleting calendar items
-
-Take a prefix argument to exco-org-delete-appointment to force-delete
-the calendar item at point in the *Excorporate* Org buffer.
-
-Quick Start
------------
-
-To create a connection to a web service:
-
-M-x excorporate
-
-Excorporate will prompt for an email address that it will use to
-automatically discover settings.  Then it will prompt you for your
-credentials two or three times depending on the server configuration.
-
-You should see a message indicating that the connection is ready
-either in the minibuffer or in the *Messages* buffer.
-
-Finally, run M-x calendar, and press 'e' to show today's meetings.
-
-If autodiscovery fails, customize `excorporate-configuration' to skip
-autodiscovery.
-
-For further information including connection troubleshooting, see the
-Excorporate Info node at C-h i d m Excorporate.
diff --git a/packages/excorporate/dir b/packages/excorporate/dir
deleted file mode 100644
index c0433c3..0000000
--- a/packages/excorporate/dir
+++ /dev/null
@@ -1,18 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "?" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Emacs
-* Excorporate: (excorporate).  Exchange Web Services integration for Emacs.
diff --git a/packages/excorporate/excorporate-calendar.el 
b/packages/excorporate/excorporate-calendar.el
deleted file mode 100644
index 506ac72..0000000
--- a/packages/excorporate/excorporate-calendar.el
+++ /dev/null
@@ -1,46 +0,0 @@
-;;; excorporate-calendar.el --- Exchange for calendar -*- lexical-binding: t 
-*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
-;; Keywords: calendar
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Add a calendar keybinding for Excorporate.  Default to the
-;; excorporate-org interface.
-
-;;; Code:
-
-(require 'calendar)
-
-(defcustom excorporate-calendar-show-day-function 'exco-org-show-day
-  "A function to be called by pressing `e' in Calendar."
-  :type 'function
-  :group 'excorporate)
-
-(defun exco-calendar-show-day ()
-  "Show meetings for the selected date."
-  (interactive)
-  (apply excorporate-calendar-show-day-function (calendar-cursor-to-date t)))
-
-;; I arrogantly claim "e" for now, but irresponsibly reserve the right
-;; to change it later.
-(define-key calendar-mode-map "e" #'exco-calendar-show-day)
-
-(provide 'excorporate-calendar)
-
-;;; excorporate-calendar.el ends here
diff --git a/packages/excorporate/excorporate-calfw.el 
b/packages/excorporate/excorporate-calfw.el
deleted file mode 100644
index 5eda6e4..0000000
--- a/packages/excorporate/excorporate-calfw.el
+++ /dev/null
@@ -1,151 +0,0 @@
-;;; excorporate-calfw.el --- Exchange calendar view   -*- lexical-binding: t 
-*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
-;; Keywords: calendar
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Use the Calfw calendar framework to display daily meetings.
-
-;; To use this handler, set excorporate-calendar-show-day to
-;; exco-calfw-show-day using `customize-variable'.
-
-;; This Excorporate handler requires the Calfw package, which is not
-;; included in GNU ELPA because not all Calfw contributors have
-;; copyright assignment papers on file with the FSF.
-
-;;; Code:
-
-;; calfw is not FSF-assigned yet so it is not in GNU ELPA.  The
-;; following workarounds allow excorporate-calfw.elc to be built
-;; regardless.
-(require 'calfw nil t)
-
-(declare-function cfw:component-model "ext:calfw" t)
-(declare-function cfw:cp-add-selection-change-hook "ext:calfw" t)
-(declare-function cfw:cp-get-contents-sources "ext:calfw" t)
-(declare-function cfw:create-calendar-component-buffer "ext:calfw" t)
-(declare-function cfw:cursor-to-nearest-date "ext:calfw" t)
-(declare-function cfw:date "ext:calfw" t)
-(declare-function cfw:model-set-contents-sources "ext:calfw" t)
-(declare-function cfw:refresh-calendar-buffer "ext:calfw" t)
-(declare-function make-cfw:event "ext:calfw" t)
-(declare-function make-cfw:source "ext:calfw" t)
-
-(defvar cfw:component)
-
-;; Fix a bad bug in calfw.  See:
-;; https://github.com/kiwanami/emacs-calfw/pull/79
-(defun cfw:cp-set-contents-sources (component sources)
-  "Set content SOURCES for COMPONENT.
-SOURCES is a list of content sources."
-  (cfw:model-set-contents-sources
-   sources (cfw:component-model component)))
-
-(require 'excorporate)
-
-(defvar excorporate-calfw-buffer-name "*Excorporate*"
-  "The buffer into which Calfw output is inserted.")
-
-(defun exco-calfw-initialize-buffer (month day year)
-  "Set up an initial blank Calfw buffer for date MONTH DAY YEAR."
-  (with-current-buffer (get-buffer-create excorporate-calfw-buffer-name)
-    (display-buffer (current-buffer))
-    (let ((status-source (make-cfw:source :name "Updating..."
-                                         :data (lambda (_b _e) nil))))
-      (cfw:create-calendar-component-buffer
-       :date (cfw:date month day year) :view 'day
-       :contents-sources (list status-source)
-       :buffer (current-buffer)))))
-
-(defun exco-calfw-add-meeting (subject start end location
-                                      main-invitees optional-invitees)
-  "Add a scheduled meeting to the event list.
-SUBJECT is a string, the subject of the meeting.  START is the
-meeting start time in Emacs internal date time format, and END is
-the end of the meeting in the same format.  LOCATION is a string
-representing the location.  MAIN-INVITEES and OPTIONAL-INVITEES
-are the requested participants."
-  (let ((start-list (decode-time start))
-       (end-list (decode-time end)))
-    (make-cfw:event :title (concat
-                           (format "\n\t%s" subject)
-                           (format "\n\tLocation: %s" location)
-                           (when main-invitees
-                             (format "\n\tInvitees: %s"
-                                     (mapconcat 'identity
-                                                main-invitees "; ")))
-                           (when optional-invitees
-                             (format "\n\tOptional: %s"
-                                     (mapconcat 'identity
-                                                optional-invitees "; "))))
-                   :start-date  (list (elt start-list 4)
-                                      (elt start-list 3)
-                                      (elt start-list 5))
-                   :start-time  (list (elt start-list 2)
-                                      (elt start-list 1))
-                   :end-date    (list (elt end-list 4)
-                                      (elt end-list 3)
-                                      (elt end-list 5))
-                   :end-time    (list (elt end-list 2)
-                                      (elt end-list 1)))))
-
-(defun exco-calfw-add-meetings (identifier response)
-  "Add the connection IDENTIFIER's meetings from RESPONSE."
-  (let ((event-list (exco-calendar-item-iterate response
-                                               #'exco-calfw-add-meeting)))
-    (with-current-buffer (get-buffer-create excorporate-calfw-buffer-name)
-      (let* ((new-source (make-cfw:source
-                         :name (format "%S (as of %s)"
-                                       identifier
-                                       (format-time-string "%F %H:%M"))
-                         :data (lambda (_b _e)
-                                 event-list)))
-            (sources (cfw:cp-get-contents-sources cfw:component))
-            (new-sources (append sources (list new-source))))
-       (cfw:cp-set-contents-sources cfw:component new-sources)))))
-
-(defun exco-calfw-finalize-buffer ()
-  "Finalize the Calfw widget after retrievals have completed."
-  (with-current-buffer (get-buffer-create excorporate-calfw-buffer-name)
-    (let ((sources (cfw:cp-get-contents-sources cfw:component))
-         (status-source (make-cfw:source :name "Done."
-                                         :data (lambda (_b _e) nil))))
-      (cfw:cp-set-contents-sources cfw:component
-                                  (cons status-source (cdr sources))))
-    (cfw:cp-add-selection-change-hook cfw:component
-                                     (lambda ()
-                                       (apply #'exco-calfw-show-day
-                                              (cfw:cursor-to-nearest-date))))
-    (cfw:refresh-calendar-buffer nil)))
-
-;;;###autoload
-(defun exco-calfw-show-day (month day year)
-  "Show meetings for the date specified by MONTH DAY YEAR."
-  (exco-connection-iterate
-   (lambda ()
-     (exco-calfw-initialize-buffer month day year))
-   (lambda (identifier callback)
-     (exco-get-meetings-for-day identifier month day year
-                               callback))
-   #'exco-calfw-add-meetings
-   #'exco-calfw-finalize-buffer))
-
-(provide 'excorporate-calfw)
-
-;;; excorporate-calfw.el ends here
diff --git a/packages/excorporate/excorporate-diary.el 
b/packages/excorporate/excorporate-diary.el
deleted file mode 100644
index 833df30..0000000
--- a/packages/excorporate/excorporate-diary.el
+++ /dev/null
@@ -1,322 +0,0 @@
-;;; excorporate-diary.el --- Diary integration        -*- lexical-binding: t 
-*-
-
-;; Copyright (C) 2018-2019 Free Software Foundation, Inc.
-
-;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
-;; Keywords: calendar
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Wrap interactive `diary-lib' functions so that they query the
-;; Exchange server asynchronously, then display retrieved results
-;; interleaved with local diary entries.
-
-;;; Code:
-
-(require 'diary-lib)
-(require 'calendar)
-(require 'icalendar)
-(require 'appt)
-(require 'excorporate)
-(require 'nadvice)
-
-;; For Emacs versions less than 27.1, which do not have the fix for
-;; Bug#35645, work around the issue where `icalendar-import-buffer'
-;; pops up the diary file buffer.
-(defun exco-diary-diary-make-entry (string &optional nonmarking file)
-  "Insert a diary entry STRING which may be NONMARKING in FILE.
-If omitted, NONMARKING defaults to nil and FILE defaults to
-`diary-file'."
-  (with-current-buffer (find-file-noselect (or file diary-file))
-    (when (eq major-mode (default-value 'major-mode)) (diary-mode))
-    (widen)
-    (diary-unhide-everything)
-    (goto-char (point-max))
-    (when (let ((case-fold-search t))
-           (search-backward "Local Variables:"
-                            (max (- (point-max) 3000) (point-min))
-                            t))
-      (beginning-of-line)
-      (insert "\n")
-      (forward-line -1))
-    (insert
-     (if (bolp) "" "\n")
-     (if nonmarking diary-nonmarking-symbol "")
-     string)))
-
-(defun exco-diary-icalendar--add-diary-entry-around (original &rest arguments)
-  "Prevent whitespace workaround from selecting diary buffer.
-Also prevent `diary-make-entry' from putting the diary file
-where (other-buffer (current-buffer)) will return it.  ORIGINAL
-and ARGUMENTS are the original function and arguments
-respectively."
-  (cl-letf (((symbol-function #'find-file)
-            (symbol-function #'find-file-noselect))
-           ;; This override suppresses diary-make-entry's window
-           ;; and buffer manipulations.
-           ((symbol-function #'diary-make-entry)
-            (symbol-function #'exco-diary-diary-make-entry)))
-    (apply original arguments)))
-
-(unless (string-match "omit-trailing-space" (documentation 'diary-make-entry))
-  (advice-add #'icalendar--add-diary-entry :around
-             #'exco-diary-icalendar--add-diary-entry-around))
-
-(defvar excorporate-diary-today-file
-  "~/.emacs.d/excorporate/diary-excorporate-today"
-  "The diary file where Excorporate should save today's meetings.
-This file will be #include'd in `diary-file' by
-`excorporate-diary-enable'.")
-
-(defvar excorporate-diary-transient-file
-  "~/.emacs.d/excorporate/diary-excorporate-transient"
-  "The diary file where Excorporate should save retrieved meetings.
-This file will be #include'd in `diary-file' by
-`excorporate-diary-enable'.")
-
-(defun exco-diary-initialize (today)
-  "Initialize diary files used by Excorporate.
-Run before retrieving diary entries from servers.  TODAY is t to
-initialize for today's date, nil otherwise."
-  ;; Keep today's entries if running on a day other than today.  If
-  ;; retrieving results for today, delete results from days other than
-  ;; today, in case the transient file (having been filled in on a
-  ;; prior day) contains duplicate or stale results for today.
-  (let ((files (if today
-                  (list excorporate-diary-today-file
-                        excorporate-diary-transient-file)
-                (list excorporate-diary-transient-file))))
-    (dolist (file files)
-      (let ((directory (file-name-directory file)))
-       (unless (file-exists-p directory)
-         (make-directory directory))
-       (with-current-buffer (find-file-noselect file)
-         (delete-region (point-min) (point-max))
-         ;; Do not call `save-buffer' to avoid any hooks from being
-         ;; run.  Otherwise `appt-update-list' in
-         ;; `write-file-functions' can cause an infinite
-         ;; connnection-callback loop.
-         (basic-save-buffer-1))))))
-
-;; Literal percent signs (%) are not supported in a diary entry since
-;; they're interpreted as format strings by `diary-sexp-entry', so
-;; encode them during entry insertion, then unescape them during
-;; display.  This is needed so that, e.g., encoded meeting URLs that
-;; contain literal percent signs (%) work with `browse-url'.
-(defun exco-diary--fix-percent-signs ()
-  "Replace percent-sign placeholders with percent signs."
-  (goto-char (point-min))
-  (let ((inhibit-read-only t))
-    (while (re-search-forward "<EXCO_PERCENT_SIGN>" nil t)
-      (replace-match "%"))))
-
-(defun exco-diary-appt-disp-window (min-to-app new-time appt-msg)
-  "Replace Excorporate diary percent signs.
-For MIN-TO-APP, NEW-TIME and APPT-MSG documentation, see
-`appt-disp-window'."
-  (appt-disp-window min-to-app new-time appt-msg)
-  (with-current-buffer (get-buffer-create appt-buffer-name)
-    (let ((inhibit-read-only t))
-      (exco-diary--fix-percent-signs))))
-
-(defun exco-diary-insert-meeting (finalize
-                                 subject start _end _location
-                                 _main-invitees _optional-invitees
-                                 icalendar-text)
-  "Insert a retrieved meeting into the diary.
-See also the documentation for `exco-calendar-item-iterate'.  The
-arguments are SUBJECT, a string, the subject of the meeting,
-START, the start date and time in Emacs internal representation,
-and ICALENDAR-TEXT, iCalendar text representing the meeting.
-_END, _LOCATION, _MAIN-INVITEES, and _OPTIONAL-INVITEES are
-unused.
-
-Call FINALIZE after the meeting has been inserted."
-  (when (not (string-match "^Cancel[l]?ed: " subject))
-    ;; FIXME: Sometimes meetings are duplicated if they have
-    ;; overlapping (and (diary-cyclic ...) (diary-block ...)) ranges,
-    ;; e.g., one in the today file and one in the transient file.
-    ;; Maybe we should de-duplicate them in the final display.  If the
-    ;; meeting start time is sometime today then put it in today's
-    ;; diary file, otherwise put it in the transient one.
-    (let* ((time (decode-time (current-time)))
-          (now (list (elt time 3) (elt time 4) (elt time 5)))
-          (dawn (apply #'encode-time 0 0 0 now))
-          (dusk (time-add dawn (seconds-to-time 86400)))
-          (file (if (and (time-less-p dawn start) (time-less-p start dusk))
-                    excorporate-diary-today-file
-                  excorporate-diary-transient-file)))
-      (with-temp-buffer
-       (insert icalendar-text)
-
-       ;; FIXME: Maybe some users of multiple calendars will want to
-       ;; know the source calendar's name for each diary entry.
-       ;; There is no great way to achieve that right now, but one
-       ;; idea is to add X-WR-CALNAME support to
-       ;; icalendar-import-buffer, replace the
-       ;; exco-diary-insert-meeting argument to
-       ;; exco-calendar-item-with-details-iterate with:
-       ;;
-       ;; (lambda (&rest arguments)
-       ;;  (apply #'exco-diary-insert-meeting identifier arguments))
-       ;;
-       ;; and uncomment the following code.
-       ;;
-       ;; (goto-char (point-min))
-       ;; (while (re-search-forward
-       ;;      "^SUMMARY\\([^:]*\\):\\(.*\\(\n[        ].*\\)*\\)" nil t)
-       ;;   (insert (format "\nX-WR-CALNAME: (%s)" identifier)))
-
-       ;; Escape literal percent signs (%).  Use less-than sign (<)
-       ;; and greater-than sign (>) which are forbidden URL
-       ;; characters, so that in the plain text diary file,
-       ;; percent-encoded URLs become completely invalid rather than
-       ;; slightly wrong.
-       (goto-char (point-min))
-       (while (re-search-forward "%" nil t)
-         (replace-match "<EXCO_PERCENT_SIGN>"))
-       (icalendar-import-buffer file t))))
-  (funcall finalize))
-
-;; Bound in appt-check.
-(defvar appt-display-diary)
-
-(defun exco-diary-diary-advice (today date advisee &rest arguments)
-  "Advise `diary' and `diary-view-entries' to add Excorporate support.
-TODAY is today's date in `calendar-current-date' format.  DATE is
-the desired date to retrieve meetings for, in the same format.
-ADVISEE is the original function being advised.  ARGUMENTS are
-the arguments to the advisee."
-  ;; FIXME: Currently numeric arguments to `diary' and
-  ;; `diary-view-entries' are ignored.
-  (exco-connection-iterate
-   (lambda ()
-     (message "Retrieving diary entries via Excorporate...")
-     (exco-diary-initialize (calendar-date-equal today date)))
-   (lambda (identifier callback)
-     (cl-destructuring-bind (month day year) date
-       (exco-get-meetings-for-day identifier month day year callback)))
-   (lambda (identifier response finalizer)
-     (exco-calendar-item-with-details-iterate identifier response
-                                             #'exco-diary-insert-meeting
-                                             finalizer))
-   (lambda ()
-     (apply advisee arguments)
-     ;; Warning: It is crucial to set appt-display-diary to nil here,
-     ;; so that diary advice isn't entered repeatedly (ultimately via
-     ;; the `appt-update-list' hook in `write-file-functions'), which
-     ;; would create a connection-callback loop.
-     (let ((appt-display-diary nil))
-       (appt-check t))
-     (message "Done retrieving diary entries via Excorporate."))
-   t)
-  ;; Just return nil from this advice.  We eventually run the advisee
-  ;; asynchronously so there is no way of providing the same return
-  ;; value as the unadvised `diary' and `diary-view-entries'
-  ;; functions.  Luckily they seem to only be used interactively, at
-  ;; least within Emacs itself.
-  nil)
-
-(defun exco-diary-diary-around (original-diary &rest arguments)
-  "Call `diary' asynchronously.
-Retrieve diary entries via Excorporate before showing results.
-ORIGINAL-DIARY is the original `diary' function, and ARGUMENTS
-are the arguments to it."
-  (let ((today (calendar-current-date))
-       (date (calendar-current-date)))
-    (apply #'exco-diary-diary-advice today date original-diary arguments)))
-
-(defun exco-diary-diary-view-entries-override (&rest arguments)
-  "Override `diary-view-entries' to make it asynchronous.
-Retrieve diary entries via Excorporate before showing results.
-ARGUMENTS are the arguments to `diary-view-entries'."
-  (interactive "p")
-  (diary-check-diary-file)
-  (let ((today (calendar-current-date))
-       (date (calendar-cursor-to-date t)))
-    (apply #'exco-diary-diary-advice today date
-          #'diary-list-entries date arguments)))
-
-;;;###autoload
-(defun excorporate-diary-enable ()
-  "Enable Excorporate diary support."
-  (interactive)
-  ;; Create the directory for Excorporate diary files if it doesn't
-  ;; already exist.
-  (exco-diary-initialize t)
-  ;; Remove advice first so that `diary' will not be run by any save
-  ;; hooks.
-  (advice-remove #'diary #'exco-diary-diary-around)
-  (advice-remove #'diary-view-entries #'exco-diary-diary-view-entries-override)
-  (with-current-buffer (find-file-noselect diary-file)
-    (dolist (file (list excorporate-diary-transient-file
-                       excorporate-diary-today-file))
-      (save-excursion
-       (goto-char (point-min))
-       (when (not (re-search-forward
-                   (concat "^ *" diary-include-string " *\"" file "\"") nil t))
-         (let ((include-string (concat diary-include-string " \"" file "\"")))
-           (if (string-match "omit-trailing-space"
-                             (documentation 'diary-make-entry))
-               (with-no-warnings
-                 (diary-make-entry include-string nil nil t t))
-             (exco-diary-diary-make-entry include-string)))
-         (save-buffer)))))
-  (advice-add #'diary :around #'exco-diary-diary-around)
-  (advice-add #'diary-view-entries :override
-             #'exco-diary-diary-view-entries-override)
-  (add-hook 'diary-list-entries-hook #'diary-sort-entries)
-  (add-hook 'diary-list-entries-hook #'diary-include-other-diary-files)
-  (add-hook 'diary-fancy-display-mode-hook #'exco-diary--fix-percent-signs)
-  (unless (eq appt-disp-window-function 'exco-diary-appt-disp-window)
-    (if (eq appt-disp-window-function 'appt-disp-window)
-       ;; exco-diary-appt-disp-window is compatible with
-       ;; appt-disp-window, so override it.
-       (setq appt-disp-window-function 'exco-diary-appt-disp-window)
-      (warn (format (concat "Excorporate diary support needs appt-disp-window"
-                           " but appt-disp-window-function is currently %S")
-                   appt-disp-window-function))))
-  (unless (eq diary-display-function 'diary-fancy-display)
-    (warn (format
-          (concat "Excorporate diary support needs diary-fancy-display"
-                  " but diary-display-function is currently %S")
-          diary-display-function)))
-  (appt-activate 1)
-  (message "Excorporate diary support enabled."))
-
-(defun excorporate-diary-disable ()
-  "Disable Excorporate diary support."
-  (interactive)
-  (advice-remove #'diary #'exco-diary-diary-around)
-  (advice-remove #'diary-view-entries #'exco-diary-diary-view-entries-override)
-  (remove-hook 'diary-fancy-display-mode-hook #'exco-diary--fix-percent-signs)
-  (when (eq appt-disp-window-function 'exco-diary-appt-disp-window)
-    (setq appt-disp-window-function 'appt-disp-window))
-  (with-current-buffer (find-file-noselect diary-file)
-    (dolist (file (list excorporate-diary-transient-file
-                       excorporate-diary-today-file))
-      (save-excursion
-       (goto-char (point-min))
-       (when (search-forward
-              (concat diary-include-string " \"" file "\"") nil t)
-         (delete-region (progn (beginning-of-line) (point))
-                        (progn (forward-line 1) (point)))
-         (save-buffer)))))
-  (message "Excorporate diary support disabled."))
-
-(provide 'excorporate-diary)
-
-;;; excorporate-diary.el ends here
diff --git a/packages/excorporate/excorporate-org.el 
b/packages/excorporate/excorporate-org.el
deleted file mode 100644
index 868fe72..0000000
--- a/packages/excorporate/excorporate-org.el
+++ /dev/null
@@ -1,364 +0,0 @@
-;;; excorporate-org.el --- Exchange Org Mode view     -*- lexical-binding: t 
-*-
-
-;; Copyright (C) 2016-2020 Free Software Foundation, Inc.
-
-;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
-;; Keywords: calendar
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Use Org Mode to display daily meetings.
-
-;;; Code:
-
-(require 'org)
-(require 'excorporate)
-(require 'cl-lib)
-
-(defvar excorporate-org-buffer-name "*Excorporate*"
-  "The buffer into which Org Mode output is inserted.")
-
-(defvar exco-org--temporary-buffers '()
-  "A list of per-connection result buffers.")
-
-(defun exco-org--calendar-item-region-at-point ()
-  "A special case replacement for `org-element-at-point'.
-Return a list (BEGIN END) representing the region of the element
-at point, if point is at a calendar item.  If point is not at a
-calendar item, return nil.  This works back to Emacs 24.1's
-built-in Org 9.1.9 which does not have the `org-element'
-feature."
-  (catch 'not-a-calendar-item
-    (save-excursion
-      (cl-values
-       (progn (ignore-errors (org-back-to-heading))
-             (unless (looking-at "^\\*\\* ") (throw 'not-a-calendar-item nil))
-             (point))
-       (progn (org-end-of-subtree) (forward-char 1)
-             (point))))))
-
-(defun exco-org--connection-identifier-at-point ()
-  "Return the connection identifier associated with point."
-  (let* ((calendar-headline
-         (save-excursion
-           (org-up-heading-safe)
-           (org-trim (substring-no-properties (thing-at-point 'line))))))
-    (when (string-match "\\* Calendar (\\(.*\\))$" calendar-headline)
-      (car (read-from-string (match-string 1 calendar-headline))))))
-
-(defun exco-org--item-identifier-at-point ()
-  "Return the item identifier associated with point."
-  (car (read-from-string
-       (org-entry-get (car (org-get-property-block)) "Identifier"))))
-
-(defun exco-org--is-meeting ()
-  "Return t if the entry at point is a meeting, not an appointment."
-  (let ((region (exco-org--calendar-item-region-at-point)))
-    (when region
-      (let ((item-text (apply #'buffer-substring-no-properties region)))
-       (when (string-match "^\+ Invitees:$" item-text) t)))))
-
-(defun exco-org--organizer ()
-  "Return a string representing the item at point's organizer."
-  (let ((region (exco-org--calendar-item-region-at-point)))
-    (when region
-      (let ((item-text (apply #'buffer-substring-no-properties region)))
-       (string-match "^+ Organizer: \\(.*\\)$" item-text)
-       ;; FIXME: Is this a critical region?
-       (match-string 1 item-text)))))
-
-(defun exco-org--organizer-matches-connection ()
-  "Return non-nil if the entry at point is owned by the connection owner."
-  (let ((identifier (exco-org--connection-identifier-at-point))
-       (organizer (exco-org--organizer)))
-    (cond
-     ((stringp identifier)
-      (equal identifier organizer))
-     ((consp identifier)
-      (equal (car identifier) organizer))
-     (t
-      (error "Did not recognize error")))))
-
-(defmacro exco-org--handle-response (response
-                                    response-type success failure &rest forms)
-  "Handle a server response RESPONSE.
-RESPONSE-TYPE is one of CreateItemResponseMessage or
-DeleteItemResponseMessage.  SUCCESS and FAILURE are strings added
-to the success and failure messages to the user.  FORMS are what
-to do, starting from point being in the calendar entry being
-operated on."
-  `(let ((response-code (exco-extract-value '(ResponseMessages
-                                             ,response-type
-                                             ResponseCode)
-                                           ,response)))
-       (if (equal response-code "NoError")
-          (progn ,@forms (message "excorporate-org: Successfully %s" ,success))
-        (message "excorporate-org: Failed to %s: %S" ,failure ,response))))
-
-(defun exco-org--remove-calendar-item ()
-  "Remove the calendar item at point."
-  (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
-    (let ((region (exco-org--calendar-item-region-at-point)))
-      (when region
-       (let ((inhibit-read-only t))
-         (apply #'delete-region region))))))
-
-(defun exco-org--reply-to-meeting (acceptance do-not-prompt-for-message)
-  "Reply to a meeting.
-ACCEPTANCE is a symbol, one of `accept', `tentatively-accept', or
-`decline'.  If DO-NOT-PROMPT-FOR-MESSAGE is non-nil, do not
-prompt for or include a reply message, otherwise prompt for the
-reply message."
-  (let (prompt success failure)
-    (cl-ecase acceptance
-      (accept
-       (setq prompt "Acceptance message: ")
-       (setq success "accepted")
-       (setq failure "accept"))
-      (tentatively-accept
-       (setq prompt "Tentative acceptance message: ")
-       (setq success "accepted tentatively")
-       (setq failure "accept tentatively"))
-      (decline
-       (setq prompt "Declination message: ")
-       (setq success "declined")
-       (setq failure "decline")))
-    (let ((message (when (not do-not-prompt-for-message)
-                    (read-from-minibuffer prompt)))
-         (identifier (exco-org--connection-identifier-at-point))
-         (item-identifier (exco-org--item-identifier-at-point)))
-      (exco-calendar-item-meeting-reply
-       identifier item-identifier message acceptance
-       (lambda (_identifier response)
-        (exco-org--handle-response response CreateItemResponseMessage
-                                   success failure))))))
-
-(defun exco-org-accept-meeting-request (&optional argument)
-  "Accept the meeting at point.
-With a prefix argument, ARGUMENT, do not prompt for acceptance
-message text, and do not send an acceptance response."
-  (interactive "P")
-  (exco-org--reply-to-meeting 'accept argument))
-
-(defun exco-org-decline-meeting-request (&optional argument)
-  "Decline the meeting at point.
-With a prefix argument, ARGUMENT, do not prompt for declination
-message text, and do not send a declination message."
-  (interactive "P")
-  (exco-org--reply-to-meeting 'decline argument))
-
-(defun exco-org-tentatively-accept-meeting-request (&optional argument)
-  "Tentatively accept the meeting at point.
-With a prefix argument, ARGUMENT, do not prompt for tentative
-acceptance message text, and do not send a tentative acceptance
-message."
-  (interactive "P")
-  (exco-org--reply-to-meeting 'tentatively-accept argument))
-
-(defun exco-org-cancel-meeting ()
-  "Cancel the meeting at point, prompting for a cancellation message."
-  (interactive)
-  (unless (exco-org--is-meeting)
-    (error (concat "This looks like an appointment,"
-                  " try `exco-org-delete-appointment' instead.")))
-  (let ((identifier (exco-org--connection-identifier-at-point))
-       (item-identifier (exco-org--item-identifier-at-point)))
-    ;; Make sure the meeting owner matches the connection owner before
-    ;; attempting to cancel the meeting.
-    (unless (exco-org--organizer-matches-connection)
-      (error (concat "exco-org will only attempt to delete"
-                    " meetings for which you are the organizer")))
-    (when item-identifier
-      (exco-calendar-item-meeting-cancel
-       identifier item-identifier
-       (read-from-minibuffer "Cancellation message: ")
-       (lambda (_identifier response)
-        (exco-org--handle-response
-         response CreateItemResponseMessage
-         "cancelled meeting" "cancel meeting"
-         (exco-org--remove-calendar-item)))))))
-
-(defun exco-org-delete-appointment (&optional argument)
-  "Delete the appointment at point.
-With a prefix argument, ARGUMENT, force-delete this calendar item
-without first checking if it is a meeting.  This is required
-sometimes, for example as a way to delete meetings for which one
-is the organizer and the sole invitee, since the server will
-refuse to send a meeting cancellation message to the organizer."
-  (interactive "P")
-  (when (and (not argument)
-            (exco-org--is-meeting))
-    (error "This looks like a meeting, try `exco-org-cancel-meeting' instead"))
-  (let ((identifier (exco-org--connection-identifier-at-point))
-       (item-identifier (exco-org--item-identifier-at-point)))
-    (when item-identifier
-      (exco-calendar-item-appointment-delete
-       identifier item-identifier
-       (lambda (_identifier response)
-        (exco-org--handle-response
-         response DeleteItemResponseMessage
-         "deleted appointment" "delete appointment"
-         (exco-org--remove-calendar-item)))))))
-
-(defun exco-org-initialize-buffer ()
-  "Add initial text to the destination buffer."
-  (setq exco-org--temporary-buffers '())
-  (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
-      (setq buffer-read-only t)
-      ;; Some Org mode configurations need `buffer-file-name' to be
-      ;; non-nil, or they'll make `org-mode' error out, for example
-      ;; `org-startup-with-latex-preview'.  Set `buffer-file-name' to
-      ;; something non-nil temporarily during initialization.  Don't
-      ;; leave it set or `save-some-buffers' will always prompt about
-      ;; *Excorporate*.
-      (let ((buffer-file-name excorporate-org-buffer-name))
-       (org-mode))
-      (use-local-map (copy-keymap org-mode-map))
-      (local-set-key "q" 'quit-window)
-      (display-buffer (current-buffer))
-      (let ((inhibit-read-only t))
-       (delete-region (point-min) (point-max))
-       (goto-char (point-min))
-       (insert "# Updated..."))))
-
-(defun exco-org-format-headline (identifier)
-  "Format an Org headline using IDENTIFIER."
-  (format "* Calendar (%S)\n" identifier))
-
-(defun exco-org-insert-meeting-headline (subject
-                                        start-time end-time
-                                        &optional item-identifier)
-  "Insert and schedule a meeting.
-SUBJECT is the meeting's subject, START-TIME and END-TIME are the
-meeting's start and end times in the same format as is returned
-by `current-time'.  ITEM-IDENTIFIER is the opaque item
-identifier."
-  (let* ((now (current-time))
-        (keyword (if (time-less-p now end-time)
-                     "TODO"
-                   "DONE")))
-    (insert (format "** %s %s\n" keyword subject))
-    (org-schedule nil (format-time-string "<%Y-%m-%d %a %H:%M>"
-                                         start-time))
-    (forward-line -1)
-    (end-of-line)
-    (insert  "--" (format-time-string "<%Y-%m-%d %a %H:%M>" end-time))
-    (forward-line)
-    (org-set-property "Identifier" (format "%S" item-identifier))
-    (org-insert-time-stamp (current-time) t t "+ Retrieved " "\n")))
-
-(defun exco-org-insert-invitees (invitees)
-  "Parse and insert a list of invitees, INVITEES."
-  (dolist (invitee invitees)
-    (insert (format "  + %s\n" invitee))))
-
-(defun exco-org--identifier-buffer (identifier)
-  "Return a hidden buffer with a name based on IDENTIFIER."
-  (get-buffer-create
-   (format " *exco-org-%S*" identifier)))
-
-(defun exco-org-insert-headline (identifier month day year)
-  "Insert Org headline for IDENTIFIER on date MONTH DAY YEAR."
-  (let ((temporary-buffer (exco-org--identifier-buffer identifier)))
-    (push temporary-buffer exco-org--temporary-buffers)
-    (with-current-buffer temporary-buffer
-      (let ((inhibit-read-only t))
-       (delete-region (point-min) (point-max))
-       (insert (exco-org-format-headline identifier))
-       (org-insert-time-stamp (encode-time 0 0 0 day month year)
-                              nil t "  + Date " "\n")))))
-
-(defun exco-org-insert-meeting (subject start end location
-                               main-invitees optional-invitees
-                               &optional item-identifier organizer)
-  "Insert a scheduled meeting.
-SUBJECT is a string, the subject of the meeting.  START is the
-meeting start time in Emacs internal date time format, and END is
-the end of the meeting in the same format.  LOCATION is a string
-representing the location.  MAIN-INVITEES and OPTIONAL-INVITEES
-are the requested participants.  ITEM-IDENTIFIER is the opaque
-item identifier.  ORGANIZER is a string, the email address of the
-meeting organizer."
-  (exco-org-insert-meeting-headline subject start end item-identifier)
-    (insert (format "+ Duration: %d minutes\n"
-                   (round (/ (float-time (time-subtract end start)) 60.0))))
-    (insert (format "+ Location: %s\n" location))
-    (insert (format "+ Organizer: %s\n" organizer))
-    (when main-invitees
-      (insert "+ Invitees:\n")
-      (exco-org-insert-invitees main-invitees))
-    (when optional-invitees
-      (insert "+ Optional invitees:\n")
-      (exco-org-insert-invitees optional-invitees)))
-
-(defun exco-org-insert-meetings (identifier response)
-  "Insert the connection IDENTIFIER's meetings from RESPONSE."
-  (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
-    (let ((inhibit-read-only t))
-      (goto-char (point-min))
-      (end-of-line)
-      (insert (format "%s..." identifier))))
-  (with-current-buffer (exco-org--identifier-buffer identifier)
-    (let ((inhibit-read-only t))
-      (org-insert-time-stamp (current-time) t t "  + Last checked " "\n")
-      (exco-calendar-item-iterate-general
-       response (lambda (&rest arguments)
-                 (with-current-buffer (exco-org--identifier-buffer identifier)
-                   (org-mode)
-                   (let ((new-arguments arguments))
-                     (setf (nth 7 new-arguments)
-                           (exco-resolve-organizer-email-address-synchronously
-                            identifier organizer-structure))
-                     (apply #'exco-org-insert-meeting new-arguments))))
-       subject start-internal end-internal
-       location main-invitees optional-invitees item-identifier
-       organizer-structure)
-      (goto-char (point-min))
-      (if (save-excursion (org-goto-first-child))
-         (org-sort-entries t ?s)
-       (forward-line 3)
-       (insert "`♘\n")))))
-
-(defun exco-org-finalize-buffer ()
-  "Finalize text in buffer after all connections have responded."
-  (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
-    ;; Sort top-level entries alphabetically.
-    (let ((inhibit-read-only t))
-      (goto-char (point-min))
-      (end-of-line)
-      (insert "done.\n")
-      (dolist (result-buffer (nreverse exco-org--temporary-buffers))
-       (insert-buffer-substring result-buffer)
-       (save-excursion (org-up-heading-safe) (org-cycle-hide-drawers 'all))
-       (kill-buffer result-buffer))
-      (setq exco-org--temporary-buffers '()))))
-
-;;;###autoload
-(defun exco-org-show-day (month day year)
-  "Show meetings for the date specified by MONTH DAY YEAR."
-  (exco-connection-iterate #'exco-org-initialize-buffer
-                          (lambda (identifier callback)
-                            (exco-org-insert-headline identifier
-                                                      month day year)
-                            (exco-get-meetings-for-day identifier
-                                                       month day year
-                                                       callback))
-                          #'exco-org-insert-meetings
-                          #'exco-org-finalize-buffer))
-
-(provide 'excorporate-org)
-
-;;; excorporate-org.el ends here
diff --git a/packages/excorporate/excorporate.el 
b/packages/excorporate/excorporate.el
deleted file mode 100644
index 4678da1..0000000
--- a/packages/excorporate/excorporate.el
+++ /dev/null
@@ -1,1212 +0,0 @@
-;;; excorporate.el --- Exchange Web Services (EWS) integration -*- 
lexical-binding: t -*-
-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
-;; Maintainer: Thomas Fitzsimmons <fitzsim@fitzsim.org>
-;; Created: 2014-09-19
-;; Version: 0.9.1
-;; Keywords: calendar
-;; Homepage: https://www.fitzsim.org/blog/
-;; Package-Requires: ((emacs "24.1") (fsm "0.2.1") (soap-client "3.2.0") 
(url-http-ntlm "2.0.4") (nadvice "0.3"))
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Excorporate provides Exchange integration for Emacs.
-
-;; To create a connection to a web service:
-
-;; M-x excorporate
-
-;; Excorporate will prompt for an email address that it will use to
-;; automatically discover settings.  Then it will connect to two or
-;; three separate hosts: the autodiscovery host, the web service host
-;; or load balancer, and the actual server if there is a load
-;; balancer.  Therefore you may be prompted for your credentials two
-;; or three times.
-
-;; You should see a message indicating that the connection is ready
-;; either in the minibuffer or failing that in the *Messages* buffer.
-
-;; Finally, run M-x calendar, and press 'e' to show today's meetings.
-
-;; Please try autodiscovery first and report issues not yet listed
-;; below.  When autodiscovery works it is very convenient; the goal is
-;; to make it work for as many users as possible.
-
-;; If autodiscovery fails, customize `excorporate-configuration' to
-;; skip autodiscovery.
-
-;; Autodiscovery will fail if:
-
-;; - Excorporate is accessing the server through a proxy (Emacs
-;;   bug#10).
-
-;; - The server is not configured to support autodiscovery.
-
-;; - The email address is at a different domain than the server, e.g.,
-;;   user@domain1.com, autodiscover.domain2.com.
-
-;; - Authentication is Kerberos/GSSAPI.
-
-;; Excorporate does know about the special case where the mail address
-;; is at a subdomain, e.g., user@sub.domain.com, and the server is at
-;; the main domain, e.g., autodiscover.domain.com.  Autodiscovery will
-;; work in that case.
-
-;; Excorporate must be loaded before any other package that requires
-;; `soap-client'.  The version of `soap-client' that Excorporate
-;; bundles is backward compatible.
-
-;; Acknowledgments:
-
-;; Alexandru Harsanyi <AlexHarsanyi@gmail.com> provided help and
-;; guidance on how to extend soap-client.el's WSDL and XSD handling,
-;; enabling support for the full Exchange Web Services API.
-
-;; Alex Luccisano <casual.lexicon@gmail.com> tested early versions of
-;; this library against a corporate installation of Exchange.
-
-;; Jon Miller <jonebird@gmail.com> tested against Exchange 2013.  He
-;; also tracked down and reported a bad interaction with other
-;; packages that require soap-client.
-
-;; Nicolas Lamirault <nicolas.lamirault@gmail.com> tested the
-;; autodiscovery feature.
-
-;; Trey Jackson <bigfaceworm@gmail.com> confirmed autodiscovery worked
-;; for him.
-
-;; Joakim Verona <joakim@verona.se> tested autodiscovery in a
-;; Kerberos/GSSAPI environment.
-
-;; Wilfred Hughes <me@wilfred.me.uk> tested on Exchange 2007 and
-;; suggested documentation improvements.
-
-;; Erik Hetzner <egh@e6h.org> tested on Office 365 and helped debug
-;; Office 365 support.
-
-;; Fabio Leimgruber <fabio.leimgruber@web.de> tested NTLM
-;; authentication against a challenging server configuration.
-
-;; Stefan Monnier <monnier@iro.umontreal.ca> wrote a variant of
-;; nadvice.el for GNU ELPA so that Excorporate could continue
-;; supporting Emacs versions 24.1, 24.2 and 24.3.
-
-;; Collin Day <dcday137@gmail.com> tested and helped debug accessing
-;; Office 365 through an HTTPS proxy.
-
-;;; Code:
-
-;; Implementation-visible functions and variables.
-
-;; Add NTLM authorization scheme.
-(require 'url-http-ntlm)
-(require 'soap-client)
-(require 'fsm)
-(require 'excorporate-calendar)
-(require 'org)
-
-;; For Office 365, URLs containing autodiscover-s.outlook.com do not
-;; seem to work properly (the returned XML gives ErrorCode 600).
-(defconst exco--autodiscovery-templates
-  '("https://%s/autodiscover/autodiscover.svc";
-    "https://autodiscover.%s/autodiscover/autodiscover.svc";)
-  "Autodiscovery URL templates.
-URL templates to be formatted with a domain name, then searched
-for autodiscovery files.")
-
-(defvar exco--connections nil
-  "A hash table of finite state machines.
-The key is the identifier passed to `exco-connect'.  Each finite
-state machine represents a service connection.")
-
-(defvar exco--connection-identifiers nil
-  "An ordered list of connection identifiers.")
-
-(defvar exco--server-timeout 5
-  "The timeout in seconds to wait for a synchronous server response.")
-
-(defun exco--parse-xml-in-current-buffer ()
-  "Decode and parse the XML contents of the current buffer."
-  (let ((mime-part (mm-dissect-buffer t t)))
-    (unless mime-part
-      (error "Failed to decode response from server"))
-    (unless (equal (car (mm-handle-type mime-part)) "text/xml")
-      (error "Server response is not an XML document"))
-    (with-temp-buffer
-      (mm-insert-part mime-part)
-      (prog1
-         (car (xml-parse-region (point-min) (point-max)))
-       (kill-buffer)
-       (mm-destroy-part mime-part)))))
-
-(defun exco--bind-wsdl (wsdl service-url port-name target-namespace
-                            binding-name)
-  "Create a WSDL binding.
-Create a binding port for WSDL from SERVICE-URL, PORT-NAME,
-TARGET-NAMESPACE and BINDING-NAME."
-  (let* ((namespace (soap-wsdl-find-namespace target-namespace wsdl))
-        (port (make-soap-port
-               :name port-name
-               :binding (cons target-namespace binding-name)
-               :service-url service-url)))
-    (soap-namespace-put port namespace)
-    (push port (soap-wsdl-ports wsdl))
-    (soap-resolve-references port wsdl)
-    wsdl))
-
-(defun exco--handle-url-error (url status)
-  "Handle an error that occurred when retrieving URL.
-The details of the error are in STATUS, in the same format as the
-argument to a `url-retrieve' callback.  Return non-nil to retry,
-nil to continue."
-  (if (eq (cl-third (plist-get status :error)) 500)
-      ;; The server reported an internal server error.  Try to recover
-      ;; by re-requesting the target URL and its most recent redirect.
-      ;; I'm not sure what conditions cause the server to get into
-      ;; this state -- it might be because the server has stale
-      ;; knowledge of old keepalive connections -- but this should
-      ;; recover it.  We need to disable ntlm in
-      ;; url-registered-auth-schemes so that it doesn't prevent
-      ;; setting keepalives to nil.
-      (let ((url-registered-auth-schemes nil)
-           (url-http-attempt-keepalives nil)
-           (redirect (plist-get status :redirect)))
-       (fsm-debug-output "exco--fsm received 500 error for %s" url)
-       (url-debug 'excorporate "Attempting 500 recovery")
-       (ignore-errors
-         ;; Emacs's url-retrieve does not respect the values of
-         ;; url-http-attempt-keepalives and
-         ;; url-registered-auth-schemes in asynchronous contexts.
-         ;; Unless url.el is eventually changed to do so, the
-         ;; following requests must be synchronous so that they run
-         ;; entirely within url-http-attempt-keepalives's dynamic
-         ;; extent.  These calls block the main event loop,
-         ;; unfortunately, but only in this rare error recovery
-         ;; scenario.
-         (url-retrieve-synchronously url)
-         (when redirect (url-retrieve-synchronously redirect)))
-       (url-debug 'excorporate "Done 500 recovery attempt")
-       ;; Retry.
-       t)
-    ;; We received some other error, which just
-    ;; means we should try the next URL.
-    (fsm-debug-output "exco--fsm didn't find %s" url)
-    ;; Don't retry.
-    nil))
-
-(defun exco--retrieve-next-import (fsm state-data return-for next-state)
-  "Retrieve the next XML schema import.
-FSM is the finite state machine, STATE-DATA is FSM's state data,
-and RETURN-FOR is one of :enter or :event to indicate what return
-type the calling function expects.  NEXT-STATE is the next state
-the FSM should transition to on success."
-  (let* ((url (plist-get state-data :service-url))
-        (xml (plist-get state-data :service-xml))
-        (wsdl (plist-get state-data :service-wsdl))
-        (imports (soap-wsdl-xmlschema-imports wsdl))
-        (next-state (if imports :parsing-service-wsdl next-state)))
-    (when imports
-      (let ((import-url (url-expand-file-name (pop imports) url)))
-       (let ((url-request-method "GET")
-             (url-package-name "soap-client.el")
-             (url-package-version "1.0")
-             (url-mime-charset-string "utf-8;q=1, iso-8859-1;q=0.5")
-             (url-http-attempt-keepalives t))
-         (url-retrieve
-          import-url
-          (lambda (status)
-            (let ((data-buffer (current-buffer)))
-              (unwind-protect
-                  (progn
-                    (url-debug 'excorporate "Processing import %s" status)
-                    (if (eq (car status) :error)
-                        ;; There is an error.  It may be recoverable
-                        ;; if it's HTTP 500 (internal server error).
-                        (if (and (exco--handle-url-error import-url status)
-                                 ;; Only retry once.
-                                 (not (plist-get state-data :retrying)))
-                            ;; We should retry.  Don't save the
-                            ;; popped urls list to state-data, so
-                            ;; that this :try-next-url will
-                            ;; re-attempt to retrieve the same car as
-                            ;; before.  Set the retry flag.
-                            (progn
-                              (plist-put state-data :retrying t))
-                          ;; Save the popped urls list so that the next url
-                          ;; is attempted, and clear the retry flag.
-                          (plist-put state-data :retrying nil)
-                          (setf (soap-wsdl-xmlschema-imports wsdl) imports)
-                          (plist-put state-data :failure-message
-                                     (format "Failed to retrieve %s"
-                                             import-url))
-                          (fsm-send fsm :unrecoverable-error))
-                      ;; Success, parse WSDL.
-                      (plist-put state-data :retrying nil)
-                      (setf (soap-wsdl-xmlschema-imports wsdl) imports)
-                      (soap-with-local-xmlns xml
-                        (soap-wsdl-add-namespace
-                         (soap-parse-schema (soap-parse-server-response) wsdl)
-                         wsdl))
-                      (plist-put state-data :service-wsdl wsdl)))
-                (and (buffer-live-p data-buffer)
-                     (kill-buffer data-buffer))))
-            (fsm-send fsm t))))))
-    (if (eq return-for :enter)
-       (list state-data nil)
-      (list next-state state-data nil))))
-
-(define-state-machine exco--fsm :start
-  ((identifier)
-   "Start an Excorporate finite state machine."
-   (let* ((autodiscover (stringp identifier))
-         (mail (if autodiscover identifier (car identifier)))
-         (url (unless autodiscover (cdr identifier)))
-         (autodiscovery-urls
-          (when autodiscover
-            (let ((domain (cadr (split-string mail "@"))))
-              (unless (and domain (not (equal domain "")))
-                (error "Invalid domain for address %s" mail))
-              (append (mapcar (lambda (template)
-                                (format template domain))
-                              exco--autodiscovery-templates)
-                      ;; Handle the user@sub.domain.com =>
-                      ;; autodiscover.domain.com case reported by a
-                      ;; user.  Only try one extra level.
-                      (let ((domain-parts (split-string domain "\\.")))
-                        (when (> (length domain-parts) 2)
-                          (mapcar (lambda (template)
-                                    (format template
-                                            (mapconcat
-                                             'identity
-                                             (cdr domain-parts) ".")))
-                                  exco--autodiscovery-templates)))))))
-         (service-url (unless autodiscover url))
-         (next-state (if autodiscover
-                         :retrieving-autodiscovery-xml
-                       ;; Go directly to :retrieving-service-xml,
-                       ;; skipping autodiscovery.
-                       :retrieving-service-xml)))
-     (list next-state
-          (list
-           ;; State machine data.
-           ;;
-           ;; Unique finite state machine identifier, either a
-           ;; string, mail-address (which implies the URL is
-           ;; autodiscovered) or a pair of strings, (mail-address
-           ;; . service-url).  This format allows multiple state
-           ;; machines to operate on the same mail address or service
-           ;; URL.  Login credentials are handled separately by
-           ;; auth-source and url, so it should be possible for one
-           ;; Emacs process to have simultaneous Excorporate
-           ;; connections for, e.g.: ("mail-1" . "url-1") and
-           ;; ("mail-2" . "url-1") or even: "mail-1" and ("mail-1"
-           ;; . "url-2") if that's ever desirable.
-           :identifier identifier
-           ;; User data.
-           :mail-address mail
-           ;; Error recovery data.
-           :retrying nil
-           ;; Autodiscovery data.
-           ;; This is nil when not doing autodiscovery.
-           :autodiscovery-urls autodiscovery-urls
-           ;; Service data.
-           ;; When doing autodiscovery this is nil, otherwise
-           ;; it is the service-url field from `identifier'.
-           :service-url service-url
-           :service-xml nil
-           :service-wsdl nil
-           ;; State data.
-           :next-state-after-success nil
-           :failure-message nil
-           :server-version nil)
-          ;; No timeout.
-          nil))))
-
-(define-state exco--fsm :retrieving-autodiscovery-xml
-  (fsm state-data event _callback)
-  (cl-case event
-    (:try-next-url
-     (let ((urls (plist-get state-data :autodiscovery-urls)))
-       (if urls
-          (let ((url (pop urls)))
-            (fsm-debug-output "exco--fsm will probe %s" url)
-            (condition-case nil
-                (url-retrieve
-                 url
-                 (lambda (status)
-                   (let ((data-buffer (current-buffer)))
-                     (unwind-protect
-                         (progn
-                           (url-debug 'excorporate
-                            "Processing status: %s" status)
-                           (if (eq (car status) :error)
-                               (progn
-                                 (if (and
-                                      (exco--handle-url-error url status)
-                                      ;; Only retry once.
-                                      (not (plist-get state-data :retrying)))
-                                     ;; We should retry.  Don't save the popped
-                                     ;; urls list to state-data, so that this
-                                     ;; :try-next-url will re-attempt to
-                                     ;; retrieve the same car as before.  Set
-                                     ;; the retry flag.
-                                     (plist-put state-data :retrying t)
-                                   ;; Save the popped urls list so that the
-                                   ;; next url is attempted, and clear the
-                                   ;; retry flag.
-                                   (plist-put state-data :retrying nil)
-                                   (plist-put state-data
-                                              :autodiscovery-urls urls))
-                                 ;; Try next or retry.
-                                 (fsm-send fsm :try-next-url))
-                             ;; Success, save URL and parse returned XML.
-                             (message
-                              "Excorporate: Found autodiscovery URL for %S: %s"
-                              (plist-get state-data :identifier) url)
-                             (plist-put state-data :retrying nil)
-                             (plist-put state-data :service-url url)
-                             (plist-put state-data :service-xml
-                                        (exco--parse-xml-in-current-buffer))
-                             (fsm-send fsm :success))
-                           (url-debug 'excorporate "Done processing status"))
-                       (and (buffer-live-p data-buffer)
-                            (kill-buffer data-buffer))))))
-              (error
-               (fsm-debug-output "exco--fsm connection refused for %s" url)
-               (plist-put state-data :retrying nil)
-               (plist-put state-data :autodiscovery-urls urls)
-               (fsm-send fsm :try-next-url)))
-            (list :retrieving-autodiscovery-xml state-data nil))
-        (plist-put state-data :failure-message
-                   "Autodiscovery ran out of URLs to try")
-        (list :shutting-down-on-error state-data nil))))
-    (:success
-     (plist-put state-data :next-state-after-success :retrieving-service-xml)
-     (list :parsing-service-wsdl state-data nil))))
-
-(define-enter-state exco--fsm :shutting-down-on-error
-  (_fsm state-data)
-  (let ((failure-message (plist-get state-data :failure-message)))
-    (exco-disconnect (plist-get state-data :identifier))
-    (message "Excorporate: %s" failure-message)
-    (url-debug 'excorporate "Failed: %s" failure-message)
-    (fsm-debug-output "exco--fsm failed: %s" failure-message))
-  (list state-data nil))
-
-(define-state exco--fsm :shutting-down-on-error
-  (_fsm state-data _event _callback)
-  (list :shutting-down-on-error state-data nil))
-
-(define-enter-state exco--fsm :retrieving-service-xml
-  (fsm state-data)
-  (when (stringp (plist-get state-data :identifier))
-    (let* ((xml (plist-get state-data :service-xml))
-          (unbound-wsdl (plist-get state-data :service-wsdl))
-          (wsdl
-           (progn
-             ;; Skip soap-parse-wsdl-phase-fetch-schema to avoid
-             ;; synchronous URL fetches.
-             (soap-parse-wsdl-phase-finish-parsing xml unbound-wsdl)
-             (exco--bind-wsdl
-              (soap-wsdl-resolve-references unbound-wsdl)
-              (plist-get state-data :service-url)
-              "AutodiscoverServicePort"
-              "http://schemas.microsoft.com/exchange/2010/Autodiscover";
-              "DefaultBinding_Autodiscover"))))
-      (soap-invoke-async
-       (lambda (response)
-        (let ((result-url
-               (exco-extract-value '(Response
-                                     UserResponses
-                                     UserResponse
-                                     UserSettings
-                                     UserSetting
-                                     Value)
-                                   response)))
-          (if result-url
-              (progn
-                (plist-put state-data :service-url result-url)
-                (message "Excorporate: Found service URL for %S: %s"
-                         (plist-get state-data :identifier)
-                         (plist-get state-data :service-url)))
-            ;; No result.  Check for error.
-            (let ((error-message
-                   (exco-extract-value '(Response
-                                         UserResponses
-                                         UserResponse
-                                         ErrorMessage)
-                                       response)))
-              (if error-message
-                  (message "Excorporate: %s" error-message)
-                (message "Excorporate: Failed to find service URL"))))
-          (fsm-send fsm :retrieve-xml)))
-       nil
-       wsdl
-       "AutodiscoverServicePort"
-       "GetUserSettings"
-       `((RequestedServerVersion . "Exchange2010")
-        (Request
-         (Users
-          (User
-           (Mailbox . ,(plist-get state-data :mail-address))))
-         (RequestedSettings
-          (Setting . "InternalEwsUrl")))))))
-  (list state-data nil))
-
-(define-state exco--fsm :retrieving-service-xml
-  (fsm state-data event _callback)
-  (cl-case event
-    (:unrecoverable-error
-     (list :shutting-down-on-error state-data nil))
-    (:retrieve-xml
-     (let* ((service-url (plist-get state-data :service-url))
-           (wsdl-url (replace-regexp-in-string "/[^/]*$" "/Services.wsdl"
-                                               service-url)))
-       (url-retrieve wsdl-url
-                    (lambda (status)
-                      (let ((data-buffer (current-buffer)))
-                        (unwind-protect
-                            (if (eq (car status) :error)
-                                (progn
-                                  (plist-put state-data :failure-message
-                                             (format "Failed to retrieve %s"
-                                                     wsdl-url))
-                                  (fsm-send fsm :unrecoverable-error))
-                              (plist-put state-data
-                                         :service-xml
-                                         (exco--parse-xml-in-current-buffer))
-                              (fsm-send fsm :success))
-                          (and (buffer-live-p data-buffer)
-                               (kill-buffer data-buffer)))))))
-     (list :retrieving-service-xml state-data nil))
-    (:success
-     (plist-put state-data :next-state-after-success :retrieving-data)
-     (list :parsing-service-wsdl state-data nil))))
-
-(define-enter-state exco--fsm :parsing-service-wsdl
-  (fsm state-data)
-  (let* ((url (plist-get state-data :service-url))
-        (xml (plist-get state-data :service-xml))
-        (next-state (plist-get state-data :next-state-after-success))
-        (wsdl (soap-make-wsdl url)))
-    (soap-parse-wsdl-phase-validate-node xml)
-    ;; Skip soap-parse-wsdl-phase-fetch-imports to avoid synchronous
-    ;; fetches of import URLs.
-    (soap-parse-wsdl-phase-parse-schema xml wsdl)
-    (plist-put state-data :service-wsdl wsdl)
-    (exco--retrieve-next-import fsm state-data :enter next-state)))
-
-(define-state exco--fsm :parsing-service-wsdl
-  (fsm state-data event _callback)
-  (if (eq event :unrecoverable-error)
-      (list :shutting-down-on-error state-data nil)
-    (let ((next-state (plist-get state-data :next-state-after-success)))
-      (exco--retrieve-next-import fsm state-data :event next-state))))
-
-(defun exco--get-server-version (wsdl)
-  "Extract server version from WSDL."
-  (let ((warning-message "Excorporate: Failed to determine server version")
-       (namespace "http://schemas.microsoft.com/exchange/services/2006/types";)
-       (name "RequestServerVersion")
-       (found-version nil))
-    (unwind-protect
-       (setq found-version
-             (catch 'found
-               (dolist (attribute
-                        (soap-xs-type-attributes
-                         (soap-xs-element-type (soap-wsdl-get
-                                                `(,namespace . ,name)
-                                                wsdl 'soap-xs-element-p))))
-                 (when (equal (soap-xs-attribute-name attribute) "Version")
-                   (throw 'found (car (soap-xs-simple-type-enumeration
-                                       (soap-xs-attribute-type attribute))))))
-               (warn warning-message)
-               nil))
-      (if found-version
-         found-version
-       (warn warning-message)
-       nil))))
-
-(define-enter-state exco--fsm :retrieving-data
-  (_fsm state-data)
-  (let ((wsdl (plist-get state-data :service-wsdl))
-       (identifier (plist-get state-data :identifier)))
-    ;; Skip soap-parse-wsdl-phase-fetch-schema to avoid synchronous
-    ;; URL fetches.
-    (soap-parse-wsdl-phase-finish-parsing (plist-get state-data :service-xml)
-                                         wsdl)
-    (exco--bind-wsdl
-     (soap-wsdl-resolve-references wsdl)
-     (plist-get state-data :service-url)
-     "ExchangeServicePort"
-     "http://schemas.microsoft.com/exchange/services/2006/messages";
-     "ExchangeServiceBinding")
-    (plist-put state-data :server-version (exco--get-server-version wsdl))
-    (fsm-debug-output "exco--fsm %s server version is %s"
-                     identifier (exco-server-version identifier))
-    (message "Excorporate: Connection %S is ready" identifier))
-  (list state-data nil))
-
-(define-state exco--fsm :retrieving-data
-  (_fsm state-data event fsm-result-callback)
-  (let* ((identifier (plist-get state-data :identifier))
-        (wsdl (plist-get state-data :service-wsdl))
-        (name (pop event))
-        (arguments (pop event))
-        (callback (pop event)))
-    (if callback
-       ;; exco-operate.
-       (apply #'soap-invoke-async
-              (lambda (response)
-                (funcall callback identifier response))
-              nil
-              wsdl
-              "ExchangeServicePort"
-              name
-              arguments)
-      ;; exco-operate-synchronously.
-      (funcall
-       fsm-result-callback
-       (apply #'soap-invoke wsdl "ExchangeServicePort" name arguments))))
-  (list :retrieving-data state-data nil))
-
-(defun exco--ensure-connection ()
-  "Ensure at least one connection exists or throw an error."
-  (unless exco--connection-identifiers
-    (error "Excorporate: No connections exist.  Run M-x excorporate")))
-
-(defmacro exco--with-fsm (identifier &rest body)
-  "With `fsm' set to IDENTIFIER, run BODY.
-Run BODY with `fsm' set to the finite state machine specified by
-IDENTIFIER."
-  (declare (indent 1) (debug t))
-  `(progn
-     (exco--ensure-connection)
-     (let ((fsm (gethash ,identifier exco--connections)))
-       (unless fsm
-        (error "Excorporate: Connection %S does not exist" ,identifier))
-       ,@body)))
-
-;; Developer-visible functions and variables.
-
-(defun exco-api-version ()
-  "Return the Excorporate API version.
-Return a non-negative integer representing the current
-Excorporate application programming interface version.  Version 0
-is subject to change."
-  0)
-
-(defun exco-connect (identifier)
-  "Connect or reconnect to a web service.
-IDENTIFIER is either a string representing a mail address or a
-pair of strings, representing a mail address and a service URL.
-
-If IDENTIFIER is a mail address, `exco-connect' will use it to
-autodiscover the service URL to use.  If IDENTIFIER is a pair,
-`exco-connect' will not perform autodiscovery, but will instead
-use the `cdr' of the pair as the service URL."
-  (let ((autodiscover (stringp identifier)))
-    (when autodiscover
-      (message "Excorporate: Starting autodiscovery for %s" identifier))
-    (let ((fsm (start-exco--fsm identifier)))
-      (unless exco--connections
-       (setq exco--connections (make-hash-table :test 'equal)))
-      (when (gethash identifier exco--connections)
-       (exco-disconnect identifier))
-      (puthash identifier fsm exco--connections)
-      (push identifier exco--connection-identifiers)
-      (if autodiscover
-         (fsm-send fsm :try-next-url)
-       (fsm-send fsm :retrieve-xml))
-      nil)))
-
-(defun exco-operate (identifier name arguments callback)
-  "Execute a service operation asynchronously.
-IDENTIFIER is the connection identifier.  Execute operation NAME
-with ARGUMENTS then call CALLBACK with two arguments, IDENTIFIER
-and the server's response."
-  (when (null callback) (error "CALLBACK cannot be nil"))
-  (exco--with-fsm identifier
-    (fsm-send fsm (list name arguments callback)))
-  nil)
-
-(defun exco-operate-synchronously (identifier name arguments)
-  "Execute a service operation synchronously.
-IDENTIFIER is the connection identifier.  Execute operation NAME
-with ARGUMENTS then call CALLBACK with two arguments, IDENTIFIER
-and the server's response."
-  (exco--with-fsm identifier
-    (with-timeout (exco--server-timeout (error "Timed out waiting for server"))
-      (fsm-call fsm (list name arguments)))))
-
-(defun exco-server-version (identifier)
-  "Return the server version for connection IDENTIFIER, as a string.
-Examples are \"Exchange2010\", \"Exchange2010_SP1\",
-\"Exchange2013\"."
-  (exco--with-fsm identifier
-    (plist-get (fsm-get-state-data fsm) :server-version)))
-
-(defun exco-disconnect (identifier)
-  "Disconnect from a web service.
-IDENTIFIER is the mail address used to look up the connection."
-  (exco--with-fsm identifier
-    (setq exco--connection-identifiers
-         (delete identifier exco--connection-identifiers))
-    (remhash identifier exco--connections))
-  nil)
-
-(defun exco-extract-value (path result)
-  "Extract the value at PATH from RESULT.
-PATH is an ordered list of node names."
-  (let ((values (nreverse (car result))))
-    (dolist (path-element path)
-      (setq values (assoc path-element values)))
-    (cdr values)))
-
-(defun exco--create-attendee-structure (attendees required)
-  "Convert a list of email addresses to an Attendees structure or nil.
-ATTENDEES is a list of strings, attendee email addresses.
-REQUIRED is t if the structure should represent required
-attendees and nil for optional attendees.
-Return a structure, or nil, suitable for splicing into
-`exco-operate` parameters with ,@."
-  (when attendees
-    (let ((attendee-list '()))
-      (dolist (address attendees)
-       (push `(Attendee (Mailbox (EmailAddress . ,address))) attendee-list))
-      (list (cons (if required 'RequiredAttendees 'OptionalAttendees)
-                 (nreverse attendee-list))))))
-
-(defun exco-operation-arity-nils (identifier operation)
-  "Return a list of nil arguments for OPERATION.
-IDENTIFIER is the connection for which to look up OPERATION."
-  (let* ((wsdl (exco--with-fsm identifier
-                 (plist-get (fsm-get-state-data fsm) :service-wsdl)))
-         (arity (soap-operation-arity wsdl "ExchangeServicePort" operation)))
-    (make-list arity nil)))
-
-(defun exco-calendar-item-meeting-create (identifier
-                                         subject body start end location
-                                         main-invitees optional-invitees
-                                         callback)
-  "Create a meeting calendar item.
-IDENTIFIER is the connection identifier.
-SUBJECT is a string, the subject of the appointment.
-BODY is a string, the message text of the appointment.
-START is the start date and time in Emacs internal representation.
-END is the end date and time in Emacs internal representation.
-LOCATION is a string representing the location of the meeting.
-MAIN-INVITEES is a list of strings representing required
-participants.
-OPTIONAL-INVITEES is a list of strings representing optional
-participants
-CALLBACK is a callback function called with two arguments,
-IDENTIFIER, the connection identifier for the responding
-connection, and RESPONSE, the server's response to the meeting
-creation."
-  (exco-operate
-   identifier
-   "CreateItem"
-   `(((SendMeetingInvitations . "SendToAllAndSaveCopy")
-      (Items
-       (CalendarItem
-       (Subject . ,subject)
-       (Body (BodyType . "Text") ,body)
-        (Start . ,(exco-format-date-time start))
-        (End . ,(exco-format-date-time end))
-        (Location . ,location)
-       ,@(exco--create-attendee-structure main-invitees t)
-       ,@(exco--create-attendee-structure optional-invitees nil))))
-     ;; Empty arguments.
-     ,@(cdr (exco-operation-arity-nils identifier "CreateItem")))
-   callback))
-
-(defun exco-calendar-item-meeting-reply (identifier
-                                        item-identifier message acceptance
-                                        callback)
-  "Reply to a meeting request.
-IDENTIFIER is the connection identifier.  ITEM-IDENTIFIER is the
-meeting identifier.  MESSAGE is the body of the reply message
-that will be sent to attendees, or nil to omit the message.
-ACCEPTANCE is a symbol representing the type of reply, one of
-`accept', `tentatively-accect' or `decline'.  CALLBACK is a
-callback function called with two arguments, IDENTIFIER, the
-connection identifier for the responding connection, and
-RESPONSE, the server's response to the meeting cancellation."
-  (let ((acceptance-symbol (cl-ecase acceptance
-                            (accept 'AcceptItem)
-                            (tentatively-accept 'TentativelyAcceptItem)
-                            (decline 'DeclineItem))))
-    (exco-operate
-     identifier
-     "CreateItem"
-     `(((MessageDisposition . "SendAndSaveCopy")
-       (Items
-        (,acceptance-symbol
-         (Sensitivity . "Private")
-         (ReferenceItemId ,@(cdr item-identifier))
-         ,@(when message (list `(Body (BodyType . "Text") ,message))))))
-       ;; Empty arguments.
-       ,@(cdr (exco-operation-arity-nils identifier "CreateItem")))
-     callback)))
-
-(defun exco-calendar-item-meeting-cancel (identifier
-                                         item-identifier message callback)
-  "Cancel a meeting.
-IDENTIFIER is the connection identifier.  ITEM-IDENTIFIER is the
-meeting identifier.  MESSAGE is the body of the cancellation
-message that will be sent to attendees.  CALLBACK is a callback
-function called with two arguments, IDENTIFIER, the connection
-identifier for the responding connection, and RESPONSE, the
-server's response to the meeting cancellation."
-  (exco-operate
-   identifier
-   "CreateItem"
-   `(((MessageDisposition . "SendAndSaveCopy")
-      (Items
-       (CancelCalendarItem
-       (ReferenceItemId ,@(cdr item-identifier))
-       (NewBodyContent (BodyType . "Text") ,message))))
-     ;; Empty arguments.
-     ,@(cdr (exco-operation-arity-nils identifier "CreateItem")))
-   callback))
-
-(defun exco-calendar-item-appointment-create (identifier
-                                             subject body start end callback)
-  "Create an appointment calendar item.
-IDENTIFIER is the connection identifier.
-SUBJECT is a string, the subject of the appointment.
-BODY is a string, the message text of the appointment.
-START is the start date and time in Emacs internal representation.
-END is the end date and time in Emacs internal representation.
-CALLBACK is a callback function called with two arguments,
-IDENTIFIER, the connection identifier for the responding
-connection, and RESPONSE, the server's response to the
-appointment creation."
-  (exco-operate identifier
-               "CreateItem"
-               `(((SendMeetingInvitations . "SendToNone")
-                  (Items
-                   (CalendarItem
-                     (Subject . ,subject)
-                    (Body (BodyType . "Text") ,body)
-                     (Start . ,(exco-format-date-time start))
-                     (End . ,(exco-format-date-time end)))))
-                 nil nil nil nil)
-               callback))
-
-(defun exco-calendar-item-appointment-delete (identifier
-                                             item-identifier callback)
-  "Delete an appointment.
-IDENTIFIER is the connection identifier.  ITEM-IDENTIFIER is an
-opaque item identifier.  CALLBACK is a callback function called
-with two arguments, IDENTIFIER, the connection identifier for the
-responding connection, and RESPONSE, the server's response to the
-appointment deletion."
-  (exco-operate identifier
-               "DeleteItem"
-               `(((DeleteType . "MoveToDeletedItems")
-                  (SendMeetingCancellations . "SendToAllAndSaveCopy")
-                  (ItemIds ,item-identifier))
-                 nil nil nil)
-               callback))
-
-(defun exco-calendar-item-get-details (identifier item-identifier process-item)
-  "Query server for details about ITEM-IDENTIFIER.
-IDENTIFIER is the connection identifier.  Call PROCESS-ITEM with
-argument ICALENDAR-TEXT."
-  (exco-operate identifier
-               "GetItem"
-               `(((ItemShape
-                   (BaseShape . "IdOnly")
-                   (IncludeMimeContent . t))
-                  (ItemIds ,item-identifier))
-                 nil nil nil nil nil nil)
-               (lambda (_identifier response)
-                 (let* ((mime-path '(ResponseMessages
-                                     GetItemResponseMessage
-                                     Items
-                                     CalendarItem
-                                     MimeContent))
-                        (character-set-path (append mime-path '(CharacterSet)))
-                        (coding-system (intern (downcase (exco-extract-value
-                                                          character-set-path
-                                                          response)))))
-                   (unless (member coding-system coding-system-list)
-                     (error "Unrecognized coding system: %s"
-                            (exco-extract-value character-set-path response)))
-                   (funcall process-item (decode-coding-string
-                                          (base64-decode-string
-                                           (cdr (exco-extract-value
-                                                 mime-path response)))
-                                          coding-system))))))
-
-;; The organizer email address is in some cases returned in the
-;; server's internal "EX" format which is very long and unfamiliar.
-;; If necessary resolve it to the "SMTP" format.  This is done
-;; synchronously, for simplicity.
-(defun exco-resolve-organizer-email-address-synchronously (identifier
-                                                          organizer-structure)
-  "Return the organizer's SMTP email address as a string.
-IDENTIFIER is the connection identifier to use to resolve
-ORGANIZER-STRUCTURE to the returned value.  ORGANIZER-STRUCTURE
-should be treated as opaque.  If the address is not already an
-SMTP address, then this function queries the server synchronously
-to resolve the SMTP address.  It times out and returns nil if the
-server does not respond in under `exco--server-timeout' seconds."
-  (let* ((wrapped (list (list organizer-structure)))
-        (routing-type
-         (exco-extract-value '(Organizer Mailbox RoutingType) wrapped))
-        (email-address
-         (exco-extract-value '(Organizer Mailbox EmailAddress) wrapped)))
-    (cond
-     ((equal routing-type "EX")
-      (exco-extract-value
-       '(ResponseMessages
-        ResolveNamesResponseMessage
-        ResolutionSet
-        Resolution
-        Mailbox
-        EmailAddress)
-       (with-timeout
-          (exco--server-timeout
-           (progn
-             (message (concat "exco-organizer-smtp-email-address:"
-                              " Server did not respond in time"))
-             nil))
-        (exco-operate-synchronously identifier
-                                    "ResolveNames"
-                                    `(((UnresolvedEntry . ,email-address))
-                                      nil nil nil)))))
-     ((equal routing-type "SMTP") email-address))))
-
-(defmacro exco--calendar-item-dolist (item items &rest forms)
-  "Iterate through ITEMS.
-On each iteration, ITEM is set, and FORMS are run."
-  `(dolist (,item ,items)
-     (let* ((subject (cdr (assoc 'Subject ,item)))
-           (start (cdr (assoc 'Start ,item)))
-           (start-internal (apply #'encode-time
-                                  (soap-decode-date-time
-                                   start 'dateTime)))
-           (end (cdr (assoc 'End ,item)))
-           (end-internal (apply #'encode-time
-                                (soap-decode-date-time
-                                 end 'dateTime)))
-           (location (cdr (assoc 'Location ,item)))
-           (to-invitees (cdr (assoc 'DisplayTo ,item)))
-           (main-invitees (when to-invitees
-                            (mapcar 'org-trim
-                                    (split-string to-invitees ";"))))
-           (cc-invitees (cdr (assoc 'DisplayCc ,item)))
-           (optional-invitees (when cc-invitees
-                                (mapcar 'org-trim
-                                        (split-string cc-invitees ";"))))
-           (item-identifier (assoc 'ItemId ,item))
-           (organizer-structure (assoc 'Organizer ,item)))
-       ,@forms)))
-
-(defun exco-calendar-item-with-details-iterate (identifier
-                                               response
-                                               callback
-                                               finalize)
-  "Iterate through calendar items in RESPONSE, calling CALLBACK on each.
-IDENTIFIER identifies the connection.
-
-CALLBACK takes the following arguments: FINALIZE, which is the
-FINALIZE argument to this function wrapped in a countdown,
-SUBJECT, a string, the subject of the meeting, START, the start
-date and time in Emacs internal representation, END, the start
-date and time in Emacs internal representation, LOCATION, the
-location of the meeting, MAIN-INVITEES, a list of strings
-representing required participants, OPTIONAL-INVITEES, a list of
-strings representing optional participants, DETAILS is the
-meeting request message body, and ICALENDAR-TEXT, the iCalendar
-text representing the meeting series.
-
-CALLBACK must arrange for FINALIZE to be called after its main
-processing is done."
-  (let* ((items (exco-extract-value '(ResponseMessages
-                                     FindItemResponseMessage
-                                     RootFolder
-                                     Items)
-                                   response))
-        (countdown (length items))
-        (finalizer
-         (lambda (&rest arguments)
-           (setq countdown (1- countdown))
-           (when (equal countdown 0)
-             (apply finalize arguments)))))
-    (if (equal countdown 0)
-       (funcall finalize)
-      (exco--calendar-item-dolist
-       calendar-item items
-       (exco-calendar-item-get-details
-       identifier item-identifier
-       (lambda (icalendar-text)
-         (funcall callback finalizer subject start-internal end-internal
-                  location main-invitees optional-invitees
-                  icalendar-text)))))))
-
-(defmacro exco-calendar-item-iterate-general (response
-                                             callback &rest care-abouts)
-  "Iterate through calendar items in RESPONSE, calling CALLBACK on each.
-Return a list of results from callback.  CARE-ABOUTS is a list of
-symbols representing the arguments with which CALLBACK should be
-called.  Options are:
-SUBJECT, a string, the subject of the meeting.
-START, the start date and time in Emacs internal representation.
-END, the start date and time in Emacs internal representation.
-LOCATION, the location of the meeting.
-MAIN-INVITEES, a list of strings, email addresses of the required
-participants.
-OPTIONAL-INVITEES, a list of strings, email addresses of optional
-participants.
-ITEM-IDENTIFIER, a structure representing the calendar item.  It
-should be treated as opaque.
-ORGANIZER-STRUCTURE, a structure representing the organizer of
-the meeting.  It should be treated as opaque and resolved with
-`exco-organizer-smtp-email-address'."
-  `(let ((result-list '()))
-     (exco--calendar-item-dolist
-      calendar-item (exco-extract-value '(ResponseMessages
-                                         FindItemResponseMessage
-                                         RootFolder
-                                         Items)
-                                       ,response)
-      (push (funcall ,callback ,@care-abouts)
-           result-list))
-     (nreverse result-list)))
-
-(defun exco-calendar-item-iterate (response callback)
-  "Iterate through calendar items in RESPONSE, calling CALLBACK on each.
-Return a list of results from callback.  CALLBACK takes arguments:
-SUBJECT, a string, the subject of the meeting.
-START, the start date and time in Emacs internal representation.
-END, the start date and time in Emacs internal representation.
-LOCATION, the location of the meeting.
-MAIN-INVITEES, a list of strings, email addresses of the required
-participants.
-OPTIONAL-INVITEES, a list of strings, email addresses of optional
-participants."
-  (exco-calendar-item-iterate-general
-   response callback
-   subject start-internal end-internal
-   location main-invitees optional-invitees))
-
-;; Date-time utility functions.
-(defun exco-extend-timezone (date-time-string)
-  "Add a colon to the timezone in DATE-TIME-STRING.
-DATE-TIME-STRING must be formatted as if returned by
-`format-time-string' with FORMAT-STRING \"%FT%T%z\".  Web
-services require the ISO8601 extended format of timezone, which
-includes the colon."
-  (concat
-   (substring date-time-string 0 22) ":" (substring date-time-string 22)))
-
-(defun exco-format-date-time (time-internal)
-  "Convert TIME-INTERNAL to an XSD compatible date-time string."
-  (exco-extend-timezone
-   (format-time-string "%FT%T%z" time-internal)))
-
-;; Use month day year order to be compatible with
-;; calendar-cursor-to-date.  I wish I could instead use the ISO 8601
-;; ordering, year month day.
-(defun exco-get-meetings-for-day (identifier month day year callback)
-  "Return the meetings for the specified day.
-IDENTIFIER is the connection identifier.  MONTH, DAY and YEAR are
-the meeting month, day and year.  Call CALLBACK with two
-arguments, IDENTIFIER and the server's response."
-  (let* ((start-of-day-time-internal
-         (apply #'encode-time `(0 0 0 ,day ,month ,year)))
-        (start-of-day-date-time
-         (exco-format-date-time start-of-day-time-internal))
-        (start-of-next-day-date-time
-         (exco-extend-timezone
-          (format-time-string "%FT00:00:00%z"
-                              (time-add start-of-day-time-internal
-                                        (seconds-to-time 86400))))))
-    (exco-operate
-     identifier
-     "FindItem"
-     `(;; Main arguments.
-       (;; RequestVersion is usually overridden by a fixed value in
-       ;; the WSDL (the RequestServerVersion element); provide the
-       ;; maximally-compatible Exchange2007 if the fixed value isn't
-       ;; present.
-       (RequestVersion (Version . "Exchange2007"))
-       (Traversal . "Shallow")
-       (ItemShape
-        (BaseShape . "AllProperties"))
-       ;; To aid productivity, excorporate-calfw automatically prunes your
-       ;; meetings to a maximum of 100 per day.
-       (CalendarView (MaxEntriesReturned . "100")
-                     (StartDate . ,start-of-day-date-time)
-                     (EndDate . ,start-of-next-day-date-time))
-       (ParentFolderIds
-        (DistinguishedFolderId (Id . "calendar"))))
-       ;; Empty arguments.
-       ,@(cdr (exco-operation-arity-nils identifier "FindItem")))
-     callback)))
-
-(defun exco-connection-iterate (initialize-function
-                               per-connection-function
-                               per-connection-callback
-                               finalize-function
-                               &optional callback-will-call-finalize)
-  "Iterate Excorporate connections.
-Call INITIALIZE-FUNCTION once before iterating.  It takes no
-arguments.
-
-Call PER-CONNECTION-FUNCTION once for each server connection.  It
-is run synchronously.  It accepts two arguments, IDENTIFIER, the
-current server connection, and CALLBACK, which is a wrapped
-version of PER-CONNECTION-CALLBACK.
-
-PER-CONNECTION-CALLBACK takes a variable number of arguments,
-depending on which callback it is.  If
-CALLBACK-WILL-CALL-FINALIZE is non-nil, it takes a final
-FINALIZE-FUNCTION argument, which is a countdown-wrapped
-finalizer function that PER-CONNECTION-CALLBACK should call (or
-arrange to be called asynchronously) each time it is invoked.
-
-If CALLBACK-WILL-CALL-FINALIZE is non-nil, this function will not
-call FINALIZE-FUNCTION itself.  Instead it will wrap
-FINALIZE-FUNCTION into a function that can be called once per
-connection, then pass the wrapped finalizer to the callback as an
-argument.  CALLBACK-WILL-CALL-FINALIZE must be set if the
-callback needs to make a recursive asynchronous call."
-  (exco--ensure-connection)
-  (funcall initialize-function)
-  (let* ((countdown (length exco--connection-identifiers))
-        (wrapped-finalizer
-         (lambda (&rest arguments)
-           (setq countdown (1- countdown))
-           (when (equal countdown 0)
-             (apply finalize-function arguments))))
-        (wrapped-callback
-         (lambda (&rest arguments)
-           (apply per-connection-callback
-                  (append arguments
-                          (when callback-will-call-finalize
-                            (list wrapped-finalizer))))
-           (unless callback-will-call-finalize
-             (funcall wrapped-finalizer)))))
-    (dolist (identifier exco--connection-identifiers)
-      (funcall per-connection-function identifier
-              wrapped-callback))))
-
-;; User-visible functions and variables.
-(defgroup excorporate nil
-  "Exchange support."
-  :version "25.1"
-  :group 'comm
-  :group 'calendar)
-
-;; Name the excorporate-configuration variable vaguely.  It is currently a
-;; MAIL-ADDRESS string, a pair (MAIL-ADDRESS . SERVICE-URL), or nil.  In the
-;; future it could allow a list of strings and pairs.
-(defcustom excorporate-configuration nil
-  "Excorporate configuration.
-
-This is the account information that Excorporate uses to connect
-to one or more Exchange servers.  No secrets are stored here.  To
-manage passwords, Excorporate will either use `auth-source' or
-prompt for them in the minibuffer.
-
-This customization variable can hold a string representing an
-Exchange email address, or a pair of strings representing an
-Exchange email address and an Exchange Web Services (EWS) URL, or
-a list of such strings and pairs of strings.
-
-Specifying just an email address implies that Excorporate should
-attempt to autodiscover the service URL for the account.
-
-Examples:
-
-\"hacker@gnu.org\"
-=> Excorporate will attempt to autodiscover the EWS URL
-
-\(\"hacker@gnu.org\" . \"https://mail.gnu.org/EWS/Exchange.asmx\";)
-=> Excorporate will use the provided EWS URL
-
-Other Excorporate documentation refers to the email address as
-the \"mail address\", and the EWS URL as the \"service URL\"."
-  :type
-  '(choice
-    (const
-     :tag "Prompt for Exchange account information" nil)
-    #1=(string
-       :tag "Exchange email address (autodiscover settings)")
-    #2=(cons
-       :tag "Exchange email address and EWS URL (no autodiscovery)"
-       (string :tag "Exchange mail address (e.g., hacker@gnu.org)")
-       (string :tag "EWS URL (e.g., https://mail.gnu.org/EWS/Exchange.asmx)"))
-    (repeat :tag "List of configurations"
-           (choice #1# #2#))))
-
-(defun exco--string-or-string-pair-p (value)
-  "Return t if VALUE is a string or a pair of strings."
-  (or (stringp value)
-      ;; A single dotted pair with neither element nil.
-      (and (consp value)
-          (not (consp (cdr value)))
-          (not (null (car value)))
-          (not (null (cdr value))))))
-
-;;;###autoload
-(defun excorporate (&optional argument)
-  "Start Excorporate.
-If `excorporate-configuration' is non-nil, use it without
-prompting, otherwise prompt for Exchange account information, starting
-with an email address.
-
-Prefixed with one \\[universal-argument], always prompt for
-Exchange account information for a new web service connection.
-ARGUMENT is the prefix argument."
-  (interactive "P")
-  (cond
-   ((or (equal argument '(4))
-       (eq excorporate-configuration nil))
-    ;; Prompt.
-    (let* ((url "https://mail.gnu.org/EWS/Exchange.asmx";)
-          (suggestion user-mail-address)
-          (ask-1 "Exchange mail address: ")
-          (ask-2 "Attempt settings autodiscovery ('n' for Office 365)?")
-          (ask-3 "EWS URL: ")
-          (mail (completing-read ask-1 (list suggestion) nil nil suggestion))
-          (identifier
-           (if (y-or-n-p ask-2)
-               mail
-             (cons mail(completing-read ask-3 (list url) nil nil url)))))
-      (exco-connect identifier)))
-   ((exco--string-or-string-pair-p excorporate-configuration)
-    ;; A single string or a single pair.
-    (exco-connect excorporate-configuration))
-   ((consp (cdr excorporate-configuration))
-    ;; A proper list.
-    (dolist (configuration excorporate-configuration)
-      (if (exco--string-or-string-pair-p configuration)
-         (exco-connect configuration)
-       (warn "Skipping invalid configuration: %s" configuration))))
-   (t
-    (error "Excorporate: Invalid configuration"))))
-
-(provide 'excorporate)
-
-;;; excorporate.el ends here
diff --git a/packages/excorporate/excorporate.info 
b/packages/excorporate/excorporate.info
deleted file mode 100644
index 9214a8d..0000000
--- a/packages/excorporate/excorporate.info
+++ /dev/null
@@ -1,746 +0,0 @@
-This is excorporate.info, produced by makeinfo version 6.7 from
-excorporate.texi.
-
-Copyright (C) 2016 Free Software Foundation, Inc.
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU Free Documentation License,
-     Version 1.2 or any later version published by the Free Software
-     Foundation; with no Invariant Sections, with the Front-Cover, or
-     Back-Cover Texts.  A copy of the license is included in the section
-     entitled "GNU Free Documentation License" in the Emacs manual.
-
-     This document is part of a collection distributed under the GNU
-     Free Documentation License.  If you want to distribute this
-     document separately from the collection, you can do so by adding a
-     copy of the license to the document, as described in section 6 of
-     the license.
-
-     All Emacs Lisp code contained in this document may be used,
-     distributed, and modified without restriction.
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Excorporate: (excorporate).  Exchange Web Services integration for Emacs.
-END-INFO-DIR-ENTRY
-
-
-File: excorporate.info,  Node: Top,  Next: Reporting Bugs,  Up: (dir)
-
-Excorporate Manual
-******************
-
-Excorporate provides Exchange Web Services (EWS) support for Emacs.
-
-   If the Exchange server you access is configured to provide EWS
-support, then there's an 86% chance that Excorporate will enable you to
-retrieve your calendar entries from the comfort of Emacs.
-
-   The 14% failure rate is because authenticating against an Exchange
-server can be challenging.
-
-   Accessing an Exchange server through an HTTPS proxy is possible now
-that <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=10> and
-<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35969> are fixed.
-
-   Kerberos/GSSAPI authentication needs more experimentation.
-
-   Reports of success or failure of different connection types are
-welcome, as are patches to enable more of these access scenarios.  See
-*note Reporting Bugs::.
-
-* Menu:
-
-* Reporting Bugs::              How to report bugs in Excorporate
-* Installation::                Getting and installing 'excorporate'.
-* Configuration::               Configuring 'excorporate'.
-* Usage::                       Using 'excorporate'.
-* Troubleshooting::             Debugging why a connection failed
-* API Usage::                   Using the API provided by 'excorporate'.
-
-
-File: excorporate.info,  Node: Reporting Bugs,  Next: Installation,  Prev: 
Top,  Up: Top
-
-1 Reporting Bugs
-****************
-
-To report a bug, send an email to 'bug-gnu-emacs@gnu.org' using your
-favourite email program.  Put "Excorporate" somewhere in the subject
-line, for example: "Excorporate: Failed to authenticate".
-
-
-File: excorporate.info,  Node: Installation,  Next: Configuration,  Prev: 
Reporting Bugs,  Up: Top
-
-2 Installation
-**************
-
-Excorporate works on Emacs versions >= 24.1.
-
-Install 'excorporate' from the GNU ELPA repository:
-
-   'M-x package-install RET excorporate'
-
-
-File: excorporate.info,  Node: Configuration,  Next: Usage,  Prev: 
Installation,  Up: Top
-
-3 Configuration
-***************
-
-Ideally you won't need to configure Excorporate beyond providing your
-account email address.  On friendly Exchange setups, Excorporate can
-discover the EWS URL automatically.
-
-Run:
-
-   'M-x excorporate'
-
-which will prompt you for the Exchange account configuration.  Follow
-the prompts and if all goes well, you'll see a message in the minibuffer
-or in *Messages* saying that the connection is ready.  Using the
-prompts, you can first try with autodiscovery.  If autodiscovery runs
-out of URLs to try, re-run 'excorporate', saying 'n' to the
-autodiscovery attempt, at which point you will be asked for the EWS URL.
-
-To save a working configuration, customize 'excorporate-configuration':
-
-   'M-x customize-variable RET excorporate-configuration'
-
-After saving the configuration, try 'M-x excorporate' again.
-
-If neither autodiscovery nor specifying the EWS URL work, *note
-Troubleshooting::.
-
-
-File: excorporate.info,  Node: Usage,  Next: Troubleshooting,  Prev: 
Configuration,  Up: Top
-
-4 Usage
-*******
-
-Excorporate can put entries it retrieves into the Emacs Diary, and use
-'appt' to remind you a few minutes before a meeting starts.  To enable
-this support, do:
-
-   'M-x excorporate-diary-enable'
-
-   Excorporate's diary front-end will retrieve today's meetings.
-Subsequently 'appt' will pop up a reminder window several minutes prior
-to each meeting.
-
-   If you leave Emacs running overnight, at 12:01 AM 'appt' (via
-Excorporate) will retrieve your meetings and display your diary so that
-you see the day's events first thing in the morning.
-
-Open the calendar with:
-
-   'M-x calendar'
-
-move the cursor to the date you want to see meetings for, and press 'd'.
-Some time later, asynchronously, a window will pop up containing events
-retrieved from the Exchange server in addition to locally-entered diary
-events.  The events are all sorted by time.
-
-   Excorporate also binds 'e' in '*Calendar*' buffers to
-'excorporate-calendar-show-day-function' to allow a different view of
-retrieved events.  By default, 'excorporate-calendar-show-day-function'
-is set to 'exco-org-show-day' which displays meetings in a temporary
-read-only Org Mode buffer named '*Excorporate*'.
-
-   In the Org Mode '*Excorporate*' buffer, you can run 'M-x
-exco-org-decline-meeting-request' to decline a meeting request.  To
-accept, use ('exco-org-accept-meeting-request') or, to tentatively
-accept, invoke ('exco-org-tentatively-accept-meeting-request').  Pass a
-prefix argument to these functions to omit a reply message.
-
-   A meeting is a calendar event to which at least one other person is
-invited.  To cancel a meeting (or an occurence of a recurring meeting)
-that you organized, use 'M-x exco-org-cancel-meeting'.
-
-   An appointment is a calendar item that has no invitees.  To delete an
-appointment that you created, type 'M-x exco-org-delete-appointment'.
-With a prefix argument, 'M-x exco-org-delete-appointment' can be used to
-force-delete calendar items, whether they be meetings or appointments.
-One example where this is necessary is when "cancelling" a meeting with
-a single invitee, you, the organizer.  The server will reject an attempt
-to cancel such a meeting because it refuses to send the organizer a
-cancellation message.
-
-   If you prefer, you can install the 'calfw' package, and set
-'excorporate-calendar-show-day-function' to 'exco-calfw-show-day'.
-
-
-File: excorporate.info,  Node: Troubleshooting,  Next: API Usage,  Prev: 
Usage,  Up: Top
-
-5 Troubleshooting
-*****************
-
-First, you'll want to double-check that the Exchange server you're
-trying to access provides EWS support.  If it doesn't, Excorporate can't
-do anything for you.  Before asking your Exchange administrator, check
-intranet wikis and so forth; other users of non-standard clients may
-have already found the EWS URL. This is called the "EWS endpoint".  It
-can be as simple as, e.g.:
-
-   'https://mail.gnu.org/EWS/Exchange.asmx'
-
-First you need to make sure you can access the endpoint.
-
-For Exchange Web Services (EWS) which Excorporate uses, you'll have to
-determine the EWS endpoint for your Exchange account, call it 'ews-url'.
-It is usually something like:
-
-   https://<mail host name>/EWS/Exchange.asmx
-
-Excorporate calculates the WSDL URL, call it 'wsdl-url', by replacing
-the endpoint's last path element with "Services.wsdl":
-
-   https://<mail host name>/EWS/Services.wsdl
-
-Before even attempting Excorporate, you have to make these succeed:
-
-     (with-current-buffer
-      (url-retrieve-synchronously ews-url)
-      (buffer-string))
-
-When this works, you'll see web page text in *Messages*, containing a
-message about having created a service.
-
-     (with-current-buffer
-      (url-retrieve-synchronously wsdl-url)
-      (buffer-string))
-
-When this works, it will show a bunch of WSDL (XML) in *Messages*.
-
-Debug the above URL retrievals with 'M-:' in an 'emacs -Q' run:
-
-     (progn
-       (setq url-debug 1)
-       (url-retrieve-synchronously URL-STRING)
-       (dolist (p (seq-filter
-                   (lambda (b) (string-match " *http*" (buffer-name b)))
-                   (buffer-list)))
-         (message "HTTP result buffer: \"%s\"\n%s"
-                  (buffer-name p)
-                  (with-current-buffer p (buffer-string))))
-       "check *Messages*")
-
-Beware that HTTP responses can be out-of-order, and that if you set
-'url-debug' to a number or 't', Emacs may hang for a while if it
-attempts to print a very large data structure.
-
-Once you're sure the above steps are working, try 'M-x excorporate'.
-
-The buffer '*fsm-debug*' shows 'excorporate' state transitions and
-should provide details of where things went wrong.
-
-Also check '*Messages*' for anything obvious.
-
-If you suspect something wrong with accessing the EWS URL, try setting
-'url-debug' to t and retry 'M-x excorporate', then check the
-'*URL-DEBUG*' buffer for output.
-
-If you suspect NTLM authentication is failing, as a long shot, you might
-try setting 'ntlm-compatibility-level' to 0 and retrying 'M-x
-excorporate'.
-
-Excorporate's dependencies implement the tricky elements of asynchronous
-Exchange access: a state machine ('fsm'), TLS negotiation ('gnutls'),
-NTLM authentication ('ntlm' and 'url-http-ntlm') and SOAP communication
-('soap-client').
-
-
-File: excorporate.info,  Node: API Usage,  Prev: Troubleshooting,  Up: Top
-
-6 API Usage
-***********
-
-Here are some examples of using the API (application programming
-interface) provided by Excorporate.
-
-Not all of Excorporate's functionality is exposed as interactive
-functions.  Here is an example of creating a meeting to which
-hacker2@gnu.org is invited, using a non-interactive function provided by
-Excorporate:
-
-     (exco-calendar-item-meeting-create
-      (car exco--connection-identifiers)
-      "Test meeting 1"
-      "Hi,\n\nThis is a test meeting 1.\n\nRegards.\n"
-      (encode-time 0 15 14 23 09 2020)
-      (encode-time 0 0  15 23 09 2020)
-      "Online only"
-      '("hacker2@gnu.org")
-      nil
-      (lambda (identifier response)
-        (message "%S: %S" identifier response)))
-     =>
-     ;; Printed in *Messages*:
-     ("hacker1@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-     (((ResponseMessages
-        (CreateItemResponseMessage
-         (ResponseClass . "Success")
-         (ResponseCode . "NoError")
-         (Items
-          (CalendarItem
-           (ItemId
-            (Id . "A[...]A==")
-            (ChangeKey . "D[...]M"))))))))
-
-The callback is run asychronously after the server responds, so as not
-to block Emacs, and the result is what is printed in the '*Messages*'
-buffer.  This example assumes the user has already run 'M-x excorporate'
-to create a connection.  '(car exco--connection-identifiers)' is a hack
-that uses the first-established connection.  Excorporate fully supports
-connecting to multiple different servers though (see
-'exco-connection-iterate') so published code that uses the Excorporate
-API should not assume just one connection.
-
-There is lots of server-side functionality that Excorporate does not
-provide high-level non-interactive functions for.  Using that
-functionality is still possible with the low-level 'exco-operate' and
-'exco-operate-synchronously' functions.
-
-For example, evaluating this form produces lots of details about the
-meeting represented by the ItemId form, including tidbits like the list
-of invitees and how they've responded (accepted, declined, tentatively
-accepted, unknown).  You can find ItemId forms to experiment with in the
-PROPERTIES drawer of calendar entries in the interactive Org buffer.
-
-     (exco-operate-synchronously
-      (car exco--connection-identifiers)
-      "GetItem"
-      '(((ItemShape
-          (BaseShape . "AllProperties"))
-         (ItemIds
-          (ItemId
-           (Id . "A[...]A==")
-           (ChangeKey . "D[...]d"))))
-        nil nil nil nil nil nil))
-     =>
-     (((ResponseMessages
-        (GetItemResponseMessage
-         (ResponseClass . "Success")
-         (ResponseCode . "NoError")
-         (Items
-          (CalendarItem
-           (ItemId (Id . "A[...]A==") (ChangeKey . "D[...]M"))
-           (ParentFolderId (Id . "A[...]A") (ChangeKey . "A[...]A=="))
-           (ItemClass . "IPM.Appointment")
-           (Subject . "Excorporate discussion")
-           (Sensitivity . "Normal")
-           (Body (BodyType . "Text") . "Hi Hacker Two,
-
-     Let's discuss Excorporate.
-
-     Hacker One")
-           (DateTimeReceived . "2020-09-24T20:07:26Z")
-           (Size . 13709)
-           (Importance . "Normal")
-           (IsSubmitted)
-           (IsDraft)
-           (IsFromMe)
-           (IsResend)
-           (IsUnmodified)
-           (DateTimeSent . "2020-09-24T20:07:26Z")
-           (DateTimeCreated . "2020-09-24T20:07:26Z")
-           (ResponseObjects
-            (ForwardItem)
-            (CancelCalendarItem))
-           (ReminderDueBy . "2020-09-25T14:30:00Z")
-           (ReminderIsSet . t)
-           (ReminderMinutesBeforeStart . 15)
-           (DisplayCc)
-           (DisplayTo . "Hacker Two")
-           (HasAttachments)
-           (Culture . "en-US")
-           (Start . "2020-09-25T14:30:00Z")
-           (End . "2020-09-25T15:30:00Z")
-           (IsAllDayEvent)
-           (LegacyFreeBusyStatus . "Busy")
-           (Location . "Online")
-           (IsMeeting . t)
-           (IsCancelled)
-           (IsRecurring)
-           (MeetingRequestWasSent . t)
-           (IsResponseRequested . t)
-           (CalendarItemType . "Single")
-           (MyResponseType . "Organizer")
-           (Organizer
-            (Mailbox
-             (Name . "Hacker One")
-             (EmailAddress . "hacker1@gnu.org")
-             (RoutingType . "SMTP")))
-           (RequiredAttendees
-            (Attendee
-             (Mailbox
-              (Name . "Hacker Two")
-              (EmailAddress . "hacker2@gnu.org")
-              (RoutingType . "SMTP")
-              (MailboxType . "Mailbox"))
-             (ResponseType . "Accept")
-             (LastResponseTime . "2020-09-24T21:08:54Z")))
-           (Duration . "PT1H")
-           (TimeZone . "(UTC+00:00) Monrovia, Reykjavik")
-           (AppointmentSequenceNumber . 0)
-           (AppointmentState . 1)
-           (IsOnlineMeeting)))))))
-
-Note that this function queries the server synchronously.  In other
-words, it waits for, and evaluates to, the server's reply.  This is nice
-when experimenting with the API, but published code should mostly use
-the asynchronous calls to avoid blocking Emacs during server operations.
-
-Here is a more complicated example that asynchronously queries the
-server for availability overlap for hacker1@gnu.org and hacker2@gnu.org,
-in the Eastern Time time zone.
-
-     (exco-operate
-      (car exco--connection-identifiers)
-      "GetUserAvailability"
-      '(((TimeZone
-          (Bias . 300)
-          (StandardTime
-           (Bias . 0)
-           (Time . "02:00:00")
-           (DayOrder . 1)
-           (Month . 11)
-           (DayOfWeek . "Sunday"))
-          (DaylightTime
-           (Bias . -60)
-           (Time . "02:00:00")
-           (DayOrder . 2)
-           (Month . 3)
-           (DayOfWeek . "Sunday")))
-         (MailboxDataArray
-          (MailboxData
-           (Email
-            (Address . "hacker1@gnu.org"))
-           (AttendeeType . "Required")
-           (ExcludeConflicts . nil))
-          (MailboxData
-           (Email
-            (Address . "hacker2@gnu.org"))
-           (AttendeeType . "Required")
-           (ExcludeConflicts . nil)))
-         (FreeBusyViewOptions
-          (TimeWindow
-           (StartTime . "2020-09-25T00:00:00Z")
-           (EndTime . "2020-09-25T23:59:00Z"))
-          (MergedFreeBusyIntervalInMinutes . 60)
-          (RequestedView "DetailedMerged")))
-        nil nil nil)
-      (lambda (identifier response)
-        (message "%S: %S" identifier response)))
-     =>
-     ;; Printed in *Messages*:
-     ("hacker1@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-     (((FreeBusyResponseArray
-        (FreeBusyResponse
-         (ResponseMessage
-          (ResponseClass . "Success")
-          (ResponseCode . "NoError"))
-         (FreeBusyView
-          (FreeBusyViewType "FreeBusyMerged")
-          (MergedFreeBusy . "000000000000000000000200")
-          (CalendarEventArray
-           (CalendarEvent
-            (StartTime . "2020-09-25T12:00:00")
-            (EndTime . "2020-09-25T12:30:00")
-            (BusyType . "Busy")))
-          (WorkingHours
-           (TimeZone
-            (Bias . 480)
-            (StandardTime
-             (Bias . 0)
-             (Time . "02:00:00")
-             (DayOrder . 1)
-             (Month . 11)
-             (DayOfWeek . "Sunday"))
-            (DaylightTime
-             (Bias . -60)
-             (Time . "02:00:00")
-             (DayOrder . 2)
-             (Month . 3)
-             (DayOfWeek . "Sunday")))
-           (WorkingPeriodArray
-            (WorkingPeriod
-             (DayOfWeek "Monday" "Tuesday" "Wednesday" "Thursday" "Friday")
-             (StartTimeInMinutes . 540)
-             (EndTimeInMinutes . 1080))))))
-        (FreeBusyResponse
-         (ResponseMessage
-          (ResponseClass . "Success")
-          (ResponseCode . "NoError"))
-         (FreeBusyView
-          (FreeBusyViewType "DetailedMerged")
-          (MergedFreeBusy . "000000000000002200000200")
-          (CalendarEventArray
-           (CalendarEvent
-            (StartTime . "2020-09-25T05:30:00")
-            (EndTime . "2020-09-25T06:30:00")
-            (BusyType . "Busy")
-            (CalendarEventDetails
-             (ID . "0[...]0")
-             (Subject . "Excorporate discussion")
-             (Location . "Online")
-             (IsMeeting . t)
-             (IsRecurring)
-             (IsException)
-             (IsReminderSet . t)
-             (IsPrivate)))
-           (CalendarEvent
-            (StartTime . "2020-09-25T12:00:00")
-            (EndTime . "2020-09-25T12:30:00")
-            (BusyType . "Busy")
-            (CalendarEventDetails
-             (ID . "0[...]0")
-             (Subject . "An occurence of a recurring meeting")
-             (Location)
-             (IsMeeting . t)
-             (IsRecurring . t)
-             (IsException)
-             (IsReminderSet . t)
-             (IsPrivate))))
-          (WorkingHours
-           (TimeZone
-            (Bias . 480)
-            (StandardTime
-             (Bias . 0)
-             (Time . "02:00:00")
-             (DayOrder . 1)
-             (Month . 11)
-             (DayOfWeek . "Sunday"))
-            (DaylightTime
-             (Bias . -60)
-             (Time . "02:00:00")
-             (DayOrder . 2)
-             (Month . 3)
-             (DayOfWeek . "Sunday")))
-           (WorkingPeriodArray
-            (WorkingPeriod
-             (DayOfWeek "Monday" "Tuesday" "Wednesday" "Thursday" "Friday")
-             (StartTimeInMinutes . 480)
-             (EndTimeInMinutes . 1020)))))))))
-
-This example shows how to create a recurrence in the "Eastern Standard
-Time" time zone.  The 'exco-operation-arity-nils' call returns a list of
-nils with a length matching the number of arguments that the
-'CreateItem' operation takes.  Arguments other than the first
-("request") argument may be needed in the future to use more complicated
-server functionality, but for now they can all be left 'nil'.
-
-     (exco-operate
-      (car exco--connection-identifiers)
-      "CreateItem"
-      `(((SendMeetingInvitations . "SendToAllAndSaveCopy")
-         (Items
-          (CalendarItem
-           (Subject . "Test recurrence 1")
-           (Body (BodyType . "Text") "Testing recurrence creation.")
-           (Start . "2020-09-25T17:00:00-04:00")
-           (End . "2020-09-25T18:00:00-04:00")
-           (StartTimeZone (Id . "Eastern Standard Time"))
-           (EndTimeZone (Id . "Eastern Standard Time"))
-           (Location . "Online")
-           (RequiredAttendees
-            (Attendee (Mailbox (EmailAddress . "hacker1@gnu.org"))))
-           (Recurrence
-            (WeeklyRecurrence
-             (Interval . 1)
-             (DaysOfWeek "Friday"))
-            (NumberedRecurrence
-             (StartDate . "2020-09-25-04:00")
-             (NumberOfOccurrences . 4))))))
-        ;; Empty arguments.
-        ,@(cdr (exco-operation-arity-nils identifier "CreateItem")))
-      (lambda (identifier response)
-        (message "%S: %S" identifier response)))
-     =>
-     ;; Printed in *Messages*:
-     ("hacker1@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-     (((ResponseMessages
-        (CreateItemResponseMessage
-         (ResponseClass . "Success")
-         (ResponseCode . "NoError")
-         (Items
-          (CalendarItem
-           (ItemId
-            (Id . "A[...]A==")
-            (ChangeKey . "D[...]k"))))))))
-
-Now we can retrieve the item's properties to see the recurrence and time
-zone details:
-
-     (exco-operate
-      (car exco--connection-identifiers)
-      "GetItem"
-      '(((ItemShape
-          (BaseShape . "AllProperties"))
-         (ItemIds
-          (ItemId
-           (Id . "A[...]A==")
-           (ChangeKey . "D[...]d"))))
-        nil nil nil nil nil nil)
-      (lambda (identifier response)
-        (message "%S: %S" identifier response)))
-     =>
-     ;; Printed in *Messages*:
-     ("hacker1@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-     (((ResponseMessages
-        (GetItemResponseMessage
-         (ResponseClass . "Success")
-         (ResponseCode . "NoError")
-         (Items
-          (CalendarItem
-           (ItemId
-            (Id . "A[...]A==")
-            (ChangeKey . "D[...]h"))
-           (ParentFolderId
-            (Id . "A[...]A")
-            (ChangeKey . "A[...]A=="))
-           (ItemClass . "IPM.Appointment")
-           (Subject . "Test recurrence 1")
-           (Sensitivity . "Normal")
-           (Body
-            (BodyType . "Text") . "Testing recurrence creation.")
-           (DateTimeReceived . "2020-09-26T00:23:59Z")
-           (Size . 13636)
-           (Importance . "Normal")
-           (IsSubmitted)
-           (IsDraft)
-           (IsFromMe)
-           (IsResend)
-           (IsUnmodified)
-           (DateTimeSent . "2020-09-26T00:23:59Z")
-           (DateTimeCreated . "2020-09-26T00:23:59Z")
-           (ResponseObjects
-            (ForwardItem)
-            (CancelCalendarItem))
-           (ReminderDueBy . "2020-10-02T21:00:00Z")
-           (ReminderIsSet . t)
-           (ReminderMinutesBeforeStart . 15)
-           (DisplayCc)
-           (DisplayTo . "Hacker One")
-           (HasAttachments)
-           (Culture . "en-US")
-           (Start . "2020-09-25T21:00:00Z")
-           (End . "2020-09-25T22:00:00Z")
-           (IsAllDayEvent)
-           (LegacyFreeBusyStatus . "Busy")
-           (Location . "Online")
-           (IsMeeting . t)
-           (IsCancelled)
-           (IsRecurring)
-           (MeetingRequestWasSent)
-           (IsResponseRequested . t)
-           (CalendarItemType . "RecurringMaster")
-           (MyResponseType . "Organizer")
-           (Organizer
-            (Mailbox
-             (Name . "Hacker One")
-             (EmailAddress . "hacker1@gnu.org")
-             (RoutingType . "SMTP")))
-           (RequiredAttendees
-            (Attendee
-             (Mailbox
-              (Name . "Hacker One")
-              (EmailAddress . "hacker1@gnu.org")
-              (RoutingType . "SMTP")
-              (MailboxType . "Mailbox"))
-             (ResponseType . "Unknown")))
-           (Duration . "PT1H")
-           (TimeZone . "
-     (UTC-05:00) Eastern Time
-     (US & Canada)")
-           (AppointmentSequenceNumber . 0)
-           (AppointmentState . 1)
-           (Recurrence
-            (WeeklyRecurrence
-             (Interval . 1)
-             (DaysOfWeek "Friday"))
-            (NumberedRecurrence
-             (StartDate . "2020-09-25-04:00")
-             (NumberOfOccurrences . 4)))
-           (FirstOccurrence
-            (ItemId
-             (Id . "A[...]A==")
-             (ChangeKey . "D[...]h"))
-            (Start . "2020-09-25T21:00:00Z")
-            (End . "2020-09-25T22:00:00Z")
-            (OriginalStart . "2020-09-25T21:00:00Z"))
-           (LastOccurrence
-            (ItemId
-             (Id . "A[...]A==")
-             (ChangeKey . "D[...]h"))
-            (Start . "2020-10-16T21:00:00Z")
-            (End . "2020-10-16T22:00:00Z")
-            (OriginalStart . "2020-10-16T21:00:00Z"))
-           (MeetingTimeZone
-            (TimeZoneName . "Eastern Standard Time")
-            (BaseOffset . 0)
-            (Daylight
-             (TimeZoneName . "Daylight")
-             (Offset . 0)
-             (RelativeYearlyRecurrence
-              (DaysOfWeek . "Sunday")
-              (DayOfWeekIndex . "Second")
-              (Month . "March"))
-             (Time . "02:00:00"))
-            (Standard
-             (TimeZoneName . "Standard")
-             (Offset . 0)
-             (RelativeYearlyRecurrence
-              (DaysOfWeek . "Sunday")
-              (DayOfWeekIndex . "First")
-              (Month . "November"))
-             (Time . "02:00:00")))
-           (IsOnlineMeeting)))))))
-
-Finally, this is how to delete all the occurrences in the series.
-ItemId here is the top-level recurrence item identifier which is
-returned as '(CalendarItem (ItemId ...) ...)' by the above 'GetItem'
-operation, whose 'CalendarType' element is "RecurringMaster".
-
-     (exco-operate
-      (car exco--connection-identifiers)
-      "DeleteItem"
-      '(((DeleteType . "MoveToDeletedItems")
-         (SendMeetingCancellations . "SendToNone")
-         (ItemIds
-          (ItemId
-           (Id . "A[...]A==")
-           (ChangeKey . "D[...]h"))))
-        nil nil nil)
-      (lambda (identifier response)
-        (message "%S: %S" identifier response)))
-     =>
-     ;; Printed in *Messages*:
-     ("hacker1@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-     (((ResponseMessages
-        (DeleteItemResponseMessage
-         (ResponseClass . "Success")
-         (ResponseCode . "NoError")))))
-
-Feel free to contribute new functions that you think others would find
-useful; file a bug with a patch against
-'https://git.savannah.gnu.org/git/emacs/elpa.git'.  Functions in
-'excorporate.el' must always keep the same interface so that they stay
-backward compatible.  If an existing function has an insufficient
-interface, make a new one.  Excorporate functions are written to work
-with older Emacs versions, back to Emacs 24.1.
-
-
-
-Tag Table:
-Node: Top1103
-Node: Reporting Bugs2399
-Node: Installation2723
-Node: Configuration2997
-Node: Usage4017
-Node: Troubleshooting6476
-Node: API Usage9344
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
diff --git a/packages/excorporate/excorporate.texi 
b/packages/excorporate/excorporate.texi
deleted file mode 100644
index c9e943e..0000000
--- a/packages/excorporate/excorporate.texi
+++ /dev/null
@@ -1,798 +0,0 @@
-\input texinfo
-@setfilename excorporate.info
-@settitle Excorporate Manual
-
-@dircategory Emacs
-@direntry
-* Excorporate: (excorporate).  Exchange Web Services integration for Emacs.
-@end direntry
-
-@copying
-Copyright @copyright{} 2016 Free Software Foundation, Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.2 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover, or Back-Cover Texts.  A copy of
-the license is included in the section entitled ``GNU Free Documentation
-License'' in the Emacs manual.
-
-This document is part of a collection distributed under the GNU Free
-Documentation License.  If you want to distribute this document
-separately from the collection, you can do so by adding a copy of the
-license to the document, as described in section 6 of the license.
-
-All Emacs Lisp code contained in this document may be used, distributed,
-and modified without restriction.
-@end quotation
-@end copying
-
-@titlepage
-@title Excorporate Manual
-@author Thomas Fitzsimmons
-@page
-@insertcopying
-@end titlepage
-
-@contents
-
-@node Top
-@top Excorporate Manual
-
-Excorporate provides Exchange Web Services (EWS) support for Emacs.
-
-If the Exchange server you access is configured to provide EWS
-support, then there's an 86% chance that Excorporate will enable you
-to retrieve your calendar entries from the comfort of Emacs.
-
-The 14% failure rate is because authenticating against an Exchange
-server can be challenging.
-
-Accessing an Exchange server through an HTTPS proxy is possible now that
-@uref{https://debbugs.gnu.org/cgi/bugreport.cgi?bug=10} and
-@uref{https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35969} are fixed.
-
-Kerberos/GSSAPI authentication needs more experimentation.
-
-Reports of success or failure of different connection types are
-welcome, as are patches to enable more of these access scenarios.  See
-@pxref{Reporting Bugs}.
-
-@menu
-* Reporting Bugs::              How to report bugs in Excorporate
-* Installation::                Getting and installing @code{excorporate}.
-* Configuration::               Configuring @code{excorporate}.
-* Usage::                       Using @code{excorporate}.
-* Troubleshooting::             Debugging why a connection failed
-* API Usage::                   Using the API provided by @code{excorporate}.
-@end menu
-
-@node Reporting Bugs
-@chapter Reporting Bugs
-
-@noindent
-To report a bug, send an email to @code{bug-gnu-emacs@@gnu.org} using
-your favourite email program.  Put ``Excorporate'' somewhere in the
-subject line, for example: ``Excorporate: Failed to authenticate''.
-
-@node Installation
-@chapter Installation
-
-Excorporate works on Emacs versions >= 24.1.
-
-@noindent
-Install @code{excorporate} from the GNU ELPA repository:
-
-@code{M-x package-install RET excorporate}
-
-@node Configuration
-@chapter Configuration
-
-@noindent
-Ideally you won't need to configure Excorporate beyond providing your
-account email address.  On friendly Exchange setups, Excorporate can
-discover the EWS URL automatically.
-
-@noindent
-Run:
-
-@code{M-x excorporate}
-
-@noindent
-which will prompt you for the Exchange account configuration.  Follow
-the prompts and if all goes well, you'll see a message in the minibuffer
-or in *Messages* saying that the connection is ready.  Using the
-prompts, you can first try with autodiscovery.  If autodiscovery runs
-out of URLs to try, re-run @code{excorporate}, saying 'n' to the
-autodiscovery attempt, at which point you will be asked for the EWS URL.
-
-@noindent
-To save a working configuration, customize
-@code{excorporate-configuration}:
-
-@code{M-x customize-variable RET excorporate-configuration}
-
-@noindent
-After saving the configuration, try @code{M-x excorporate} again.
-
-@noindent
-If neither autodiscovery nor specifying the EWS URL work,
-@pxref{Troubleshooting}.
-
-@node Usage
-@chapter Usage
-
-@noindent
-Excorporate can put entries it retrieves into the Emacs Diary, and use
-@code{appt} to remind you a few minutes before a meeting starts.  To
-enable this support, do:
-
-@code{M-x excorporate-diary-enable}
-
-Excorporate's diary front-end will retrieve today's meetings.
-Subsequently @code{appt} will pop up a reminder window several minutes
-prior to each meeting.
-
-If you leave Emacs running overnight, at 12:01 AM @code{appt} (via
-Excorporate) will retrieve your meetings and display your diary so
-that you see the day's events first thing in the morning.
-
-@noindent
-Open the calendar with:
-
-@code{M-x calendar}
-
-@noindent
-move the cursor to the date you want to see meetings for, and press
-`d'.  Some time later, asynchronously, a window will pop up containing
-events retrieved from the Exchange server in addition to
-locally-entered diary events.  The events are all sorted by time.
-
-Excorporate also binds `e' in @code{*Calendar*} buffers to
-@code{excorporate-calendar-show-day-function} to allow a different
-view of retrieved events.  By default,
-@code{excorporate-calendar-show-day-function} is set to
-@code{exco-org-show-day} which displays meetings in a temporary
-read-only Org Mode buffer named @code{*Excorporate*}.
-
-In the Org Mode @code{*Excorporate*} buffer, you can run @kbd{M-x
-exco-org-decline-meeting-request} to decline a meeting request.  To
-accept, use (@code{exco-org-accept-meeting-request}) or, to tentatively
-accept, invoke (@code{exco-org-tentatively-accept-meeting-request}).
-Pass a prefix argument to these functions to omit a reply message.
-
-A meeting is a calendar event to which at least one other person is
-invited.  To cancel a meeting (or an occurence of a recurring meeting)
-that you organized, use @kbd{M-x exco-org-cancel-meeting}.
-
-An appointment is a calendar item that has no invitees.  To delete an
-appointment that you created, type @kbd{M-x
-exco-org-delete-appointment}.  With a prefix argument, @kbd{M-x
-exco-org-delete-appointment} can be used to force-delete calendar items,
-whether they be meetings or appointments.  One example where this is
-necessary is when ``cancelling'' a meeting with a single invitee, you,
-the organizer.  The server will reject an attempt to cancel such a
-meeting because it refuses to send the organizer a cancellation message.
-
-If you prefer, you can install the @code{calfw} package, and set
-@code{excorporate-calendar-show-day-function} to
-@code{exco-calfw-show-day}.
-
-@node Troubleshooting
-@chapter Troubleshooting
-
-@noindent
-First, you'll want to double-check that the Exchange server you're
-trying to access provides EWS support.  If it doesn't, Excorporate
-can't do anything for you.  Before asking your Exchange administrator,
-check intranet wikis and so forth; other users of non-standard clients
-may have already found the EWS URL.  This is called the ``EWS
-endpoint''.  It can be as simple as, e.g.:
-
-@code{https://mail.gnu.org/EWS/Exchange.asmx}
-
-@noindent
-First you need to make sure you can access the endpoint.
-
-@noindent
-For Exchange Web Services (EWS) which Excorporate uses, you'll have to
-determine the EWS endpoint for your Exchange account, call it
-@code{ews-url}.  It is usually something like:
-
-   https://<mail host name>/EWS/Exchange.asmx
-
-@noindent
-Excorporate calculates the WSDL URL, call it @code{wsdl-url}, by
-replacing the endpoint's last path element with ``Services.wsdl'':
-
-   https://<mail host name>/EWS/Services.wsdl
-
-@noindent
-Before even attempting Excorporate, you have to make these succeed:
-
-@example
-(with-current-buffer
- (url-retrieve-synchronously ews-url)
- (buffer-string))
-@end example
-
-@noindent
-When this works, you'll see web page text in *Messages*, containing a
-message about having created a service.
-
-@example
-(with-current-buffer
- (url-retrieve-synchronously wsdl-url)
- (buffer-string))
-@end example
-
-@noindent
-When this works, it will show a bunch of WSDL (XML) in *Messages*.
-
-@noindent
-Debug the above URL retrievals with @code{M-:} in an @code{emacs -Q}
-run:
-
-@example
-(progn
-  (setq url-debug 1)
-  (url-retrieve-synchronously URL-STRING)
-  (dolist (p (seq-filter
-              (lambda (b) (string-match " *http*" (buffer-name b)))
-              (buffer-list)))
-    (message "HTTP result buffer: \"%s\"\n%s"
-             (buffer-name p)
-             (with-current-buffer p (buffer-string))))
-  "check *Messages*")
-@end example
-
-@noindent
-Beware that HTTP responses can be out-of-order, and that if you set
-@code{url-debug} to a number or @code{t}, Emacs may hang for a while if
-it attempts to print a very large data structure.
-
-@noindent
-Once you're sure the above steps are working, try @code{M-x
-excorporate}.
-
-@noindent
-The buffer @code{*fsm-debug*} shows @code{excorporate} state
-transitions and should provide details of where things went wrong.
-
-@noindent
-Also check @code{*Messages*} for anything obvious.
-
-@noindent
-If you suspect something wrong with accessing the EWS URL, try setting
-@code{url-debug} to t and retry @code{M-x excorporate}, then check the
-@code{*URL-DEBUG*} buffer for output.
-
-@noindent
-If you suspect NTLM authentication is failing, as a long shot, you
-might try setting @code{ntlm-compatibility-level} to 0 and retrying
-@code{M-x excorporate}.
-
-@noindent
-Excorporate's dependencies implement the tricky elements of
-asynchronous Exchange access: a state machine (@code{fsm}), TLS
-negotiation (@code{gnutls}), NTLM authentication (@code{ntlm} and
-@code{url-http-ntlm}) and SOAP communication (@code{soap-client}).
-
-@node API Usage
-@chapter API Usage
-
-@noindent
-Here are some examples of using the API (application programming
-interface) provided by Excorporate.
-
-@noindent
-Not all of Excorporate's functionality is exposed as interactive
-functions.  Here is an example of creating a meeting to which
-hacker2@@gnu.org is invited, using a non-interactive function provided by
-Excorporate:
-
-@example
-@group
-(exco-calendar-item-meeting-create
- (car exco--connection-identifiers)
- "Test meeting 1"
- "Hi,\n\nThis is a test meeting 1.\n\nRegards.\n"
- (encode-time 0 15 14 23 09 2020)
- (encode-time 0 0  15 23 09 2020)
- "Online only"
- '("hacker2@@gnu.org")
- nil
- (lambda (identifier response)
-   (message "%S: %S" identifier response)))
-@result{}
-;; Printed in *Messages*:
-("hacker1@@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-(((ResponseMessages
-   (CreateItemResponseMessage
-    (ResponseClass . "Success")
-    (ResponseCode . "NoError")
-    (Items
-     (CalendarItem
-      (ItemId
-       (Id . "A[...]A==")
-       (ChangeKey . "D[...]M"))))))))
-@end group
-@end example
-
-@noindent
-The callback is run asychronously after the server responds, so as not
-to block Emacs, and the result is what is printed in the
-@code{*Messages*} buffer.  This example assumes the user has already run
-@kbd{M-x excorporate} to create a connection.  @code{(car
-exco--connection-identifiers)} is a hack that uses the first-established
-connection.  Excorporate fully supports connecting to multiple different
-servers though (see @code{exco-connection-iterate}) so published code
-that uses the Excorporate API should not assume just one connection.
-
-@noindent
-There is lots of server-side functionality that Excorporate does not
-provide high-level non-interactive functions for.  Using that
-functionality is still possible with the low-level @code{exco-operate}
-and @code{exco-operate-synchronously} functions.
-
-@noindent
-For example, evaluating this form produces lots of details about the
-meeting represented by the ItemId form, including tidbits like the list
-of invitees and how they've responded (accepted, declined, tentatively
-accepted, unknown).  You can find ItemId forms to experiment with in the
-PROPERTIES drawer of calendar entries in the interactive Org buffer.
-
-@example
-@group
-(exco-operate-synchronously
- (car exco--connection-identifiers)
- "GetItem"
- '(((ItemShape
-     (BaseShape . "AllProperties"))
-    (ItemIds
-     (ItemId
-      (Id . "A[...]A==")
-      (ChangeKey . "D[...]d"))))
-   nil nil nil nil nil nil))
-@result{}
-(((ResponseMessages
-   (GetItemResponseMessage
-    (ResponseClass . "Success")
-    (ResponseCode . "NoError")
-    (Items
-     (CalendarItem
-      (ItemId (Id . "A[...]A==") (ChangeKey . "D[...]M"))
-      (ParentFolderId (Id . "A[...]A") (ChangeKey . "A[...]A=="))
-      (ItemClass . "IPM.Appointment")
-      (Subject . "Excorporate discussion")
-      (Sensitivity . "Normal")
-      (Body (BodyType . "Text") . "Hi Hacker Two,
-
-Let's discuss Excorporate.
-
-Hacker One")
-      (DateTimeReceived . "2020-09-24T20:07:26Z")
-      (Size . 13709)
-      (Importance . "Normal")
-      (IsSubmitted)
-      (IsDraft)
-      (IsFromMe)
-      (IsResend)
-      (IsUnmodified)
-      (DateTimeSent . "2020-09-24T20:07:26Z")
-      (DateTimeCreated . "2020-09-24T20:07:26Z")
-      (ResponseObjects
-       (ForwardItem)
-       (CancelCalendarItem))
-      (ReminderDueBy . "2020-09-25T14:30:00Z")
-      (ReminderIsSet . t)
-      (ReminderMinutesBeforeStart . 15)
-      (DisplayCc)
-      (DisplayTo . "Hacker Two")
-      (HasAttachments)
-      (Culture . "en-US")
-      (Start . "2020-09-25T14:30:00Z")
-      (End . "2020-09-25T15:30:00Z")
-      (IsAllDayEvent)
-      (LegacyFreeBusyStatus . "Busy")
-      (Location . "Online")
-      (IsMeeting . t)
-      (IsCancelled)
-      (IsRecurring)
-      (MeetingRequestWasSent . t)
-      (IsResponseRequested . t)
-      (CalendarItemType . "Single")
-      (MyResponseType . "Organizer")
-      (Organizer
-       (Mailbox
-        (Name . "Hacker One")
-        (EmailAddress . "hacker1@@gnu.org")
-        (RoutingType . "SMTP")))
-      (RequiredAttendees
-       (Attendee
-        (Mailbox
-         (Name . "Hacker Two")
-         (EmailAddress . "hacker2@@gnu.org")
-         (RoutingType . "SMTP")
-         (MailboxType . "Mailbox"))
-        (ResponseType . "Accept")
-        (LastResponseTime . "2020-09-24T21:08:54Z")))
-      (Duration . "PT1H")
-      (TimeZone . "(UTC+00:00) Monrovia, Reykjavik")
-      (AppointmentSequenceNumber . 0)
-      (AppointmentState . 1)
-      (IsOnlineMeeting)))))))
-@end group
-@end example
-
-@noindent
-Note that this function queries the server synchronously.  In other
-words, it waits for, and evaluates to, the server's reply.  This is nice
-when experimenting with the API, but published code should mostly use
-the asynchronous calls to avoid blocking Emacs during server operations.
-
-@noindent
-Here is a more complicated example that asynchronously queries the
-server for availability overlap for hacker1@@gnu.org and
-hacker2@@gnu.org, in the Eastern Time time zone.
-
-@example
-@group
-(exco-operate
- (car exco--connection-identifiers)
- "GetUserAvailability"
- '(((TimeZone
-     (Bias . 300)
-     (StandardTime
-      (Bias . 0)
-      (Time . "02:00:00")
-      (DayOrder . 1)
-      (Month . 11)
-      (DayOfWeek . "Sunday"))
-     (DaylightTime
-      (Bias . -60)
-      (Time . "02:00:00")
-      (DayOrder . 2)
-      (Month . 3)
-      (DayOfWeek . "Sunday")))
-    (MailboxDataArray
-     (MailboxData
-      (Email
-       (Address . "hacker1@@gnu.org"))
-      (AttendeeType . "Required")
-      (ExcludeConflicts . nil))
-     (MailboxData
-      (Email
-       (Address . "hacker2@@gnu.org"))
-      (AttendeeType . "Required")
-      (ExcludeConflicts . nil)))
-    (FreeBusyViewOptions
-     (TimeWindow
-      (StartTime . "2020-09-25T00:00:00Z")
-      (EndTime . "2020-09-25T23:59:00Z"))
-     (MergedFreeBusyIntervalInMinutes . 60)
-     (RequestedView "DetailedMerged")))
-   nil nil nil)
- (lambda (identifier response)
-   (message "%S: %S" identifier response)))
-@result{}
-;; Printed in *Messages*:
-("hacker1@@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-(((FreeBusyResponseArray
-   (FreeBusyResponse
-    (ResponseMessage
-     (ResponseClass . "Success")
-     (ResponseCode . "NoError"))
-    (FreeBusyView
-     (FreeBusyViewType "FreeBusyMerged")
-     (MergedFreeBusy . "000000000000000000000200")
-     (CalendarEventArray
-      (CalendarEvent
-       (StartTime . "2020-09-25T12:00:00")
-       (EndTime . "2020-09-25T12:30:00")
-       (BusyType . "Busy")))
-     (WorkingHours
-      (TimeZone
-       (Bias . 480)
-       (StandardTime
-        (Bias . 0)
-        (Time . "02:00:00")
-        (DayOrder . 1)
-        (Month . 11)
-        (DayOfWeek . "Sunday"))
-       (DaylightTime
-        (Bias . -60)
-        (Time . "02:00:00")
-        (DayOrder . 2)
-        (Month . 3)
-        (DayOfWeek . "Sunday")))
-      (WorkingPeriodArray
-       (WorkingPeriod
-        (DayOfWeek "Monday" "Tuesday" "Wednesday" "Thursday" "Friday")
-        (StartTimeInMinutes . 540)
-        (EndTimeInMinutes . 1080))))))
-   (FreeBusyResponse
-    (ResponseMessage
-     (ResponseClass . "Success")
-     (ResponseCode . "NoError"))
-    (FreeBusyView
-     (FreeBusyViewType "DetailedMerged")
-     (MergedFreeBusy . "000000000000002200000200")
-     (CalendarEventArray
-      (CalendarEvent
-       (StartTime . "2020-09-25T05:30:00")
-       (EndTime . "2020-09-25T06:30:00")
-       (BusyType . "Busy")
-       (CalendarEventDetails
-        (ID . "0[...]0")
-        (Subject . "Excorporate discussion")
-        (Location . "Online")
-        (IsMeeting . t)
-        (IsRecurring)
-        (IsException)
-        (IsReminderSet . t)
-        (IsPrivate)))
-      (CalendarEvent
-       (StartTime . "2020-09-25T12:00:00")
-       (EndTime . "2020-09-25T12:30:00")
-       (BusyType . "Busy")
-       (CalendarEventDetails
-        (ID . "0[...]0")
-        (Subject . "An occurence of a recurring meeting")
-        (Location)
-        (IsMeeting . t)
-        (IsRecurring . t)
-        (IsException)
-        (IsReminderSet . t)
-        (IsPrivate))))
-     (WorkingHours
-      (TimeZone
-       (Bias . 480)
-       (StandardTime
-        (Bias . 0)
-        (Time . "02:00:00")
-        (DayOrder . 1)
-        (Month . 11)
-        (DayOfWeek . "Sunday"))
-       (DaylightTime
-        (Bias . -60)
-        (Time . "02:00:00")
-        (DayOrder . 2)
-        (Month . 3)
-        (DayOfWeek . "Sunday")))
-      (WorkingPeriodArray
-       (WorkingPeriod
-        (DayOfWeek "Monday" "Tuesday" "Wednesday" "Thursday" "Friday")
-        (StartTimeInMinutes . 480)
-        (EndTimeInMinutes . 1020)))))))))
-@end group
-@end example
-
-@noindent
-This example shows how to create a recurrence in the ``Eastern Standard
-Time'' time zone.  The @code{exco-operation-arity-nils} call returns a
-list of nils with a length matching the number of arguments that the
-@code{CreateItem} operation takes.  Arguments other than the first
-(``request'') argument may be needed in the future to use more
-complicated server functionality, but for now they can all be left
-@code{nil}.
-
-@example
-@group
-(exco-operate
- (car exco--connection-identifiers)
- "CreateItem"
- `(((SendMeetingInvitations . "SendToAllAndSaveCopy")
-    (Items
-     (CalendarItem
-      (Subject . "Test recurrence 1")
-      (Body (BodyType . "Text") "Testing recurrence creation.")
-      (Start . "2020-09-25T17:00:00-04:00")
-      (End . "2020-09-25T18:00:00-04:00")
-      (StartTimeZone (Id . "Eastern Standard Time"))
-      (EndTimeZone (Id . "Eastern Standard Time"))
-      (Location . "Online")
-      (RequiredAttendees
-       (Attendee (Mailbox (EmailAddress . "hacker1@@gnu.org"))))
-      (Recurrence
-       (WeeklyRecurrence
-        (Interval . 1)
-        (DaysOfWeek "Friday"))
-       (NumberedRecurrence
-        (StartDate . "2020-09-25-04:00")
-        (NumberOfOccurrences . 4))))))
-   ;; Empty arguments.
-   ,@@(cdr (exco-operation-arity-nils identifier "CreateItem")))
- (lambda (identifier response)
-   (message "%S: %S" identifier response)))
-@result{}
-;; Printed in *Messages*:
-("hacker1@@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-(((ResponseMessages
-   (CreateItemResponseMessage
-    (ResponseClass . "Success")
-    (ResponseCode . "NoError")
-    (Items
-     (CalendarItem
-      (ItemId
-       (Id . "A[...]A==")
-       (ChangeKey . "D[...]k"))))))))
-@end group
-@end example
-
-@noindent
-Now we can retrieve the item's properties to see the recurrence and time
-zone details:
-
-@example
-@group
-(exco-operate
- (car exco--connection-identifiers)
- "GetItem"
- '(((ItemShape
-     (BaseShape . "AllProperties"))
-    (ItemIds
-     (ItemId
-      (Id . "A[...]A==")
-      (ChangeKey . "D[...]d"))))
-   nil nil nil nil nil nil)
- (lambda (identifier response)
-   (message "%S: %S" identifier response)))
-@result{}
-;; Printed in *Messages*:
-("hacker1@@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-(((ResponseMessages
-   (GetItemResponseMessage
-    (ResponseClass . "Success")
-    (ResponseCode . "NoError")
-    (Items
-     (CalendarItem
-      (ItemId
-       (Id . "A[...]A==")
-       (ChangeKey . "D[...]h"))
-      (ParentFolderId
-       (Id . "A[...]A")
-       (ChangeKey . "A[...]A=="))
-      (ItemClass . "IPM.Appointment")
-      (Subject . "Test recurrence 1")
-      (Sensitivity . "Normal")
-      (Body
-       (BodyType . "Text") . "Testing recurrence creation.")
-      (DateTimeReceived . "2020-09-26T00:23:59Z")
-      (Size . 13636)
-      (Importance . "Normal")
-      (IsSubmitted)
-      (IsDraft)
-      (IsFromMe)
-      (IsResend)
-      (IsUnmodified)
-      (DateTimeSent . "2020-09-26T00:23:59Z")
-      (DateTimeCreated . "2020-09-26T00:23:59Z")
-      (ResponseObjects
-       (ForwardItem)
-       (CancelCalendarItem))
-      (ReminderDueBy . "2020-10-02T21:00:00Z")
-      (ReminderIsSet . t)
-      (ReminderMinutesBeforeStart . 15)
-      (DisplayCc)
-      (DisplayTo . "Hacker One")
-      (HasAttachments)
-      (Culture . "en-US")
-      (Start . "2020-09-25T21:00:00Z")
-      (End . "2020-09-25T22:00:00Z")
-      (IsAllDayEvent)
-      (LegacyFreeBusyStatus . "Busy")
-      (Location . "Online")
-      (IsMeeting . t)
-      (IsCancelled)
-      (IsRecurring)
-      (MeetingRequestWasSent)
-      (IsResponseRequested . t)
-      (CalendarItemType . "RecurringMaster")
-      (MyResponseType . "Organizer")
-      (Organizer
-       (Mailbox
-        (Name . "Hacker One")
-        (EmailAddress . "hacker1@@gnu.org")
-        (RoutingType . "SMTP")))
-      (RequiredAttendees
-       (Attendee
-        (Mailbox
-         (Name . "Hacker One")
-         (EmailAddress . "hacker1@@gnu.org")
-         (RoutingType . "SMTP")
-         (MailboxType . "Mailbox"))
-        (ResponseType . "Unknown")))
-      (Duration . "PT1H")
-      (TimeZone . "
-(UTC-05:00) Eastern Time
-(US & Canada)")
-      (AppointmentSequenceNumber . 0)
-      (AppointmentState . 1)
-      (Recurrence
-       (WeeklyRecurrence
-        (Interval . 1)
-        (DaysOfWeek "Friday"))
-       (NumberedRecurrence
-        (StartDate . "2020-09-25-04:00")
-        (NumberOfOccurrences . 4)))
-      (FirstOccurrence
-       (ItemId
-        (Id . "A[...]A==")
-        (ChangeKey . "D[...]h"))
-       (Start . "2020-09-25T21:00:00Z")
-       (End . "2020-09-25T22:00:00Z")
-       (OriginalStart . "2020-09-25T21:00:00Z"))
-      (LastOccurrence
-       (ItemId
-        (Id . "A[...]A==")
-        (ChangeKey . "D[...]h"))
-       (Start . "2020-10-16T21:00:00Z")
-       (End . "2020-10-16T22:00:00Z")
-       (OriginalStart . "2020-10-16T21:00:00Z"))
-      (MeetingTimeZone
-       (TimeZoneName . "Eastern Standard Time")
-       (BaseOffset . 0)
-       (Daylight
-        (TimeZoneName . "Daylight")
-        (Offset . 0)
-        (RelativeYearlyRecurrence
-         (DaysOfWeek . "Sunday")
-         (DayOfWeekIndex . "Second")
-         (Month . "March"))
-        (Time . "02:00:00"))
-       (Standard
-        (TimeZoneName . "Standard")
-        (Offset . 0)
-        (RelativeYearlyRecurrence
-         (DaysOfWeek . "Sunday")
-         (DayOfWeekIndex . "First")
-         (Month . "November"))
-        (Time . "02:00:00")))
-      (IsOnlineMeeting)))))))
-@end group
-@end example
-
-
-@noindent
-Finally, this is how to delete all the occurrences in the series.
-ItemId here is the top-level recurrence item identifier which is
-returned as @code{(CalendarItem (ItemId ...) ...)} by the above
-@code{GetItem} operation, whose @code{CalendarType} element is
-``RecurringMaster''.
-
-@example
-@group
-(exco-operate
- (car exco--connection-identifiers)
- "DeleteItem"
- '(((DeleteType . "MoveToDeletedItems")
-    (SendMeetingCancellations . "SendToNone")
-    (ItemIds
-     (ItemId
-      (Id . "A[...]A==")
-      (ChangeKey . "D[...]h"))))
-   nil nil nil)
- (lambda (identifier response)
-   (message "%S: %S" identifier response)))
-@result{}
-;; Printed in *Messages*:
-("hacker1@@gnu.org" . "https://mail.gnu.org/EWS/Exchange.asmx";):
-(((ResponseMessages
-   (DeleteItemResponseMessage
-    (ResponseClass . "Success")
-    (ResponseCode . "NoError")))))
-@end group
-@end example
-
-@noindent
-Feel free to contribute new functions that you think others would find
-useful; file a bug with a patch against
-@code{https://git.savannah.gnu.org/git/emacs/elpa.git}.  Functions in
-@code{excorporate.el} must always keep the same interface so that they
-stay backward compatible.  If an existing function has an insufficient
-interface, make a new one.  Excorporate functions are written to work
-with older Emacs versions, back to Emacs 24.1.
-
-@bye



reply via email to

[Prev in Thread] Current Thread [Next in Thread]