Merge from emacs-24; up to 2012-04-22T13:58:00Z!cyd@gnu.org
[bpt/emacs.git] / lisp / org / org-agenda.el
index bb9f4be..ddb56ca 100644 (file)
@@ -1,12 +1,10 @@
 ;;; org-agenda.el --- Dynamic task and appointment lists for Org
 
 ;;; org-agenda.el --- Dynamic task and appointment lists for Org
 
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 2004-2012 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
-;; Version: 7.4
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 ;;; Commentary:
 
 ;; This file contains the code for creating and using the Agenda for Org-mode.
 ;;; Commentary:
 
 ;; This file contains the code for creating and using the Agenda for Org-mode.
+;;
+;; The functions `org-batch-agenda', `org-batch-agenda-csv', and
+;; `org-batch-store-agenda-views' are implemented as macros to provide
+;; a convenient way for extracting agenda information from the command
+;; line. The Lisp does not evaluate parameters of a macro call; thus
+;; it is not necessary to quote the parameters passed to one of those
+;; functions. E.g. you can write:
+;;
+;;   emacs -batch -l ~/.emacs -eval '(org-batch-agenda "a" org-agenda-span 7)'
+;;
+;; To export an agenda spanning 7 days. If `org-batch-agenda' would
+;; have been implemented as a regular function you'd have to quote the
+;; symbol org-agenda-span. Moreover: To use a symbol as parameter
+;; value you would have to double quote the symbol.
+;;
+;; This is a hack, but it works even when running Org byte-compiled.
+;;
 
 ;;; Code:
 
 
 ;;; Code:
 
@@ -51,6 +66,8 @@
 (declare-function calendar-julian-date-string   "cal-julian" (&optional date))
 (declare-function calendar-mayan-date-string    "cal-mayan"  (&optional date))
 (declare-function calendar-persian-date-string  "cal-persia" (&optional date))
 (declare-function calendar-julian-date-string   "cal-julian" (&optional date))
 (declare-function calendar-mayan-date-string    "cal-mayan"  (&optional date))
 (declare-function calendar-persian-date-string  "cal-persia" (&optional date))
+(declare-function calendar-check-holidays       "holidays" (date))
+
 (declare-function org-datetree-find-date-create "org-datetree"
                  (date &optional keep-restriction))
 (declare-function org-columns-quit              "org-colview" ())
 (declare-function org-datetree-find-date-create "org-datetree"
                  (date &optional keep-restriction))
 (declare-function org-columns-quit              "org-colview" ())
@@ -61,6 +78,9 @@
 (declare-function org-is-habit-p "org-habit" (&optional pom))
 (declare-function org-habit-parse-todo "org-habit" (&optional pom))
 (declare-function org-habit-get-priority "org-habit" (habit &optional moment))
 (declare-function org-is-habit-p "org-habit" (&optional pom))
 (declare-function org-habit-parse-todo "org-habit" (&optional pom))
 (declare-function org-habit-get-priority "org-habit" (habit &optional moment))
+(declare-function org-pop-to-buffer-same-window "org-compat"
+                 (&optional buffer-or-name norecord label))
+
 (defvar calendar-mode-map)
 (defvar org-clock-current-task) ; defined in org-clock.el
 (defvar org-mobile-force-id-on-agenda-items) ; defined in org-mobile.el
 (defvar calendar-mode-map)
 (defvar org-clock-current-task) ; defined in org-clock.el
 (defvar org-mobile-force-id-on-agenda-items) ; defined in org-mobile.el
@@ -89,16 +109,20 @@ only needed when the text to be killed contains more than N non-white lines."
 
 (defcustom org-agenda-compact-blocks nil
   "Non-nil means make the block agenda more compact.
 
 (defcustom org-agenda-compact-blocks nil
   "Non-nil means make the block agenda more compact.
-This is done by leaving out unnecessary lines."
+This is done globally by leaving out lines like the agenda span
+name and week number or the separator lines."
   :group 'org-agenda
   :type 'boolean)
 
 (defcustom org-agenda-block-separator ?=
   "The separator between blocks in the agenda.
 If this is a string, it will be used as the separator, with a newline added.
   :group 'org-agenda
   :type 'boolean)
 
 (defcustom org-agenda-block-separator ?=
   "The separator between blocks in the agenda.
 If this is a string, it will be used as the separator, with a newline added.
-If it is a character, it will be repeated to fill the window width."
+If it is a character, it will be repeated to fill the window width.
+If nil the separator is disabled.  In `org-agenda-custom-commands' this
+addresses the separator between the current and the previous block."
   :group 'org-agenda
   :type '(choice
   :group 'org-agenda
   :type '(choice
+         (const :tag "Disabled" nil)
          (character)
          (string)))
 
          (character)
          (string)))
 
@@ -221,6 +245,10 @@ you can \"misuse\" it to also add other text to the header.  However,
     (const user-defined-up) (const user-defined-down))
   "Sorting choices.")
 
     (const user-defined-up) (const user-defined-down))
   "Sorting choices.")
 
+;; Keep custom values for `org-agenda-filter-preset' compatible with
+;; the new variable `org-agenda-tag-filter-preset'.
+(defvaralias 'org-agenda-filter-preset 'org-agenda-tag-filter-preset)
+
 (defconst org-agenda-custom-commands-local-options
   `(repeat :tag "Local settings for this command. Remember to quote values"
           (choice :tag "Setting"
 (defconst org-agenda-custom-commands-local-options
   `(repeat :tag "Local settings for this command. Remember to quote values"
           (choice :tag "Setting"
@@ -262,19 +290,27 @@ you can \"misuse\" it to also add other text to the header.  However,
            (list :tag "Deadline Warning days"
                  (const org-deadline-warning-days)
                  (integer :value 1))
            (list :tag "Deadline Warning days"
                  (const org-deadline-warning-days)
                  (integer :value 1))
+           (list :tag "Category filter preset"
+                 (const org-agenda-category-filter-preset)
+                 (list
+                  (const :format "" quote)
+                  (repeat
+                   (string :tag "+category or -category"))))
            (list :tag "Tags filter preset"
            (list :tag "Tags filter preset"
-                 (const org-agenda-filter-preset)
+                 (const org-agenda-tag-filter-preset)
                  (list
                   (const :format "" quote)
                   (repeat
                    (string :tag "+tag or -tag"))))
            (list :tag "Set daily/weekly entry types"
                  (const org-agenda-entry-types)
                  (list
                   (const :format "" quote)
                   (repeat
                    (string :tag "+tag or -tag"))))
            (list :tag "Set daily/weekly entry types"
                  (const org-agenda-entry-types)
-                 (set :greedy t :value (:deadline :scheduled :timestamp :sexp)
-                      (const :deadline)
-                      (const :scheduled)
-                      (const :timestamp)
-                      (const :sexp)))
+                 (list
+                  (const :format "" quote)
+                  (set :greedy t :value (:deadline :scheduled :timestamp :sexp)
+                       (const :deadline)
+                       (const :scheduled)
+                       (const :timestamp)
+                       (const :sexp))))
            (list :tag "Standard skipping condition"
                  :value (org-agenda-skip-function '(org-agenda-skip-entry-if))
                  (const org-agenda-skip-function)
            (list :tag "Standard skipping condition"
                  :value (org-agenda-skip-function '(org-agenda-skip-entry-if))
                  (const org-agenda-skip-function)
@@ -326,7 +362,8 @@ This will be spliced into the custom type of
 `org-agenda-custom-commands'.")
 
 
 `org-agenda-custom-commands'.")
 
 
-(defcustom org-agenda-custom-commands nil
+(defcustom org-agenda-custom-commands '(("n" "Agenda and all TODO's"
+                                        ((agenda "") (alltodo))))
   "Custom commands for the agenda.
 These commands will be offered on the splash screen displayed by the
 agenda dispatcher \\[org-agenda].  Each entry is a list like this:
   "Custom commands for the agenda.
 These commands will be offered on the splash screen displayed by the
 agenda dispatcher \\[org-agenda].  Each entry is a list like this:
@@ -371,7 +408,7 @@ where
 
 desc   A description string to be displayed in the dispatcher menu.
 cmd    An agenda command, similar to the above.  However, tree commands
 
 desc   A description string to be displayed in the dispatcher menu.
 cmd    An agenda command, similar to the above.  However, tree commands
-       are no allowed, but instead you can get agenda and global todo list.
+       are not allowed, but instead you can get agenda and global todo list.
        So valid commands for a set are:
        (agenda \"\" settings)
        (alltodo \"\" settings)
        So valid commands for a set are:
        (agenda \"\" settings)
        (alltodo \"\" settings)
@@ -516,6 +553,23 @@ this one will be used."
  "Options concerning skipping parts of agenda files."
  :tag "Org Agenda Skip"
  :group 'org-agenda)
  "Options concerning skipping parts of agenda files."
  :tag "Org Agenda Skip"
  :group 'org-agenda)
+
+(defcustom org-agenda-skip-function-global nil
+  "Function to be called at each match during agenda construction.
+If this function returns nil, the current match should not be skipped.
+If the function decided to skip an agenda match, is must return the
+buffer position from which the search should be continued.
+This may also be a Lisp form, which will be evaluated.
+
+This variable will be applied to every agenda match, including
+tags/property searches and TODO lists.  So try to make the test function
+do its checking as efficiently as possible.  To implement a skipping
+condition just for specific agenda commands, use the variable
+`org-agenda-skip-function' which can be set in the options section
+of custom agenda commands."
+  :group 'org-agenda-skip
+  :type 'sexp)
+
 (defgroup org-agenda-daily/weekly nil
   "Options concerning the daily/weekly agenda."
   :tag "Org Agenda Daily/Weekly"
 (defgroup org-agenda-daily/weekly nil
   "Options concerning the daily/weekly agenda."
   :tag "Org Agenda Daily/Weekly"
@@ -582,16 +636,26 @@ all      Don't show any entries with a timestamp in the global todo list.
          The idea behind this is that by setting a timestamp, you
          have already \"taken care\" of this item.
 
          The idea behind this is that by setting a timestamp, you
          have already \"taken care\" of this item.
 
+This variable can also have an integer as a value. If positive (N),
+todos with a timestamp N or more days in the future will be ignored. If
+negative (-N), todos with a timestamp N or more days in the past will be
+ignored. If 0, todos with a timestamp either today or in the future will
+be ignored. For example, a value of -1 will exclude todos with a
+timestamp in the past (yesterday or earlier), while a value of 7 will
+exclude todos with a timestamp a week or more in the future.
+
 See also `org-agenda-todo-ignore-with-date'.
 See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
 to make his option also apply to the tags-todo list."
   :group 'org-agenda-skip
   :group 'org-agenda-todo-list
 See also `org-agenda-todo-ignore-with-date'.
 See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
 to make his option also apply to the tags-todo list."
   :group 'org-agenda-skip
   :group 'org-agenda-todo-list
+  :version "24.1"
   :type '(choice
          (const :tag "Ignore future timestamp todos" future)
          (const :tag "Ignore past or present timestamp todos" past)
          (const :tag "Ignore all timestamp todos" all)
   :type '(choice
          (const :tag "Ignore future timestamp todos" future)
          (const :tag "Ignore past or present timestamp todos" past)
          (const :tag "Ignore all timestamp todos" all)
-         (const :tag "Show timestamp todos" nil)))
+         (const :tag "Show timestamp todos" nil)
+         (integer :tag "Ignore if N or more days in past(-) or future(+).")))
 
 (defcustom org-agenda-todo-ignore-scheduled nil
   "Non-nil means, ignore some scheduled TODO items when making TODO list.
 
 (defcustom org-agenda-todo-ignore-scheduled nil
   "Non-nil means, ignore some scheduled TODO items when making TODO list.
@@ -610,6 +674,9 @@ all      Don't show any scheduled entries in the global todo list.
 
 t        Same as `all', for backward compatibility.
 
 
 t        Same as `all', for backward compatibility.
 
+This variable can also have an integer as a value. See
+`org-agenda-todo-ignore-timestamp' for more details.
+
 See also `org-agenda-todo-ignore-with-date'.
 See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
 to make his option also apply to the tags-todo list."
 See also `org-agenda-todo-ignore-with-date'.
 See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
 to make his option also apply to the tags-todo list."
@@ -620,7 +687,8 @@ to make his option also apply to the tags-todo list."
          (const :tag "Ignore past- or present-scheduled todos" past)
          (const :tag "Ignore all scheduled todos" all)
          (const :tag "Ignore all scheduled todos (compatibility)" t)
          (const :tag "Ignore past- or present-scheduled todos" past)
          (const :tag "Ignore all scheduled todos" all)
          (const :tag "Ignore all scheduled todos (compatibility)" t)
-         (const :tag "Show scheduled todos" nil)))
+         (const :tag "Show scheduled todos" nil)
+         (integer :tag "Ignore if N or more days in past(-) or future(+).")))
 
 (defcustom org-agenda-todo-ignore-deadlines nil
   "Non-nil means ignore some deadlined TODO items when making TODO list.
 
 (defcustom org-agenda-todo-ignore-deadlines nil
   "Non-nil means ignore some deadlined TODO items when making TODO list.
@@ -647,6 +715,9 @@ all     Ignore all TODO entries that do have a deadline.
 
 t       Same as `near', for backward compatibility.
 
 
 t       Same as `near', for backward compatibility.
 
+This variable can also have an integer as a value. See
+`org-agenda-todo-ignore-timestamp' for more details.
+
 See also `org-agenda-todo-ignore-with-date'.
 See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
 to make his option also apply to the tags-todo list."
 See also `org-agenda-todo-ignore-with-date'.
 See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
 to make his option also apply to the tags-todo list."
@@ -657,7 +728,8 @@ to make his option also apply to the tags-todo list."
          (const :tag "Ignore near deadlines (compatibility)" t)
          (const :tag "Ignore far deadlines" far)
          (const :tag "Ignore all TODOs with a deadlines" all)
          (const :tag "Ignore near deadlines (compatibility)" t)
          (const :tag "Ignore far deadlines" far)
          (const :tag "Ignore all TODOs with a deadlines" all)
-         (const :tag "Show all TODOs, even if they have a deadline" nil)))
+         (const :tag "Show all TODOs, even if they have a deadline" nil)
+         (integer :tag "Ignore if N or more days in past(-) or future(+).")))
 
 (defcustom org-agenda-tags-todo-honor-ignore-options nil
   "Non-nil means honor todo-list ...ignore options also in tags-todo search.
 
 (defcustom org-agenda-tags-todo-honor-ignore-options nil
   "Non-nil means honor todo-list ...ignore options also in tags-todo search.
@@ -725,12 +797,13 @@ trigger you to schedule it, and then you don't want to be reminded of it
 because you will take care of it on the day when scheduled."
   :group 'org-agenda-skip
   :group 'org-agenda-daily/weekly
 because you will take care of it on the day when scheduled."
   :group 'org-agenda-skip
   :group 'org-agenda-daily/weekly
+  :version "24.1"
   :type '(choice
          (const :tag "Alwas show prewarning" nil)
          (const :tag "Remove prewarning if entry is scheduled" t)
          (integer :tag "Restart prewarning N days before deadline")))
 
   :type '(choice
          (const :tag "Alwas show prewarning" nil)
          (const :tag "Remove prewarning if entry is scheduled" t)
          (integer :tag "Restart prewarning N days before deadline")))
 
-(defcustom org-agenda-skip-additional-timestamps-same-entry t
+(defcustom org-agenda-skip-additional-timestamps-same-entry nil
   "When nil, multiple same-day timestamps in entry make multiple agenda lines.
 When non-nil, after the search for timestamps has matched once in an
 entry, the rest of the entry will not be searched."
   "When nil, multiple same-day timestamps in entry make multiple agenda lines.
 When non-nil, after the search for timestamps has matched once in an
 entry, the rest of the entry will not be searched."
@@ -762,7 +835,7 @@ will only be dimmed."
   :group 'org-agenda-todo-list
   :type '(choice
          (const :tag "Do not dim" nil)
   :group 'org-agenda-todo-list
   :type '(choice
          (const :tag "Do not dim" nil)
-         (const :tag "Dim to a grey face" t)
+         (const :tag "Dim to a gray face" t)
          (const :tag "Make invisible" invisible)))
 
 (defcustom org-timeline-show-empty-dates 3
          (const :tag "Make invisible" invisible)))
 
 (defcustom org-timeline-show-empty-dates 3
@@ -783,12 +856,13 @@ N days, just insert a special line indicating the size of the gap."
   :group 'org-agenda)
 
 (defcustom org-agenda-menu-show-matcher t
   :group 'org-agenda)
 
 (defcustom org-agenda-menu-show-matcher t
-  "Non-nil menas show the match string in the agenda dispatcher menu.
+  "Non-nil means show the match string in the agenda dispatcher menu.
 When nil, the matcher string is not shown, but is put into the help-echo
 property so than moving the mouse over the command shows it.
 Setting it to nil is good if matcher strings are very long and/or if
 When nil, the matcher string is not shown, but is put into the help-echo
 property so than moving the mouse over the command shows it.
 Setting it to nil is good if matcher strings are very long and/or if
-you wnat to use two-column display (see `org-agenda-menu-two-column')."
+you want to use two-column display (see `org-agenda-menu-two-column')."
   :group 'org-agenda
   :group 'org-agenda
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-agenda-menu-two-column nil
   :type 'boolean)
 
 (defcustom org-agenda-menu-two-column nil
@@ -796,6 +870,7 @@ you wnat to use two-column display (see `org-agenda-menu-two-column')."
 If you use this, you probably want to set `org-agenda-menu-show-matcher'
 to nil."
   :group 'org-agenda
 If you use this, you probably want to set `org-agenda-menu-show-matcher'
 to nil."
   :group 'org-agenda
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-finalize-agenda-hook nil
   :type 'boolean)
 
 (defcustom org-finalize-agenda-hook nil
@@ -815,6 +890,13 @@ Needs to be set before org.el is loaded."
   :group 'org-agenda-startup
   :type 'boolean)
 
   :group 'org-agenda-startup
   :type 'boolean)
 
+(defcustom org-agenda-follow-indirect nil
+  "Non-nil means `org-agenda-follow-mode' displays only the
+current item's tree, in an indirect buffer."
+  :group 'org-agenda
+  :version "24.1"
+  :type 'boolean)
+
 (defcustom org-agenda-show-outline-path t
   "Non-nil means show outline path in echo area after line motion."
   :group 'org-agenda-startup
 (defcustom org-agenda-show-outline-path t
   "Non-nil means show outline path in echo area after line motion."
   :group 'org-agenda-startup
@@ -883,7 +965,7 @@ It only matters if `org-agenda-window-setup' is `reorganize-frame'."
   :type '(cons (number :tag "Minimum") (number :tag "Maximum")))
 
 (defcustom org-agenda-restore-windows-after-quit nil
   :type '(cons (number :tag "Minimum") (number :tag "Maximum")))
 
 (defcustom org-agenda-restore-windows-after-quit nil
-  "Non-nil means restore window configuration open exiting agenda.
+  "Non-nil means restore window configuration upon exiting agenda.
 Before the window configuration is changed for displaying the agenda,
 the current status is recorded.  When the agenda is exited with
 `q' or `x' and this option is set, the old state is restored.  If
 Before the window configuration is changed for displaying the agenda,
 the current status is recorded.  When the agenda is exited with
 `q' or `x' and this option is set, the old state is restored.  If
@@ -965,11 +1047,13 @@ This function makes sure that dates are aligned for easy reading."
   "Non-nil means use leading zero for military times in agenda.
 For example, 9:30am would become 09:30 rather than  9:30."
   :group 'org-agenda-daily/weekly
   "Non-nil means use leading zero for military times in agenda.
 For example, 9:30am would become 09:30 rather than  9:30."
   :group 'org-agenda-daily/weekly
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-agenda-timegrid-use-ampm nil
   "When set, show AM/PM style timestamps on the timegrid."
   :group 'org-agenda
   :type 'boolean)
 
 (defcustom org-agenda-timegrid-use-ampm nil
   "When set, show AM/PM style timestamps on the timegrid."
   :group 'org-agenda
+  :version "24.1"
   :type 'boolean)
 
 (defun org-agenda-time-of-day-to-ampm (time)
   :type 'boolean)
 
 (defun org-agenda-time-of-day-to-ampm (time)
@@ -1010,6 +1094,16 @@ and timeline buffers."
              (const :tag "Saturday" 6)
              (const :tag "Sunday" 0)))
 
              (const :tag "Saturday" 6)
              (const :tag "Sunday" 0)))
 
+(defcustom org-agenda-move-date-from-past-immediately-to-today t
+  "Non-nil means jump to today when moving a past date forward in time.
+When using S-right in the agenda to move a a date forward, and the date
+stamp currently points to the past, the first key press will move it
+to today.  WHen nil, just move one day forward even if the date stays
+in the past."
+  :group 'org-agenda-daily/weekly
+  :version "24.1"
+  :type 'boolean)
+
 (defcustom org-agenda-include-diary nil
   "If non-nil, include in the agenda entries from the Emacs Calendar's diary.
 Custom commands can set this variable in the options section."
 (defcustom org-agenda-include-diary nil
   "If non-nil, include in the agenda entries from the Emacs Calendar's diary.
 Custom commands can set this variable in the options section."
@@ -1020,22 +1114,20 @@ Custom commands can set this variable in the options section."
   "If non-nil, include entries within their deadline warning period.
 Custom commands can set this variable in the options section."
   :group 'org-agenda-daily/weekly
   "If non-nil, include entries within their deadline warning period.
 Custom commands can set this variable in the options section."
   :group 'org-agenda-daily/weekly
-  :type 'boolean)
-
-(defcustom org-agenda-include-all-todo nil
-  "Set  means weekly/daily agenda will always contain all TODO entries.
-The TODO entries will be listed at the top of the agenda, before
-the entries for specific days.
-This option is deprecated, it is better to define a block agenda instead."
-  :group 'org-agenda-daily/weekly
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-agenda-repeating-timestamp-show-all t
   "Non-nil means show all occurrences of a repeating stamp in the agenda.
   :type 'boolean)
 
 (defcustom org-agenda-repeating-timestamp-show-all t
   "Non-nil means show all occurrences of a repeating stamp in the agenda.
-When nil, only one occurrence is shown, either today or the
-nearest into the future."
+When set to a list of strings, only show occurrences of repeating
+stamps for these TODO keywords.  When nil, only one occurrence is
+shown, either today or the nearest into the future."
   :group 'org-agenda-daily/weekly
   :group 'org-agenda-daily/weekly
-  :type 'boolean)
+  :type '(choice
+         (const :tag "Show repeating stamps" t)
+         (repeat :tag "Show repeating stamps for these TODO keywords"
+                 (string :tag "TODO Keyword"))
+         (const :tag "Don't show repeating stamps" nil)))
 
 (defcustom org-scheduled-past-days 10000
   "No. of days to continue listing scheduled items that are not marked DONE.
 
 (defcustom org-scheduled-past-days 10000
   "No. of days to continue listing scheduled items that are not marked DONE.
@@ -1057,6 +1149,50 @@ the agenda to display all available LOG items temporarily."
   :group 'org-agenda-daily/weekly
   :type '(set :greedy t (const closed) (const clock) (const state)))
 
   :group 'org-agenda-daily/weekly
   :type '(set :greedy t (const closed) (const clock) (const state)))
 
+(defcustom org-agenda-clock-consistency-checks
+  '(:max-duration "10:00" :min-duration 0 :max-gap "0:05"
+                 :gap-ok-around ("4:00")
+                 :default-face ((:background "DarkRed") (:foreground "white"))
+                 :overlap-face nil :gap-face nil :no-end-time-face nil
+                 :long-face nil :short-face nil)
+  "This is a property list, with the following keys:
+
+:max-duration    Mark clocking chunks that are longer than this time.
+                 This is a time string like \"HH:MM\", or the number
+                 of minutes as an integer.
+
+:min-duration    Mark clocking chunks that are shorter that this.
+                 This is a time string like \"HH:MM\", or the number
+                 of minutes as an integer.
+
+:max-gap         Mark gaps between clocking chunks that are longer than
+                 this duration.  A number of minutes, or a string
+                 like \"HH:MM\".
+
+:gap-ok-around   List of times during the day which are usually not working
+                 times.  When a gap is detected, but the gap contains any
+                 of these times, the gap is *not* reported.  For example,
+                 if this is (\"4:00\" \"13:00\") then gaps that contain
+                 4:00 in the morning (i.e. the night) and 13:00
+                 (i.e. a typical lunch time) do not cause a warning.
+                 You should have at least one time during the night in this
+                 list, or otherwise the first task each morning will trigger
+                 a warning because it follows a long gap.
+
+Furthermore, the following properties can be used to define faces for
+issue display.
+
+:default-face         the default face, if the specific face is undefined
+:overlap-face         face for overlapping clocks
+:gap-face             face for gaps between clocks
+:no-end-time-face     face for incomplete clocks
+:long-face            face for clock intervals that are too long
+:short-face           face for clock intervals that are too short"
+  :group 'org-agenda-daily/weekly
+  :group 'org-clock
+  :version "24.1"
+  :type 'plist)
+
 (defcustom org-agenda-log-mode-add-notes t
   "Non-nil means add first line of notes to log entries in agenda views.
 If a log item like a state change or a clock entry is associated with
 (defcustom org-agenda-log-mode-add-notes t
   "Non-nil means add first line of notes to log entries in agenda views.
 If a log item like a state change or a clock entry is associated with
@@ -1113,6 +1249,7 @@ by preceding the first snippet with \"+\" or \"-\".  If the first snippet
 is a regexp marked with braces like \"{abc}\", this will also switch to
 boolean search."
   :group 'org-agenda-search-view
 is a regexp marked with braces like \"{abc}\", this will also switch to
 boolean search."
   :group 'org-agenda-search-view
+  :version "24.1"
   :type 'boolean)
 
 (if (fboundp 'defvaralias)
   :type 'boolean)
 
 (if (fboundp 'defvaralias)
@@ -1123,6 +1260,7 @@ boolean search."
   "Non-nil means, search words must be matches as complete words.
 When nil, they may also match part of a word."
   :group 'org-agenda-search-view
   "Non-nil means, search words must be matches as complete words.
 When nil, they may also match part of a word."
   :group 'org-agenda-search-view
+  :version "24.1"
   :type 'boolean)
 
 (defgroup org-agenda-time-grid nil
   :type 'boolean)
 
 (defgroup org-agenda-time-grid nil
@@ -1183,6 +1321,19 @@ a grid line."
     (string :tag "Grid String")
     (repeat :tag "Grid Times" (integer :tag "Time"))))
 
     (string :tag "Grid String")
     (repeat :tag "Grid Times" (integer :tag "Time"))))
 
+(defcustom org-agenda-show-current-time-in-grid t
+  "Non-nil means show the current time in the time grid."
+  :group 'org-agenda-time-grid
+  :version "24.1"
+  :type 'boolean)
+
+(defcustom org-agenda-current-time-string
+  "now - - - - - - - - - - - - - - - - - - - - - - - - -"
+  "The string for the current time marker in the agenda."
+  :group 'org-agenda-time-grid
+  :version "24.1"
+  :type 'string)
+
 (defgroup org-agenda-sorting nil
   "Options concerning sorting in the Org-mode Agenda."
   :tag "Org Agenda Sorting"
 (defgroup org-agenda-sorting nil
   "Options concerning sorting in the Org-mode Agenda."
   :tag "Org Agenda Sorting"
@@ -1291,32 +1442,32 @@ When nil, such items are sorted as 0 minutes effort."
     (tags  . " %i %-12:c")
     (search . " %i %-12:c"))
   "Format specifications for the prefix of items in the agenda views.
     (tags  . " %i %-12:c")
     (search . " %i %-12:c"))
   "Format specifications for the prefix of items in the agenda views.
-An alist with four entries, for the different agenda types.  The keys to the
-sublists are `agenda', `timeline', `todo', and `tags'.  The values
-are format strings.
+An alist with five entries, each for the different agenda types.  The
+keys of the sublists are `agenda', `timeline', `todo', `search' and `tags'.
+The values are format strings.
+
 This format works similar to a printf format, with the following meaning:
 
 This format works similar to a printf format, with the following meaning:
 
-  %c   the category of the item, \"Diary\" for entries from the diary, or
-       as given by the CATEGORY keyword or derived from the file name.
-  %i   the icon category of the item, as give in
-       `org-agenda-category-icon-alist'.
-  %T   the *last* tag of the item.  Last because inherited tags come
-       first in the list.
-  %t   the time-of-day specification if one applies to the entry, in the
-       format HH:MM
+  %c   the category of the item, \"Diary\" for entries from the diary,
+       or as given by the CATEGORY keyword or derived from the file name
+  %e   the effort required by the item
+  %i   the icon category of the item, see `org-agenda-category-icon-alist'
+  %T   the last tag of the item (ignore inherited tags, which come first)
+  %t   the HH:MM time-of-day specification if one applies to the entry
   %s   Scheduling/Deadline information, a short string
   %s   Scheduling/Deadline information, a short string
+  %(expression) Eval EXPRESSION and replace the control string
+                by the result
 
 All specifiers work basically like the standard `%s' of printf, but may
 
 All specifiers work basically like the standard `%s' of printf, but may
-contain two additional characters:  A question mark just after the `%' and
-a whitespace/punctuation character just before the final letter.
+contain two additional characters:  a question mark just after the `%'
+and a whitespace/punctuation character just before the final letter.
 
 If the first character after `%' is a question mark, the entire field
 
 If the first character after `%' is a question mark, the entire field
-will only be included if the corresponding value applies to the
-current entry.  This is useful for fields which should have fixed
-width when present, but zero width when absent.  For example,
-\"%?-12t\" will result in a 12 character time field if a time of the
-day is specified, but will completely disappear in entries which do
-not contain a time.
+will only be included if the corresponding value applies to the current
+entry.  This is useful for fields which should have fixed width when
+present, but zero width when absent.  For example, \"%?-12t\" will
+result in a 12 character time field if a time of the day is specified,
+but will completely disappear in entries which do not contain a time.
 
 If there is punctuation or whitespace character just before the final
 format letter, this character will be appended to the field value if
 
 If there is punctuation or whitespace character just before the final
 format letter, this character will be appended to the field value if
@@ -1324,19 +1475,16 @@ the value is not empty.  For example, the format \"%-12:c\" leads to
 \"Diary: \" if the category is \"Diary\".  If the category were be
 empty, no additional colon would be inserted.
 
 \"Diary: \" if the category is \"Diary\".  If the category were be
 empty, no additional colon would be inserted.
 
-The default value of this option is \"  %-12:c%?-12t% s\", meaning:
+The default value for the agenda sublist is \"  %-12:c%?-12t% s\",
+which means:
+
 - Indent the line with two space characters
 - Indent the line with two space characters
-- Give the category in a 12 chars wide field, padded with whitespace on
+- Give the category a 12 chars wide field, padded with whitespace on
   the right (because of `-').  Append a colon if there is a category
   (because of `:').
 - If there is a time-of-day, put it into a 12 chars wide field.  If no
   time, don't put in an empty field, just skip it (because of '?').
   the right (because of `-').  Append a colon if there is a category
   (because of `:').
 - If there is a time-of-day, put it into a 12 chars wide field.  If no
   time, don't put in an empty field, just skip it (because of '?').
-- Finally, put the scheduling information and append a whitespace.
-
-As another example, if you don't want the time-of-day of entries in
-the prefix, you could use:
-
-  (setq org-agenda-prefix-format \"  %-11:c% s\")
+- Finally, put the scheduling information.
 
 See also the variables `org-agenda-remove-times-when-in-prefix' and
 `org-agenda-remove-tags'.
 
 See also the variables `org-agenda-remove-times-when-in-prefix' and
 `org-agenda-remove-tags'.
@@ -1394,6 +1542,7 @@ that passed since this item was scheduled first."
   "Text preceding item pulled into the agenda by inactive time stamps.
 These entries are added to the agenda when pressing \"[\"."
   :group 'org-agenda-line-format
   "Text preceding item pulled into the agenda by inactive time stamps.
 These entries are added to the agenda when pressing \"[\"."
   :group 'org-agenda-line-format
+  :version "24.1"
   :type '(list
          (string :tag "Scheduled today     ")
          (string :tag "Scheduled previously")))
   :type '(list
          (string :tag "Scheduled today     ")
          (string :tag "Scheduled previously")))
@@ -1432,6 +1581,7 @@ the headline/diary entry."
   "Non-nil means remove time ranges specifications in agenda
 items that span on several days."
   :group 'org-agenda-line-format
   "Non-nil means remove time ranges specifications in agenda
 items that span on several days."
   :group 'org-agenda-line-format
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-agenda-default-appointment-duration nil
   :type 'boolean)
 
 (defcustom org-agenda-default-appointment-duration nil
@@ -1513,6 +1663,7 @@ The only argument passed to that function is the day. It should
 returns a face, or nil if does not want to specify a face and let
 the normal rules apply."
   :group 'org-agenda-line-format
 returns a face, or nil if does not want to specify a face and let
 the normal rules apply."
   :group 'org-agenda-line-format
+  :version "24.1"
   :type 'function)
 
 (defcustom org-agenda-category-icon-alist nil
   :type 'function)
 
 (defcustom org-agenda-category-icon-alist nil
@@ -1526,7 +1677,7 @@ Where CATEGORY-REGEXP is a regexp matching the categories where
 the icon should be displayed.
 FILE-OR-DATA either a file path or a string containing image data.
 
 the icon should be displayed.
 FILE-OR-DATA either a file path or a string containing image data.
 
-The other fields can be ommited safely if not needed:
+The other fields can be omitted safely if not needed:
 TYPE indicates the image type.
 DATA-P is a boolean indicating whether the FILE-OR-DATA string is
 image data.
 TYPE indicates the image type.
 DATA-P is a boolean indicating whether the FILE-OR-DATA string is
 image data.
@@ -1545,6 +1696,7 @@ category, you can use:
 
   (\"Emacs\" '(space . (:width (16))))"
   :group 'org-agenda-line-format
 
   (\"Emacs\" '(space . (:width (16))))"
   :group 'org-agenda-line-format
+  :version "24.1"
   :type '(alist :key-type (string :tag "Regexp matching category")
                :value-type (choice (list :tag "Icon"
                                          (string :tag "File or data")
   :type '(alist :key-type (string :tag "Regexp matching category")
                :value-type (choice (list :tag "Icon"
                                          (string :tag "File or data")
@@ -1563,16 +1715,6 @@ category, you can use:
   :group 'org-agenda-column-view
   :type 'boolean)
 
   :group 'org-agenda-column-view
   :type 'boolean)
 
-(defcustom org-agenda-columns-remove-prefix-from-item t
-  "Non-nil means remove the prefix from a headline for agenda column view.
-The special ITEM field in the columns format contains the current line, with
-all information shown in other columns (like the TODO state or a tag).
-When this variable is non-nil, also the agenda prefix will be removed from
-the content of the ITEM field, to make sure as much as possible of the
-headline can be shown in the limited width of the field."
-  :group 'org-agenda
-  :type 'boolean)
-
 (defcustom org-agenda-columns-compute-summary-properties t
   "Non-nil means recompute all summary properties before column view.
 When column view in the agenda is listing properties that have a summary
 (defcustom org-agenda-columns-compute-summary-properties t
   "Non-nil means recompute all summary properties before column view.
 When column view in the agenda is listing properties that have a summary
@@ -1606,6 +1748,20 @@ the lower-case version of all tags."
   :group 'org-agenda
   :type 'function)
 
   :group 'org-agenda
   :type 'function)
 
+(defcustom org-agenda-bulk-custom-functions nil
+  "Alist of characters and custom functions for bulk actions.
+For example, this value makes those two functions available:
+
+  '((?R set-category)
+    (?C bulk-cut))
+
+With selected entries in an agenda buffer, `B R' will call
+the custom function `set-category' on the selected entries.
+Note that functions in this alist don't need to be quoted."
+  :type 'alist
+  :version "24.1"
+  :group 'org-agenda)
+
 (eval-when-compile
   (require 'cl))
 (require 'org)
 (eval-when-compile
   (require 'cl))
 (require 'org)
@@ -1615,12 +1771,14 @@ the lower-case version of all tags."
 If STRING is non-nil, the text property will be fetched from position 0
 in that string.  If STRING is nil, it will be fetched from the beginning
 of the current line."
 If STRING is non-nil, the text property will be fetched from position 0
 in that string.  If STRING is nil, it will be fetched from the beginning
 of the current line."
-  `(let ((marker (get-text-property (if string 0 (point-at-bol))
-                                   'org-hd-marker string)))
-     (with-current-buffer (marker-buffer marker)
-       (save-excursion
-        (goto-char marker)
-        ,@body))))
+  (org-with-gensyms (marker)
+    `(let ((,marker (get-text-property (if string 0 (point-at-bol))
+                                      'org-hd-marker ,string)))
+       (with-current-buffer (marker-buffer ,marker)
+        (save-excursion
+          (goto-char ,marker)
+          ,@body)))))
+(def-edebug-spec org-agenda-with-point-at-orig-entry (form body))
 
 (defun org-add-agenda-custom-command (entry)
   "Replace or add a command in `org-agenda-custom-commands'.
 
 (defun org-add-agenda-custom-command (entry)
   "Replace or add a command in `org-agenda-custom-commands'.
@@ -1710,8 +1868,10 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "\C-k"     'org-agenda-kill)
 (org-defkey org-agenda-mode-map "\C-c\C-w" 'org-agenda-refile)
 (org-defkey org-agenda-mode-map "m"        'org-agenda-bulk-mark)
 (org-defkey org-agenda-mode-map "\C-k"     'org-agenda-kill)
 (org-defkey org-agenda-mode-map "\C-c\C-w" 'org-agenda-refile)
 (org-defkey org-agenda-mode-map "m"        'org-agenda-bulk-mark)
+(org-defkey org-agenda-mode-map "%"        'org-agenda-bulk-mark-regexp)
 (org-defkey org-agenda-mode-map "u"        'org-agenda-bulk-unmark)
 (org-defkey org-agenda-mode-map "U"        'org-agenda-bulk-remove-all-marks)
 (org-defkey org-agenda-mode-map "u"        'org-agenda-bulk-unmark)
 (org-defkey org-agenda-mode-map "U"        'org-agenda-bulk-remove-all-marks)
+(org-defkey org-agenda-mode-map "A"        'org-agenda-append-agenda)
 (org-defkey org-agenda-mode-map "B"        'org-agenda-bulk-action)
 (org-defkey org-agenda-mode-map "\C-c\C-x!" 'org-reload)
 (org-defkey org-agenda-mode-map "\C-c\C-x\C-a" 'org-agenda-archive-default)
 (org-defkey org-agenda-mode-map "B"        'org-agenda-bulk-action)
 (org-defkey org-agenda-mode-map "\C-c\C-x!" 'org-reload)
 (org-defkey org-agenda-mode-map "\C-c\C-x\C-a" 'org-agenda-archive-default)
@@ -1772,7 +1932,7 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "\C-c\C-xp" 'org-agenda-set-property)
 (org-defkey org-agenda-mode-map "q" 'org-agenda-quit)
 (org-defkey org-agenda-mode-map "x" 'org-agenda-exit)
 (org-defkey org-agenda-mode-map "\C-c\C-xp" 'org-agenda-set-property)
 (org-defkey org-agenda-mode-map "q" 'org-agenda-quit)
 (org-defkey org-agenda-mode-map "x" 'org-agenda-exit)
-(org-defkey org-agenda-mode-map "\C-x\C-w" 'org-write-agenda)
+(org-defkey org-agenda-mode-map "\C-x\C-w" 'org-agenda-write)
 (org-defkey org-agenda-mode-map "\C-x\C-s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "P" 'org-agenda-show-priority)
 (org-defkey org-agenda-mode-map "\C-x\C-s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "P" 'org-agenda-show-priority)
@@ -1820,6 +1980,7 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
 (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
 (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
 (org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
 (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
 (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
+(org-defkey org-agenda-mode-map "<" 'org-agenda-filter-by-category)
 (org-defkey org-agenda-mode-map ";" 'org-timer-set-timer)
 (define-key org-agenda-mode-map "?" 'org-agenda-show-the-flagging-note)
 (org-defkey org-agenda-mode-map "\C-c\C-x\C-mg"    'org-mobile-pull)
 (org-defkey org-agenda-mode-map ";" 'org-timer-set-timer)
 (define-key org-agenda-mode-map "?" 'org-agenda-show-the-flagging-note)
 (org-defkey org-agenda-mode-map "\C-c\C-x\C-mg"    'org-mobile-pull)
@@ -1886,7 +2047,7 @@ The following commands are available:
       :keys "v A"]
      "--"
      ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
       :keys "v A"]
      "--"
      ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
-    ["Write view to file" org-write-agenda t]
+    ["Write view to file" org-agenda-write t]
     ["Rebuild buffer" org-agenda-redo t]
     ["Save all Org-mode Buffers" org-save-all-org-buffers t]
     "--"
     ["Rebuild buffer" org-agenda-redo t]
     ["Save all Org-mode Buffers" org-save-all-org-buffers t]
     "--"
@@ -1914,9 +2075,10 @@ The following commands are available:
      ["Delete subtree" org-agenda-kill t])
     ("Bulk action"
      ["Mark entry" org-agenda-bulk-mark t]
      ["Delete subtree" org-agenda-kill t])
     ("Bulk action"
      ["Mark entry" org-agenda-bulk-mark t]
+     ["Mark matching regexp" org-agenda-bulk-mark-regexp t]
      ["Unmark entry" org-agenda-bulk-unmark t]
      ["Unmark entry" org-agenda-bulk-unmark t]
-     ["Act on all marked" org-agenda-bulk-action t]
      ["Unmark all entries" org-agenda-bulk-remove-all-marks :active t :keys "C-u s"])
      ["Unmark all entries" org-agenda-bulk-remove-all-marks :active t :keys "C-u s"])
+     ["Act on all marked" org-agenda-bulk-action t]
     "--"
     ("Tags and Properties"
      ["Show all Tags" org-agenda-show-tags t]
     "--"
     ("Tags and Properties"
      ["Show all Tags" org-agenda-show-tags t]
@@ -1989,7 +2151,6 @@ The following commands are available:
 (defvar org-agenda-pending-undo-list nil
   "In a series of undo commands, this is the list of remaining undo items.")
 
 (defvar org-agenda-pending-undo-list nil
   "In a series of undo commands, this is the list of remaining undo items.")
 
-
 (defun org-agenda-undo ()
   "Undo a remote editing step in the agenda.
 This undoes changes both in the agenda buffer and in the remote buffer
 (defun org-agenda-undo ()
   "Undo a remote editing step in the agenda.
 This undoes changes both in the agenda buffer and in the remote buffer
@@ -2105,6 +2266,8 @@ Pressing `<' twice means to restrict to the current subtree or region
        (move-marker org-agenda-restrict-end nil))
       ;; Delete old local properties
       (put 'org-agenda-redo-command 'org-lprops nil)
        (move-marker org-agenda-restrict-end nil))
       ;; Delete old local properties
       (put 'org-agenda-redo-command 'org-lprops nil)
+      ;; Delete previously set last-arguments
+      (put 'org-agenda-redo-command 'last-args nil)
       ;; Remember where this call originated
       (setq org-agenda-last-dispatch-buffer (current-buffer))
       (unless keys
       ;; Remember where this call originated
       (setq org-agenda-last-dispatch-buffer (current-buffer))
       (unless keys
@@ -2157,7 +2320,7 @@ Pressing `<' twice means to restrict to the current subtree or region
               ((eq type 'todo-tree)
                (org-check-for-org-mode)
                (org-let lprops
               ((eq type 'todo-tree)
                (org-check-for-org-mode)
                (org-let lprops
-                 '(org-occur (concat "^" outline-regexp "[ \t]*"
+                 '(org-occur (concat "^" org-outline-regexp "[ \t]*"
                                      (regexp-quote match) "\\>"))))
               ((eq type 'occur-tree)
                (org-check-for-org-mode)
                                      (regexp-quote match) "\\>"))))
               ((eq type 'occur-tree)
                (org-check-for-org-mode)
@@ -2167,7 +2330,7 @@ Pressing `<' twice means to restrict to the current subtree or region
               ((fboundp type)
                (org-let lprops '(funcall type match)))
               (t (error "Invalid custom agenda command type %s" type))))
               ((fboundp type)
                (org-let lprops '(funcall type match)))
               (t (error "Invalid custom agenda command type %s" type))))
-         (org-run-agenda-series (nth 1 entry) (cddr entry))))
+         (org-agenda-run-series (nth 1 entry) (cddr entry))))
        ((equal keys "C")
        (setq org-agenda-custom-commands org-agenda-custom-commands-orig)
        (customize-variable 'org-agenda-custom-commands))
        ((equal keys "C")
        (setq org-agenda-custom-commands org-agenda-custom-commands-orig)
        (customize-variable 'org-agenda-custom-commands))
@@ -2195,7 +2358,7 @@ Pressing `<' twice means to restrict to the current subtree or region
                               nil 'face 'org-warning)))))))
         t t))
        ((equal keys "L")
                               nil 'face 'org-warning)))))))
         t t))
        ((equal keys "L")
-       (unless (org-mode-p)
+       (unless (eq major-mode 'org-mode)
          (error "This is not an Org-mode file"))
        (unless restriction
          (put 'org-agenda-files 'org-restrict (list bfn))
          (error "This is not an Org-mode file"))
        (unless restriction
          (put 'org-agenda-files 'org-restrict (list bfn))
@@ -2205,6 +2368,17 @@ Pressing `<' twice means to restrict to the current subtree or region
        ((equal keys "!") (customize-variable 'org-stuck-projects))
        (t (error "Invalid agenda key"))))))
 
        ((equal keys "!") (customize-variable 'org-stuck-projects))
        (t (error "Invalid agenda key"))))))
 
+(defun org-agenda-append-agenda ()
+  "Append another agenda view to the current one.
+This function allows interactive building of block agendas.
+Agenda views are separated by `org-agenda-block-separator'."
+  (interactive)
+  (unless (string= (buffer-name) org-agenda-buffer-name)
+    (error "Can only append from within agenda buffer"))
+  (let ((org-agenda-multi t))
+    (org-agenda)
+    (widen)))
+
 (defun org-agenda-normalize-custom-commands (cmds)
   (delq nil
        (mapcar
 (defun org-agenda-normalize-custom-commands (cmds)
   (delq nil
        (mapcar
@@ -2219,7 +2393,7 @@ Pressing `<' twice means to restrict to the current subtree or region
   "The user interface for selecting an agenda command."
   (catch 'exit
     (let* ((bfn (buffer-file-name (buffer-base-buffer)))
   "The user interface for selecting an agenda command."
   (catch 'exit
     (let* ((bfn (buffer-file-name (buffer-base-buffer)))
-          (restrict-ok (and bfn (org-mode-p)))
+          (restrict-ok (and bfn (eq major-mode 'org-mode)))
           (region-p (org-region-active-p))
           (custom org-agenda-custom-commands)
           (selstring "")
           (region-p (org-region-active-p))
           (custom org-agenda-custom-commands)
           (selstring "")
@@ -2403,10 +2577,17 @@ s   Search for keywords                 C   Configure custom agenda commands
           ((equal c ?q) (error "Abort"))
           (t (error "Invalid key %c" c))))))))
 
           ((equal c ?q) (error "Abort"))
           (t (error "Invalid key %c" c))))))))
 
-(defun org-run-agenda-series (name series)
+(defvar org-agenda-overriding-arguments nil) ; dynamically scoped parameter
+(defvar org-agenda-last-arguments nil
+  "The arguments of the previous call to `org-agenda'.")
+(defun org-agenda-run-series (name series)
   (org-let (nth 1 series) '(org-prepare-agenda name))
   (let* ((org-agenda-multi t)
   (org-let (nth 1 series) '(org-prepare-agenda name))
   (let* ((org-agenda-multi t)
-        (redo (list 'org-run-agenda-series name (list 'quote series)))
+        (redo (list 'org-agenda-run-series name (list 'quote series)))
+        (org-agenda-overriding-arguments
+         (or org-agenda-overriding-arguments
+             (unless (null (delq nil (get 'org-agenda-redo-command 'last-args)))
+               (get 'org-agenda-redo-command 'last-args))))
         (cmds (car series))
         (gprops (nth 1 series))
         match ;; The byte compiler incorrectly complains about this.  Keep it!
         (cmds (car series))
         (gprops (nth 1 series))
         match ;; The byte compiler incorrectly complains about this.  Keep it!
@@ -2441,6 +2622,7 @@ s   Search for keywords                 C   Configure custom agenda commands
        (t (error "Invalid type in command series"))))
     (widen)
     (setq org-agenda-redo-command redo)
        (t (error "Invalid type in command series"))))
     (widen)
     (setq org-agenda-redo-command redo)
+    (put 'org-agenda-redo-command 'last-args org-agenda-last-arguments)
     (goto-char (point-min)))
   (org-fit-agenda-window)
   (org-let (nth 1 series) '(org-finalize-agenda)))
     (goto-char (point-min)))
   (org-fit-agenda-window)
   (org-let (nth 1 series) '(org-finalize-agenda)))
@@ -2453,23 +2635,13 @@ If CMD-KEY is a string of length 1, it is used as a key in
 longer string it is used as a tags/todo match string.
 Parameters are alternating variable names and values that will be bound
 before running the agenda command."
 longer string it is used as a tags/todo match string.
 Parameters are alternating variable names and values that will be bound
 before running the agenda command."
-  (let (pars)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
+  (org-eval-in-environment (org-make-parameter-alist parameters)
     (if (> (length cmd-key) 2)
     (if (> (length cmd-key) 2)
-       (eval (list 'let (nreverse pars)
-                   (list 'org-tags-view nil cmd-key)))
-      (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
-    (set-buffer org-agenda-buffer-name)
-    (princ (org-encode-for-stdout (buffer-string)))))
-
-;(defun org-encode-for-stdout (string)
-;  (if (fboundp 'encode-coding-string)
-;      (encode-coding-string string buffer-file-coding-system)
-;    string))
-
-(defun org-encode-for-stdout (string)
-  string)
+       (org-tags-view nil cmd-key)
+      (org-agenda nil cmd-key)))
+  (set-buffer org-agenda-buffer-name)
+  (princ (buffer-string)))
+(def-edebug-spec org-batch-agenda (form &rest sexp))
 
 (defvar org-agenda-info nil)
 
 
 (defvar org-agenda-info nil)
 
@@ -2508,30 +2680,26 @@ extra        Sting with extra planning info
 priority-l   The priority letter if any was given
 priority-n   The computed numerical priority
 agenda-day   The day in the agenda where this is listed"
 priority-l   The priority letter if any was given
 priority-n   The computed numerical priority
 agenda-day   The day in the agenda where this is listed"
-
-  (let (pars)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
-    (push (list 'org-agenda-remove-tags t) pars)
+  (org-eval-in-environment (append '((org-agenda-remove-tags t))
+                                  (org-make-parameter-alist parameters))
     (if (> (length cmd-key) 2)
     (if (> (length cmd-key) 2)
-       (eval (list 'let (nreverse pars)
-                   (list 'org-tags-view nil cmd-key)))
-      (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
-    (set-buffer org-agenda-buffer-name)
-    (let* ((lines (org-split-string (buffer-string) "\n"))
-          line)
-      (while (setq line (pop lines))
-       (catch 'next
-         (if (not (get-text-property 0 'org-category line)) (throw 'next nil))
-         (setq org-agenda-info
-               (org-fix-agenda-info (text-properties-at 0 line)))
-         (princ
-          (org-encode-for-stdout
-           (mapconcat 'org-agenda-export-csv-mapper
-                      '(org-category txt type todo tags date time extra
-                                     priority-letter priority agenda-day)
-                     ",")))
-         (princ "\n"))))))
+       (org-tags-view nil cmd-key)
+      (org-agenda nil cmd-key)))
+  (set-buffer org-agenda-buffer-name)
+  (let* ((lines (org-split-string (buffer-string) "\n"))
+        line)
+    (while (setq line (pop lines))
+      (catch 'next
+       (if (not (get-text-property 0 'org-category line)) (throw 'next nil))
+       (setq org-agenda-info
+             (org-fix-agenda-info (text-properties-at 0 line)))
+       (princ
+        (mapconcat 'org-agenda-export-csv-mapper
+                   '(org-category txt type todo tags date time extra
+                                  priority-letter priority agenda-day)
+                   ","))
+       (princ "\n")))))
+(def-edebug-spec org-batch-agenda-csv (form &rest sexp))
 
 (defun org-fix-agenda-info (props)
   "Make sure all properties on an agenda item have a canonical form.
 
 (defun org-fix-agenda-info (props)
   "Make sure all properties on an agenda item have a canonical form.
@@ -2581,17 +2749,14 @@ This ensures the export commands can easily use it."
   (interactive)
   (eval (list 'org-batch-store-agenda-views)))
 
   (interactive)
   (eval (list 'org-batch-store-agenda-views)))
 
-;; FIXME, why is this a macro?????
 ;;;###autoload
 (defmacro org-batch-store-agenda-views (&rest parameters)
   "Run all custom agenda commands that have a file argument."
   (let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
        (pop-up-frames nil)
        (dir default-directory)
 ;;;###autoload
 (defmacro org-batch-store-agenda-views (&rest parameters)
   "Run all custom agenda commands that have a file argument."
   (let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
        (pop-up-frames nil)
        (dir default-directory)
-       pars cmd thiscmdkey files opts cmd-or-set)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
-    (setq pars (reverse pars))
+       (pars (org-make-parameter-alist parameters))
+       cmd thiscmdkey files opts cmd-or-set)
     (save-window-excursion
       (while cmds
        (setq cmd (pop cmds)
     (save-window-excursion
       (while cmds
        (setq cmd (pop cmds)
@@ -2601,15 +2766,17 @@ This ensures the export commands can easily use it."
              files (nth (if (listp cmd-or-set) 4 5) cmd))
        (if (stringp files) (setq files (list files)))
        (when files
              files (nth (if (listp cmd-or-set) 4 5) cmd))
        (if (stringp files) (setq files (list files)))
        (when files
-         (eval (list 'let (append org-agenda-exporter-settings opts pars)
-                     (list 'org-agenda nil thiscmdkey)))
+         (org-eval-in-environment (append org-agenda-exporter-settings
+                                          opts pars)
+           (org-agenda nil thiscmdkey))
          (set-buffer org-agenda-buffer-name)
          (while files
          (set-buffer org-agenda-buffer-name)
          (while files
-           (eval (list 'let (append org-agenda-exporter-settings opts pars)
-                       (list 'org-write-agenda
-                             (expand-file-name (pop files) dir) nil t))))
+           (org-eval-in-environment (append org-agenda-exporter-settings
+                                            opts pars)
+             (org-agenda-write (expand-file-name (pop files) dir) nil t)))
          (and (get-buffer org-agenda-buffer-name)
               (kill-buffer org-agenda-buffer-name)))))))
          (and (get-buffer org-agenda-buffer-name)
               (kill-buffer org-agenda-buffer-name)))))))
+(def-edebug-spec org-batch-store-agenda-views (&rest sexp))
 
 (defun org-agenda-mark-header-line (pos)
   "Mark the line at POS as an agenda structure header."
 
 (defun org-agenda-mark-header-line (pos)
   "Mark the line at POS as an agenda structure header."
@@ -2622,7 +2789,8 @@ This ensures the export commands can easily use it."
                         'org-agenda-title-append org-agenda-title-append))))
 
 (defvar org-mobile-creating-agendas)
                         'org-agenda-title-append org-agenda-title-append))))
 
 (defvar org-mobile-creating-agendas)
-(defun org-write-agenda (file &optional open nosettings)
+(defvar org-agenda-write-buffer-name "Agenda View")
+(defun org-agenda-write (file &optional open nosettings)
   "Write the current buffer (an agenda view) as a file.
 Depending on the extension of the file name, plain text (.txt),
 HTML (.html or .htm) or Postscript (.ps) is produced.
   "Write the current buffer (an agenda view) as a file.
 Depending on the extension of the file name, plain text (.txt),
 HTML (.html or .htm) or Postscript (.ps) is produced.
@@ -2644,7 +2812,7 @@ higher priority settings."
         (let ((bs (copy-sequence (buffer-string))) beg)
           (org-agenda-unmark-filtered-text)
           (with-temp-buffer
         (let ((bs (copy-sequence (buffer-string))) beg)
           (org-agenda-unmark-filtered-text)
           (with-temp-buffer
-            (rename-buffer "Agenda View" t)
+            (rename-buffer org-agenda-write-buffer-name t)
             (set-buffer-modified-p nil)
             (insert bs)
             (org-agenda-remove-marked-text 'org-filtered)
             (set-buffer-modified-p nil)
             (insert bs)
             (org-agenda-remove-marked-text 'org-filtered)
@@ -2705,7 +2873,8 @@ higher priority settings."
     (set-buffer org-agenda-buffer-name))
   (when open (org-open-file file)))
 
     (set-buffer org-agenda-buffer-name))
   (when open (org-open-file file)))
 
-(defvar org-agenda-filter-overlays nil)
+(defvar org-agenda-tag-filter-overlays nil)
+(defvar org-agenda-cat-filter-overlays nil)
 
 (defun org-agenda-mark-filtered-text ()
   "Mark all text hidden by filtering with a text property."
 
 (defun org-agenda-mark-filtered-text ()
   "Mark all text hidden by filtering with a text property."
@@ -2716,7 +2885,8 @@ higher priority settings."
         (put-text-property
          (overlay-start o) (overlay-end o)
          'org-filtered t)))
         (put-text-property
          (overlay-start o) (overlay-end o)
          'org-filtered t)))
-     org-agenda-filter-overlays)))
+     (append org-agenda-tag-filter-overlays
+            org-agenda-cat-filter-overlays))))
 
 (defun org-agenda-unmark-filtered-text ()
   "Remove the filtering text property."
 
 (defun org-agenda-unmark-filtered-text ()
   "Remove the filtering text property."
@@ -2763,7 +2933,7 @@ removed from the entry content.  Currently only `planning' is allowed here."
   (let (txt drawer-re kwd-time-re ind)
     (save-excursion
       (with-current-buffer (marker-buffer marker)
   (let (txt drawer-re kwd-time-re ind)
     (save-excursion
       (with-current-buffer (marker-buffer marker)
-       (if (not (org-mode-p))
+       (if (not (eq major-mode 'org-mode))
            (setq txt "")
          (save-excursion
            (save-restriction
            (setq txt "")
          (save-excursion
            (save-restriction
@@ -2879,7 +3049,7 @@ removed from the entry content.  Currently only `planning' is allowed here."
 
 (defun org-check-for-org-mode ()
   "Make sure current buffer is in org-mode.  Error if not."
 
 (defun org-check-for-org-mode ()
   "Make sure current buffer is in org-mode.  Error if not."
-  (or (org-mode-p)
+  (or (eq major-mode 'org-mode)
       (error "Cannot execute org-mode agenda command on buffer in %s"
             major-mode)))
 
       (error "Cannot execute org-mode agenda command on buffer in %s"
             major-mode)))
 
@@ -2899,9 +3069,10 @@ removed from the entry content.  Currently only `planning' is allowed here."
 (defvar org-pre-agenda-window-conf nil)
 (defvar org-agenda-columns-active nil)
 (defvar org-agenda-name nil)
 (defvar org-pre-agenda-window-conf nil)
 (defvar org-agenda-columns-active nil)
 (defvar org-agenda-name nil)
-(defvar org-agenda-filter nil)
-(defvar org-agenda-filter-while-redo nil)
-(defvar org-agenda-filter-preset nil
+(defvar org-agenda-tag-filter nil)
+(defvar org-agenda-category-filter nil)
+(defvar org-agenda-tag-filter-while-redo nil)
+(defvar org-agenda-tag-filter-preset nil
   "A preset of the tags filter used for secondary agenda filtering.
 This must be a list of strings, each string must be a single tag preceded
 by \"+\" or \"-\".
   "A preset of the tags filter used for secondary agenda filtering.
 This must be a list of strings, each string must be a single tag preceded
 by \"+\" or \"-\".
@@ -2911,24 +3082,37 @@ the entire agenda view.  In a block agenda, it will not work reliably to
 define a filter for one of the individual blocks.  You need to set it in
 the global options and expect it to be applied to the entire view.")
 
 define a filter for one of the individual blocks.  You need to set it in
 the global options and expect it to be applied to the entire view.")
 
+(defvar org-agenda-category-filter-preset nil
+  "A preset of the category filter used for secondary agenda filtering.
+This must be a list of strings, each string must be a single category
+preceded by \"+\" or \"-\".
+This variable should not be set directly, but agenda custom commands can
+bind it in the options section.  The preset filter is a global property of
+the entire agenda view.  In a block agenda, it will not work reliably to
+define a filter for one of the individual blocks.  You need to set it in
+the global options and expect it to be applied to the entire view.")
+
 (defun org-prepare-agenda (&optional name)
   (setq org-todo-keywords-for-agenda nil)
 (defun org-prepare-agenda (&optional name)
   (setq org-todo-keywords-for-agenda nil)
-  (setq org-done-keywords-for-agenda nil)
   (setq org-drawers-for-agenda nil)
   (unless org-agenda-persistent-filter
   (setq org-drawers-for-agenda nil)
   (unless org-agenda-persistent-filter
-    (setq org-agenda-filter nil))
-  (put 'org-agenda-filter :preset-filter org-agenda-filter-preset)
+    (setq org-agenda-tag-filter nil
+          org-agenda-category-filter nil))
+  (put 'org-agenda-tag-filter :preset-filter org-agenda-tag-filter-preset)
+  (put 'org-agenda-category-filter :preset-filter org-agenda-category-filter-preset)
   (if org-agenda-multi
       (progn
        (setq buffer-read-only nil)
        (goto-char (point-max))
   (if org-agenda-multi
       (progn
        (setq buffer-read-only nil)
        (goto-char (point-max))
-       (unless (or (bobp) org-agenda-compact-blocks)
+       (unless (or (bobp) org-agenda-compact-blocks
+                   (not org-agenda-block-separator))
          (insert "\n"
                  (if (stringp org-agenda-block-separator)
                      org-agenda-block-separator
                    (make-string (window-width) org-agenda-block-separator))
                  "\n"))
        (narrow-to-region (point) (point-max)))
          (insert "\n"
                  (if (stringp org-agenda-block-separator)
                      org-agenda-block-separator
                    (make-string (window-width) org-agenda-block-separator))
                  "\n"))
        (narrow-to-region (point) (point-max)))
+    (setq org-done-keywords-for-agenda nil)
     (org-agenda-reset-markers)
     (setq org-agenda-contributing-files nil)
     (setq org-agenda-columns-active nil)
     (org-agenda-reset-markers)
     (setq org-agenda-contributing-files nil)
     (setq org-agenda-columns-active nil)
@@ -2945,7 +3129,7 @@ the global options and expect it to be applied to the entire view.")
        (awin (select-window awin))
        ((not (setq org-pre-agenda-window-conf (current-window-configuration))))
        ((equal org-agenda-window-setup 'current-window)
        (awin (select-window awin))
        ((not (setq org-pre-agenda-window-conf (current-window-configuration))))
        ((equal org-agenda-window-setup 'current-window)
-       (switch-to-buffer abuf))
+       (org-pop-to-buffer-same-window abuf))
        ((equal org-agenda-window-setup 'other-window)
        (org-switch-to-buffer-other-window abuf))
        ((equal org-agenda-window-setup 'other-frame)
        ((equal org-agenda-window-setup 'other-window)
        (org-switch-to-buffer-other-window abuf))
        ((equal org-agenda-window-setup 'other-frame)
@@ -2956,7 +3140,7 @@ the global options and expect it to be applied to the entire view.")
       ;; additional test in case agenda is invoked from within agenda
       ;; buffer via elisp link
       (unless (equal (current-buffer) abuf)
       ;; additional test in case agenda is invoked from within agenda
       ;; buffer via elisp link
       (unless (equal (current-buffer) abuf)
-       (switch-to-buffer abuf)))
+       (org-pop-to-buffer-same-window abuf)))
     (setq buffer-read-only nil)
     (let ((inhibit-read-only t)) (erase-buffer))
     (org-agenda-mode)
     (setq buffer-read-only nil)
     (let ((inhibit-read-only t)) (erase-buffer))
     (org-agenda-mode)
@@ -2995,8 +3179,10 @@ the global options and expect it to be applied to the entire view.")
          (org-habit-insert-consistency-graphs))
       (run-hooks 'org-finalize-agenda-hook)
       (setq org-agenda-type (org-get-at-bol 'org-agenda-type))
          (org-habit-insert-consistency-graphs))
       (run-hooks 'org-finalize-agenda-hook)
       (setq org-agenda-type (org-get-at-bol 'org-agenda-type))
-      (when (or org-agenda-filter (get 'org-agenda-filter :preset-filter))
-       (org-agenda-filter-apply org-agenda-filter))
+      (when (or org-agenda-tag-filter (get 'org-agenda-tag-filter :preset-filter))
+       (org-agenda-filter-apply org-agenda-tag-filter 'tag))
+      (when (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter))
+       (org-agenda-filter-apply org-agenda-category-filter 'category))
       )))
 
 (defun org-agenda-mark-clocking-task ()
       )))
 
 (defun org-agenda-mark-clocking-task ()
@@ -3070,17 +3256,9 @@ the global options and expect it to be applied to the entire view.")
        (setq org-blocked-by-checkboxes nil invis1 invis)
        (let ((marker (org-get-at-bol 'org-hd-marker)))
          (when (and marker
        (setq org-blocked-by-checkboxes nil invis1 invis)
        (let ((marker (org-get-at-bol 'org-hd-marker)))
          (when (and marker
-                    (not (with-current-buffer (marker-buffer marker)
-                           (save-excursion
-                             (goto-char marker)
-                             (if (org-entry-get nil "NOBLOCKING")
-                                 t ;; Never block this entry
-                               (run-hook-with-args-until-failure
-                                'org-blocker-hook
-                                (list :type 'todo-state-change
-                                      :position marker
-                                      :from 'todo
-                                      :to 'done)))))))
+                    (with-current-buffer (marker-buffer marker)
+                      (save-excursion (goto-char marker)
+                                      (org-entry-blocked-p))))
            (if org-blocked-by-checkboxes (setq invis1 nil))
            (setq b (if invis1
                        (max (point-min) (1- (point-at-bol)))
            (if org-blocked-by-checkboxes (setq invis1 nil))
            (setq b (if invis1
                        (max (point-min) (1- (point-at-bol)))
@@ -3099,15 +3277,17 @@ Otherwise, the function must return a position from where the search
 should be continued.
 This may also be a Lisp form, it will be evaluated.
 Never set this variable using `setq' or so, because then it will apply
 should be continued.
 This may also be a Lisp form, it will be evaluated.
 Never set this variable using `setq' or so, because then it will apply
-to all future agenda commands.  Instead, bind it with `let' to scope
-it dynamically into the agenda-constructing command.  A good way to set
-it is through options in `org-agenda-custom-commands'.")
+to all future agenda commands.  If you do want a global skipping condition,
+use the option `org-agenda-skip-function-global' instead.
+The correct usage for `org-agenda-skip-function' is to bind it with
+`let' to scope it dynamically into the agenda-constructing command.
+A good way to set it is through options in `org-agenda-custom-commands'.")
 
 (defun org-agenda-skip ()
   "Throw to `:skip' in places that should be skipped.
 Also moves point to the end of the skipped region, so that search can
 continue from there."
 
 (defun org-agenda-skip ()
   "Throw to `:skip' in places that should be skipped.
 Also moves point to the end of the skipped region, so that search can
 continue from there."
-  (let ((p (point-at-bol)) to fp)
+  (let ((p (point-at-bol)) to)
     (and org-agenda-skip-archived-trees (not org-agenda-archives-mode)
         (get-text-property p :org-archived)
         (org-end-of-subtree t)
     (and org-agenda-skip-archived-trees (not org-agenda-archives-mode)
         (get-text-property p :org-archived)
         (org-end-of-subtree t)
@@ -3117,16 +3297,26 @@ continue from there."
         (org-end-of-subtree t)
         (throw :skip t))
     (if (equal (char-after p) ?#) (throw :skip t))
         (org-end-of-subtree t)
         (throw :skip t))
     (if (equal (char-after p) ?#) (throw :skip t))
-    (when (and (or (setq fp (functionp org-agenda-skip-function))
-                  (consp org-agenda-skip-function))
-              (setq to (save-excursion
-                         (save-match-data
-                           (if fp
-                               (funcall org-agenda-skip-function)
-                             (eval org-agenda-skip-function))))))
+    (when (setq to (or (org-agenda-skip-eval org-agenda-skip-function-global)
+                      (org-agenda-skip-eval org-agenda-skip-function)))
       (goto-char to)
       (throw :skip t))))
 
       (goto-char to)
       (throw :skip t))))
 
+(defun org-agenda-skip-eval (form)
+  "If FORM is a function or a list, call (or eval) is and return result.
+`save-excursion' and `save-match-data' are wrapped around the call, so point
+and match data are returned to the previous state no matter what these
+functions do."
+  (let (fp)
+    (and form
+        (or (setq fp (functionp form))
+            (consp form))
+        (save-excursion
+          (save-match-data
+            (if fp
+                (funcall form)
+              (eval form)))))))
+
 (defvar org-agenda-markers nil
   "List of all currently active markers created by `org-agenda'.")
 (defvar org-agenda-last-marker-time (org-float-time)
 (defvar org-agenda-markers nil
   "List of all currently active markers created by `org-agenda'.")
 (defvar org-agenda-last-marker-time (org-float-time)
@@ -3202,7 +3392,7 @@ no longer in use."
 
 (defvar org-agenda-only-exact-dates nil) ; dynamically scoped
 
 
 (defvar org-agenda-only-exact-dates nil) ; dynamically scoped
 
-(defun org-timeline (&optional include-all)
+(defun org-timeline (&optional dotodo)
   "Show a time-sorted view of the entries in the current org file.
 Only entries with a time stamp of today or later will be listed.  With
 \\[universal-argument] prefix, all unfinished TODO items will also be shown,
   "Show a time-sorted view of the entries in the current org file.
 Only entries with a time stamp of today or later will be listed.  With
 \\[universal-argument] prefix, all unfinished TODO items will also be shown,
@@ -3213,7 +3403,6 @@ dates."
   (org-compile-prefix-format 'timeline)
   (org-set-sorting-strategy 'timeline)
   (let* ((dopast t)
   (org-compile-prefix-format 'timeline)
   (org-set-sorting-strategy 'timeline)
   (let* ((dopast t)
-        (dotodo include-all)
         (doclosed org-agenda-show-log)
         (entry (buffer-file-name (or (buffer-base-buffer (current-buffer))
                                      (current-buffer))))
         (doclosed org-agenda-show-log)
         (entry (buffer-file-name (or (buffer-base-buffer (current-buffer))
                                      (current-buffer))))
@@ -3232,7 +3421,7 @@ dates."
     (setq org-agenda-redo-command
          (list 'progn
                (list 'org-switch-to-buffer-other-window (current-buffer))
     (setq org-agenda-redo-command
          (list 'progn
                (list 'org-switch-to-buffer-other-window (current-buffer))
-               (list 'org-timeline (list 'quote include-all))))
+               (list 'org-timeline (list 'quote dotodo))))
     (if (not dopast)
        ;; Remove past dates from the list of dates.
        (setq day-numbers (delq nil (mapcar (lambda(x)
     (if (not dopast)
        ;; Remove past dates from the list of dates.
        (setq day-numbers (delq nil (mapcar (lambda(x)
@@ -3300,22 +3489,26 @@ When EMPTY is non-nil, also include days without any entries."
   (let ((re (concat
             (if pre-re pre-re "")
             (if inactive org-ts-regexp-both org-ts-regexp)))
   (let ((re (concat
             (if pre-re pre-re "")
             (if inactive org-ts-regexp-both org-ts-regexp)))
-        dates dates1 date day day1 day2 ts1 ts2)
+        dates dates1 date day day1 day2 ts1 ts2 pos)
     (if force-today
        (setq dates (list (org-today))))
     (save-excursion
       (goto-char beg)
       (while (re-search-forward re end t)
        (setq day (time-to-days (org-time-string-to-time
     (if force-today
        (setq dates (list (org-today))))
     (save-excursion
       (goto-char beg)
       (while (re-search-forward re end t)
        (setq day (time-to-days (org-time-string-to-time
-                                (substring (match-string 1) 0 10))))
+                                (substring (match-string 1) 0 10)
+                                (current-buffer) (match-beginning 0))))
        (or (memq day dates) (push day dates)))
       (unless no-ranges
        (goto-char beg)
        (while (re-search-forward org-tr-regexp end t)
        (or (memq day dates) (push day dates)))
       (unless no-ranges
        (goto-char beg)
        (while (re-search-forward org-tr-regexp end t)
+         (setq pos (match-beginning 0))
          (setq ts1 (substring (match-string 1) 0 10)
                ts2 (substring (match-string 2) 0 10)
          (setq ts1 (substring (match-string 1) 0 10)
                ts2 (substring (match-string 2) 0 10)
-               day1 (time-to-days (org-time-string-to-time ts1))
-               day2 (time-to-days (org-time-string-to-time ts2)))
+               day1 (time-to-days (org-time-string-to-time
+                                   ts1 (current-buffer) pos))
+               day2 (time-to-days (org-time-string-to-time
+                                   ts2  (current-buffer) pos)))
          (while (< (setq day1 (1+ day1)) day2)
            (or (memq day1 dates) (push day1 dates)))))
       (setq dates (sort dates '<))
          (while (< (setq day1 (1+ day1)) day2)
            (or (memq day1 dates) (push day1 dates)))))
       (setq dates (sort dates '<))
@@ -3334,15 +3527,13 @@ When EMPTY is non-nil, also include days without any entries."
 
 ;;; Agenda Daily/Weekly
 
 
 ;;; Agenda Daily/Weekly
 
-(defvar org-agenda-overriding-arguments nil) ; dynamically scoped parameter
 (defvar org-agenda-start-day nil  ; dynamically scoped parameter
 (defvar org-agenda-start-day nil  ; dynamically scoped parameter
-"Custom commands can set this variable in the options section.")
-(defvar org-agenda-last-arguments nil
-  "The arguments of the previous call to `org-agenda'.")
+"Start day for the agenda view.
+Custom commands can set this variable in the options section.")
 (defvar org-starting-day nil) ; local variable in the agenda buffer
 (defvar org-agenda-current-span nil
   "The current span used in the agenda view.") ; local variable in the agenda buffer
 (defvar org-starting-day nil) ; local variable in the agenda buffer
 (defvar org-agenda-current-span nil
   "The current span used in the agenda view.") ; local variable in the agenda buffer
-(defvar org-include-all-loc nil) ; local variable
+(defvar org-arg-loc nil) ; local variable
 
 (defvar org-agenda-entry-types '(:deadline :scheduled :timestamp :sexp)
   "List of types searched for when creating the daily/weekly agenda.
 
 (defvar org-agenda-entry-types '(:deadline :scheduled :timestamp :sexp)
   "List of types searched for when creating the daily/weekly agenda.
@@ -3371,44 +3562,40 @@ By default, all four types are turned on.
 
 Never set this variable globally using `setq', because then it
 will apply to all future agenda commands.  Instead, bind it with
 
 Never set this variable globally using `setq', because then it
 will apply to all future agenda commands.  Instead, bind it with
-`let' to scope it dynamically into the the agenda-constructing
+`let' to scope it dynamically into the agenda-constructing
 command.  A good way to set it is through options in
 `org-agenda-custom-commands'.  For a more flexible (though
 somewhat less efficient) way of determining what is included in
 the daily/weekly agenda, see `org-agenda-skip-function'.")
 
 ;;;###autoload
 command.  A good way to set it is through options in
 `org-agenda-custom-commands'.  For a more flexible (though
 somewhat less efficient) way of determining what is included in
 the daily/weekly agenda, see `org-agenda-skip-function'.")
 
 ;;;###autoload
-(defun org-agenda-list (&optional include-all start-day span)
+(defun org-agenda-list (&optional arg start-day span)
   "Produce a daily/weekly view from all files in variable `org-agenda-files'.
 The view will be for the current day or week, but from the overview buffer
 you will be able to go to other days/weeks.
 
   "Produce a daily/weekly view from all files in variable `org-agenda-files'.
 The view will be for the current day or week, but from the overview buffer
 you will be able to go to other days/weeks.
 
-With one \\[universal-argument] prefix argument INCLUDE-ALL,
-all unfinished TODO items will also be shown, before the agenda.
-This feature is considered obsolete, please use the TODO list or a block
-agenda instead.
-
 With a numeric prefix argument in an interactive call, the agenda will
 With a numeric prefix argument in an interactive call, the agenda will
-span INCLUDE-ALL days.  Lisp programs should instead specify SPAN to change
+span ARG days.  Lisp programs should instead specify SPAN to change
 the number of days.  SPAN defaults to `org-agenda-span'.
 
 START-DAY defaults to TODAY, or to the most recent match for the weekday
 given in `org-agenda-start-on-weekday'."
   (interactive "P")
 the number of days.  SPAN defaults to `org-agenda-span'.
 
 START-DAY defaults to TODAY, or to the most recent match for the weekday
 given in `org-agenda-start-on-weekday'."
   (interactive "P")
-  (if (and (integerp include-all) (> include-all 0))
-      (setq span include-all include-all nil))
+  (if (and (integerp arg) (> arg 0))
+      (setq span arg arg nil))
   (setq start-day (or start-day org-agenda-start-day))
   (if org-agenda-overriding-arguments
   (setq start-day (or start-day org-agenda-start-day))
   (if org-agenda-overriding-arguments
-      (setq include-all (car org-agenda-overriding-arguments)
+      (setq arg (car org-agenda-overriding-arguments)
            start-day (nth 1 org-agenda-overriding-arguments)
            span (nth 2 org-agenda-overriding-arguments)))
   (if (stringp start-day)
       ;; Convert to an absolute day number
       (setq start-day (time-to-days (org-read-date nil t start-day))))
            start-day (nth 1 org-agenda-overriding-arguments)
            span (nth 2 org-agenda-overriding-arguments)))
   (if (stringp start-day)
       ;; Convert to an absolute day number
       (setq start-day (time-to-days (org-read-date nil t start-day))))
-  (setq org-agenda-last-arguments (list include-all start-day span))
+  (setq org-agenda-last-arguments (list arg start-day span))
   (org-compile-prefix-format 'agenda)
   (org-set-sorting-strategy 'agenda)
   (org-compile-prefix-format 'agenda)
   (org-set-sorting-strategy 'agenda)
-  (let* ((span (org-agenda-ndays-to-span (or span org-agenda-ndays org-agenda-span)))
+  (let* ((span (org-agenda-ndays-to-span
+               (or span org-agenda-ndays org-agenda-span)))
         (today (org-today))
         (sd (or start-day today))
         (ndays (org-agenda-span-to-ndays span sd))
         (today (org-today))
         (sd (or start-day today))
         (ndays (org-agenda-span-to-ndays span sd))
@@ -3431,7 +3618,7 @@ given in `org-agenda-start-on-weekday'."
         s e rtn rtnall file date d start-pos end-pos todayp
         clocktable-start clocktable-end filter)
     (setq org-agenda-redo-command
         s e rtn rtnall file date d start-pos end-pos todayp
         clocktable-start clocktable-end filter)
     (setq org-agenda-redo-command
-         (list 'org-agenda-list (list 'quote include-all) start-day (list 'quote span)))
+         (list 'org-agenda-list (list 'quote arg) start-day (list 'quote span)))
     (dotimes (n (1- ndays))
       (push (1+ (car day-numbers)) day-numbers))
     (setq day-numbers (nreverse day-numbers))
     (dotimes (n (1- ndays))
       (push (1+ (car day-numbers)) day-numbers))
     (setq day-numbers (nreverse day-numbers))
@@ -3439,26 +3626,8 @@ given in `org-agenda-start-on-weekday'."
          clocktable-end (1+ (or (org-last day-numbers) 0)))
     (org-prepare-agenda "Day/Week")
     (org-set-local 'org-starting-day (car day-numbers))
          clocktable-end (1+ (or (org-last day-numbers) 0)))
     (org-prepare-agenda "Day/Week")
     (org-set-local 'org-starting-day (car day-numbers))
-    (org-set-local 'org-include-all-loc include-all)
+    (org-set-local 'org-arg-loc arg)
     (org-set-local 'org-agenda-current-span (org-agenda-ndays-to-span span))
     (org-set-local 'org-agenda-current-span (org-agenda-ndays-to-span span))
-    (when (and (or include-all org-agenda-include-all-todo)
-              (member today day-numbers))
-      (setq files thefiles
-           rtnall nil)
-      (while (setq file (pop files))
-       (catch 'nextfile
-         (org-check-agenda-file file)
-         (setq date (calendar-gregorian-from-absolute today)
-               rtn (org-agenda-get-day-entries
-                    file date :todo))
-         (setq rtnall (append rtnall rtn))))
-      (when rtnall
-       (insert "All currently open TODO items:\n")
-       (add-text-properties (point-min) (1- (point))
-                            (list 'face 'org-agenda-structure
-                                  'short-heading "All TODO items"))
-       (org-agenda-mark-header-line (point-min))
-       (insert (org-finalize-agenda-entries rtnall) "\n")))
     (unless org-agenda-compact-blocks
       (let* ((d1 (car day-numbers))
             (d2 (org-last day-numbers))
     (unless org-agenda-compact-blocks
       (let* ((d1 (car day-numbers))
             (d2 (org-last day-numbers))
@@ -3497,7 +3666,7 @@ given in `org-agenda-start-on-weekday'."
              (setq org-agenda-entry-types
                    (delq :deadline org-agenda-entry-types)))
            (cond
              (setq org-agenda-entry-types
                    (delq :deadline org-agenda-entry-types)))
            (cond
-            ((eq org-agenda-show-log 'only)
+            ((memq org-agenda-show-log '(only clockcheck))
              (setq rtn (org-agenda-get-day-entries
                         file date :closed)))
             (org-agenda-show-log
              (setq rtn (org-agenda-get-day-entries
                         file date :closed)))
             (org-agenda-show-log
@@ -3508,7 +3677,7 @@ given in `org-agenda-start-on-weekday'."
              (setq rtn (apply 'org-agenda-get-day-entries
                               file date
                               org-agenda-entry-types)))))
              (setq rtn (apply 'org-agenda-get-day-entries
                               file date
                               org-agenda-entry-types)))))
-         (setq rtnall (append rtnall rtn))))
+         (setq rtnall (append rtnall rtn)))) ;; all entries
       (if org-agenda-include-diary
          (let ((org-agenda-search-headline-for-time t))
            (require 'diary-lib)
       (if org-agenda-include-diary
          (let ((org-agenda-search-headline-for-time t))
            (require 'diary-lib)
@@ -3530,7 +3699,7 @@ given in `org-agenda-start-on-weekday'."
            (put-text-property s (1- (point)) 'org-day-cnt day-cnt)
            (when todayp
              (put-text-property s (1- (point)) 'org-today t))
            (put-text-property s (1- (point)) 'org-day-cnt day-cnt)
            (when todayp
              (put-text-property s (1- (point)) 'org-today t))
-           (if rtnall (insert
+           (if rtnall (insert ;; all entries
                        (org-finalize-agenda-entries
                         (org-agenda-add-time-grid-maybe
                          rtnall ndays todayp))
                        (org-finalize-agenda-entries
                         (org-agenda-add-time-grid-maybe
                          rtnall ndays todayp))
@@ -3540,21 +3709,20 @@ given in `org-agenda-start-on-weekday'."
     (when (and org-agenda-clockreport-mode clocktable-start)
       (let ((org-agenda-files (org-agenda-files nil 'ifmode))
            ;; the above line is to ensure the restricted range!
     (when (and org-agenda-clockreport-mode clocktable-start)
       (let ((org-agenda-files (org-agenda-files nil 'ifmode))
            ;; the above line is to ensure the restricted range!
-           (p org-agenda-clockreport-parameter-plist)
+           (p (copy-sequence org-agenda-clockreport-parameter-plist))
            tbl)
        (setq p (org-plist-delete p :block))
        (setq p (plist-put p :tstart clocktable-start))
        (setq p (plist-put p :tend clocktable-end))
        (setq p (plist-put p :scope 'agenda))
        (when (and (eq org-agenda-clockreport-mode 'with-filter)
            tbl)
        (setq p (org-plist-delete p :block))
        (setq p (plist-put p :tstart clocktable-start))
        (setq p (plist-put p :tend clocktable-end))
        (setq p (plist-put p :scope 'agenda))
        (when (and (eq org-agenda-clockreport-mode 'with-filter)
-                  (setq filter (or org-agenda-filter-while-redo
-                                   (get 'org-agenda-filter :preset-filter))))
+                  (setq filter (or org-agenda-tag-filter-while-redo
+                                   (get 'org-agenda-tag-filter :preset-filter))))
          (setq p (plist-put p :tags (mapconcat (lambda (x)
                                                  (if (string-match "[<>=]" x)
                                                      ""
                                                    x))
                                                filter ""))))
          (setq p (plist-put p :tags (mapconcat (lambda (x)
                                                  (if (string-match "[<>=]" x)
                                                      ""
                                                    x))
                                                filter ""))))
-       (message "%s" (plist-get p :tags)) (sit-for 2)
        (setq tbl (apply 'org-get-clocktable p))
        (insert tbl)))
     (goto-char (point-min))
        (setq tbl (apply 'org-get-clocktable p))
        (insert tbl)))
     (goto-char (point-min))
@@ -3569,6 +3737,8 @@ given in `org-agenda-start-on-weekday'."
            (recenter 1))))
     (goto-char (or start-pos 1))
     (add-text-properties (point-min) (point-max) '(org-agenda-type agenda))
            (recenter 1))))
     (goto-char (or start-pos 1))
     (add-text-properties (point-min) (point-max) '(org-agenda-type agenda))
+    (if (eq org-agenda-show-log 'clockcheck)
+       (org-agenda-show-clocking-issues))
     (org-finalize-agenda)
     (setq buffer-read-only t)
     (message "")))
     (org-finalize-agenda)
     (setq buffer-read-only t)
     (message "")))
@@ -3677,7 +3847,7 @@ in `org-agenda-text-search-extra-files'."
         (full-words org-agenda-search-view-force-full-words)
         (org-agenda-text-search-extra-files org-agenda-text-search-extra-files)
         regexp rtn rtnall files file pos
         (full-words org-agenda-search-view-force-full-words)
         (org-agenda-text-search-extra-files org-agenda-text-search-extra-files)
         regexp rtn rtnall files file pos
-        marker category tags c neg re boolean
+        marker category org-category-pos tags c neg re boolean
         ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
     (unless (and (not edit-at)
                 (stringp string)
         ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
     (unless (and (not edit-at)
                 (stringp string)
@@ -3758,9 +3928,9 @@ in `org-agenda-text-search-extra-files'."
            regexps+))
     (setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
     (if (not regexps+)
            regexps+))
     (setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
     (if (not regexps+)
-       (setq regexp (concat "^" org-outline-regexp))
+       (setq regexp org-outline-regexp-bol)
       (setq regexp (pop regexps+))
       (setq regexp (pop regexps+))
-      (if hdl-only (setq regexp (concat "^" org-outline-regexp ".*?"
+      (if hdl-only (setq regexp (concat org-outline-regexp-bol ".*?"
                                        regexp))))
     (setq files (org-agenda-files nil 'ifmode))
     (when (eq (car org-agenda-text-search-extra-files) 'agenda-archives)
                                        regexp))))
     (setq files (org-agenda-files nil 'ifmode))
     (when (eq (car org-agenda-text-search-extra-files) 'agenda-archives)
@@ -3781,7 +3951,7 @@ in `org-agenda-text-search-extra-files'."
                                    file))))
        (with-current-buffer buffer
          (with-syntax-table (org-search-syntax-table)
                                    file))))
        (with-current-buffer buffer
          (with-syntax-table (org-search-syntax-table)
-           (unless (org-mode-p)
+           (unless (eq major-mode 'org-mode)
              (error "Agenda file %s is not in `org-mode'" file))
            (let ((case-fold-search t))
              (save-excursion
              (error "Agenda file %s is not in `org-mode'" file))
            (let ((case-fold-search t))
              (save-excursion
@@ -3791,7 +3961,7 @@ in `org-agenda-text-search-extra-files'."
                                        org-agenda-restrict-end)
                    (widen))
                  (goto-char (point-min))
                                        org-agenda-restrict-end)
                    (widen))
                  (goto-char (point-min))
-                 (unless (or (org-on-heading-p)
+                 (unless (or (org-at-heading-p)
                              (outline-next-heading))
                    (throw 'nextfile t))
                  (goto-char (max (point-min) (1- (point))))
                              (outline-next-heading))
                    (throw 'nextfile t))
                  (goto-char (max (point-min) (1- (point))))
@@ -3821,8 +3991,9 @@ in `org-agenda-text-search-extra-files'."
                      (goto-char beg)
                      (setq marker (org-agenda-new-marker (point))
                            category (org-get-category)
                      (goto-char beg)
                      (setq marker (org-agenda-new-marker (point))
                            category (org-get-category)
+                           org-category-pos (get-text-property (point) 'org-category-position)
                            tags (org-get-tags-at (point))
                            tags (org-get-tags-at (point))
-                           txt (org-format-agenda-item
+                           txt (org-agenda-format-item
                                 ""
                                 (buffer-substring-no-properties
                                  beg1 (point-at-eol))
                                 ""
                                 (buffer-substring-no-properties
                                  beg1 (point-at-eol))
@@ -3832,6 +4003,7 @@ in `org-agenda-text-search-extra-files'."
                        'org-todo-regexp org-todo-regexp
                        'org-complex-heading-regexp org-complex-heading-regexp
                        'priority 1000 'org-category category
                        'org-todo-regexp org-todo-regexp
                        'org-complex-heading-regexp org-complex-heading-regexp
                        'priority 1000 'org-category category
+                       'org-category-position org-category-pos
                        'type "search")
                      (push txt ee)
                      (goto-char (1- end))))))))))
                        'type "search")
                      (push txt ee)
                      (goto-char (1- end))))))))))
@@ -3972,7 +4144,7 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
                       (format "ORG-AGENDA-ERROR: No such org-file %s" file))
                  rtnall (append rtnall rtn))
          (with-current-buffer buffer
                       (format "ORG-AGENDA-ERROR: No such org-file %s" file))
                  rtnall (append rtnall rtn))
          (with-current-buffer buffer
-           (unless (org-mode-p)
+           (unless (eq major-mode 'org-mode)
              (error "Agenda file %s is not in `org-mode'" file))
            (save-excursion
              (save-restriction
              (error "Agenda file %s is not in `org-mode'" file))
            (save-excursion
              (save-restriction
@@ -4014,7 +4186,7 @@ This is basically a temporary global variable that can be set and then
 used by user-defined selections using `org-agenda-skip-function'.")
 
 (defvar org-agenda-overriding-header nil
 used by user-defined selections using `org-agenda-skip-function'.")
 
 (defvar org-agenda-overriding-header nil
-  "When this is set during todo and tags searches, will replace header.
+  "When set during agenda, todo and tags searches it replaces the header.
 This variable should not be set directly, but custom commands can bind it
 in the options section.")
 
 This variable should not be set directly, but custom commands can bind it
 in the options section.")
 
@@ -4068,7 +4240,7 @@ See `org-agenda-skip-if' for details."
 (defun org-agenda-skip-if (subtree conditions)
   "Checks current entity for CONDITIONS.
 If SUBTREE is non-nil, the entire subtree is checked.  Otherwise, only
 (defun org-agenda-skip-if (subtree conditions)
   "Checks current entity for CONDITIONS.
 If SUBTREE is non-nil, the entire subtree is checked.  Otherwise, only
-the entry, i.e. the text before the next heading is checked.
+the entry (i.e. the text before the next heading) is checked.
 
 CONDITIONS is a list of symbols, boolean OR is used to combine the results
 from different tests.  Valid conditions are:
 
 CONDITIONS is a list of symbols, boolean OR is used to combine the results
 from different tests.  Valid conditions are:
@@ -4094,12 +4266,12 @@ keywords, which may include \"*\" to match any todo keyword.
 
 would skip all entries with \"TODO\" or \"WAITING\" keywords.
 
 
 would skip all entries with \"TODO\" or \"WAITING\" keywords.
 
-Instead of a list a keyword class may be given
+Instead of a list, a keyword class may be given.  For example:
 
     (org-agenda-skip-entry-if 'nottodo 'done)
 
 would skip entries that haven't been marked with any of \"DONE\"
 
     (org-agenda-skip-entry-if 'nottodo 'done)
 
 would skip entries that haven't been marked with any of \"DONE\"
-keywords. Possible classes are: `todo', `done', `any'.
+keywords.  Possible classes are: `todo', `done', `any'.
 
 If any of these conditions is met, this function returns the end point of
 the entity, causing the search to continue from there.  This is a function
 
 If any of these conditions is met, this function returns the end point of
 the entity, causing the search to continue from there.  This is a function
@@ -4132,8 +4304,8 @@ that can be put into `org-agenda-skip-function' for the duration of a command."
           (stringp (nth 1 m))
           (not (re-search-forward (nth 1 m) end t)))
       (and (or
           (stringp (nth 1 m))
           (not (re-search-forward (nth 1 m) end t)))
       (and (or
-           (setq m (memq 'todo conditions))
-           (setq m (memq 'nottodo conditions)))
+           (setq m (memq 'nottodo conditions))
+           (setq m (memq 'todo conditions)))
           (org-agenda-skip-if-todo m end)))
      end)))
 
           (org-agenda-skip-if-todo m end)))
      end)))
 
@@ -4196,9 +4368,11 @@ of what a project is and how to check if it stuck, customize the variable
                          "\\)\\>"))
         (tags (nth 2 org-stuck-projects))
         (tags-re (if (member "*" tags)
                          "\\)\\>"))
         (tags (nth 2 org-stuck-projects))
         (tags-re (if (member "*" tags)
-                     (org-re "^\\*+ .*:[[:alnum:]_@#%]+:[ \t]*$")
+                     (concat org-outline-regexp-bol
+                             (org-re ".*:[[:alnum:]_@#%]+:[ \t]*$"))
                    (if tags
                    (if tags
-                       (concat "^\\*+ .*:\\("
+                       (concat org-outline-regexp-bol
+                               ".*:\\("
                                (mapconcat 'identity tags "\\|")
                                (org-re "\\):[[:alnum:]_@#%:]*[ \t]*$")))))
         (gen-re (nth 3 org-stuck-projects))
                                (mapconcat 'identity tags "\\|")
                                (org-re "\\):[[:alnum:]_@#%:]*[ \t]*$")))))
         (gen-re (nth 3 org-stuck-projects))
@@ -4223,7 +4397,7 @@ of what a project is and how to check if it stuck, customize the variable
 
 (defvar org-disable-agenda-to-diary nil)          ;Dynamically-scoped param.
 (defvar list-diary-entries-hook)
 
 (defvar org-disable-agenda-to-diary nil)          ;Dynamically-scoped param.
 (defvar list-diary-entries-hook)
-
+(defvar diary-time-regexp)
 (defun org-get-entries-from-diary (date)
   "Get the (Emacs Calendar) diary entries for DATE."
   (require 'diary-lib)
 (defun org-get-entries-from-diary (date)
   "Get the (Emacs Calendar) diary entries for DATE."
   (require 'diary-lib)
@@ -4254,7 +4428,14 @@ of what a project is and how to check if it stuck, customize the variable
          ;; Add prefix to each line and extend the text properties
          (if (zerop (buffer-size))
              (setq entries nil)
          ;; Add prefix to each line and extend the text properties
          (if (zerop (buffer-size))
              (setq entries nil)
-           (setq entries (buffer-substring (point-min) (- (point-max) 1)))))
+           (setq entries (buffer-substring (point-min) (- (point-max) 1)))
+           (setq entries
+                 (with-temp-buffer
+                   (insert entries) (goto-char (point-min))
+                   (while (re-search-forward "\n[ \t]+\\(.+\\)$" nil t)
+                     (unless (save-match-data (string-match diary-time-regexp (match-string 1)))
+                       (replace-match (concat "; " (match-string 1)))))
+                   (buffer-string)))))
        (set-buffer-modified-p nil)
        (kill-buffer diary-fancy-buffer)))
     (when entries
        (set-buffer-modified-p nil)
        (kill-buffer diary-fancy-buffer)))
     (when entries
@@ -4262,7 +4443,7 @@ of what a project is and how to check if it stuck, customize the variable
       (setq entries
            (mapcar
             (lambda (x)
       (setq entries
            (mapcar
             (lambda (x)
-              (setq x (org-format-agenda-item "" x "Diary" nil 'time))
+              (setq x (org-agenda-format-item "" x "Diary" nil 'time))
               ;; Extend the text properties to the beginning of the line
               (org-add-props x (text-properties-at (1- (length x)) x)
                 'type "diary" 'date date 'face 'org-agenda-diary))
               ;; Extend the text properties to the beginning of the line
               (org-add-props x (text-properties-at (1- (length x)) x)
                 'type "diary" 'date date 'face 'org-agenda-diary))
@@ -4407,7 +4588,7 @@ the documentation of `org-diary'."
        ;; If file does not exist, make sure an error message ends up in diary
        (list (format "ORG-AGENDA-ERROR: No such org-file %s" file))
       (with-current-buffer buffer
        ;; If file does not exist, make sure an error message ends up in diary
        (list (format "ORG-AGENDA-ERROR: No such org-file %s" file))
       (with-current-buffer buffer
-       (unless (org-mode-p)
+       (unless (eq major-mode 'org-mode)
          (error "Agenda file %s is not in `org-mode'" file))
        (let ((case-fold-search nil))
          (save-excursion
          (error "Agenda file %s is not in `org-mode'" file))
        (let ((case-fold-search nil))
          (save-excursion
@@ -4420,7 +4601,8 @@ the documentation of `org-diary'."
              (while (setq arg (pop args))
                (cond
                 ((and (eq arg :todo)
              (while (setq arg (pop args))
                (cond
                 ((and (eq arg :todo)
-                      (equal date (calendar-current-date)))
+                      (equal date (calendar-gregorian-from-absolute
+                                   (org-today))))
                  (setq rtn (org-agenda-get-todos))
                  (setq results (append results rtn)))
                 ((eq arg :timestamp)
                  (setq rtn (org-agenda-get-todos))
                  (setq results (append results rtn)))
                 ((eq arg :timestamp)
@@ -4443,6 +4625,7 @@ the documentation of `org-diary'."
                  (setq results (append results rtn))))))))
        results))))
 
                  (setq results (append results rtn))))))))
        results))))
 
+(defvar org-heading-keyword-regexp-format) ; defined in org.el
 (defun org-agenda-get-todos ()
   "Return the TODO information for agenda display."
   (let* ((props (list 'face nil
 (defun org-agenda-get-todos ()
   "Return the TODO information for agenda display."
   (let* ((props (list 'face nil
@@ -4454,47 +4637,63 @@ the documentation of `org-diary'."
                      'help-echo
                      (format "mouse-2 or RET jump to org file %s"
                              (abbreviate-file-name buffer-file-name))))
                      'help-echo
                      (format "mouse-2 or RET jump to org file %s"
                              (abbreviate-file-name buffer-file-name))))
-        (regexp (concat "^\\*+[ \t]+\\("
-                        (if org-select-this-todo-keyword
-                            (if (equal org-select-this-todo-keyword "*")
-                                org-todo-regexp
-                              (concat "\\<\\("
-                                      (mapconcat 'identity (org-split-string org-select-this-todo-keyword "|") "\\|")
-                                    "\\)\\>"))
-                          org-not-done-regexp)
-                        "[^\n\r]*\\)"))
-        marker priority category tags todo-state
+        (regexp (format org-heading-keyword-regexp-format
+                        (cond
+                         ((and org-select-this-todo-keyword
+                               (equal org-select-this-todo-keyword "*"))
+                          org-todo-regexp)
+                         (org-select-this-todo-keyword
+                          (concat "\\("
+                                  (mapconcat 'identity
+                                             (org-split-string
+                                              org-select-this-todo-keyword
+                                              "|")
+                                             "\\|") "\\)"))
+                         (t org-not-done-regexp))))
+        marker priority category org-category-pos tags todo-state
         ee txt beg end)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
        (save-match-data
          (beginning-of-line)
         ee txt beg end)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
        (save-match-data
          (beginning-of-line)
+         (org-agenda-skip)
          (setq beg (point) end (save-excursion (outline-next-heading) (point)))
          (when (org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item end)
            (goto-char (1+ beg))
            (or org-agenda-todo-list-sublevels (org-end-of-subtree 'invisible))
            (throw :skip nil)))
          (setq beg (point) end (save-excursion (outline-next-heading) (point)))
          (when (org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item end)
            (goto-char (1+ beg))
            (or org-agenda-todo-list-sublevels (org-end-of-subtree 'invisible))
            (throw :skip nil)))
-       (goto-char beg)
-       (org-agenda-skip)
-       (goto-char (match-beginning 1))
+       (goto-char (match-beginning 2))
        (setq marker (org-agenda-new-marker (match-beginning 0))
              category (org-get-category)
        (setq marker (org-agenda-new-marker (match-beginning 0))
              category (org-get-category)
-             txt (match-string 1)
+             org-category-pos (get-text-property (point) 'org-category-position)
+             txt (org-trim
+                  (buffer-substring (match-beginning 2) (match-end 0)))
              tags (org-get-tags-at (point))
              tags (org-get-tags-at (point))
-             txt (org-format-agenda-item "" txt category tags)
+             txt (org-agenda-format-item "" txt category tags)
              priority (1+ (org-get-priority txt))
              todo-state (org-get-todo-state))
        (org-add-props txt props
          'org-marker marker 'org-hd-marker marker
          'priority priority 'org-category category
              priority (1+ (org-get-priority txt))
              todo-state (org-get-todo-state))
        (org-add-props txt props
          'org-marker marker 'org-hd-marker marker
          'priority priority 'org-category category
+         'org-category-position org-category-pos
          'type "todo" 'todo-state todo-state)
        (push txt ee)
        (if org-agenda-todo-list-sublevels
          'type "todo" 'todo-state todo-state)
        (push txt ee)
        (if org-agenda-todo-list-sublevels
-           (goto-char (match-end 1))
+           (goto-char (match-end 2))
          (org-end-of-subtree 'invisible))))
     (nreverse ee)))
 
          (org-end-of-subtree 'invisible))))
     (nreverse ee)))
 
+(defun org-agenda-todo-custom-ignore-p (time n)
+  "Check whether timestamp is farther away then n number of days.
+This function is invoked if `org-agenda-todo-ignore-deadlines',
+`org-agenda-todo-ignore-scheduled' or
+`org-agenda-todo-ignore-timestamp' is set to an integer."
+  (let ((days (org-days-to-time time)))
+    (if (>= n 0)
+       (>= days n)
+      (<= days n))))
+
 ;;;###autoload
 (defun org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item
   (&optional end)
 ;;;###autoload
 (defun org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item
   (&optional end)
@@ -4514,6 +4713,9 @@ the documentation of `org-diary'."
                 (> (org-days-to-time (match-string 1)) 0))
                ((eq org-agenda-todo-ignore-scheduled 'past)
                 (<= (org-days-to-time (match-string 1)) 0))
                 (> (org-days-to-time (match-string 1)) 0))
                ((eq org-agenda-todo-ignore-scheduled 'past)
                 (<= (org-days-to-time (match-string 1)) 0))
+               ((numberp org-agenda-todo-ignore-scheduled)
+                (org-agenda-todo-custom-ignore-p
+                 (match-string 1) org-agenda-todo-ignore-scheduled))
                (t)))
          (and org-agenda-todo-ignore-deadlines
               (re-search-forward org-deadline-time-regexp end t)
                (t)))
          (and org-agenda-todo-ignore-deadlines
               (re-search-forward org-deadline-time-regexp end t)
@@ -4525,6 +4727,9 @@ the documentation of `org-diary'."
                 (> (org-days-to-time (match-string 1)) 0))
                ((eq org-agenda-todo-ignore-deadlines 'past)
                 (<= (org-days-to-time (match-string 1)) 0))
                 (> (org-days-to-time (match-string 1)) 0))
                ((eq org-agenda-todo-ignore-deadlines 'past)
                 (<= (org-days-to-time (match-string 1)) 0))
+               ((numberp org-agenda-todo-ignore-deadlines)
+                (org-agenda-todo-custom-ignore-p
+                 (match-string 1) org-agenda-todo-ignore-deadlines))
                (t (org-deadline-close (match-string 1)))))
          (and org-agenda-todo-ignore-timestamp
               (let ((buffer (current-buffer))
                (t (org-deadline-close (match-string 1)))))
          (and org-agenda-todo-ignore-timestamp
               (let ((buffer (current-buffer))
@@ -4547,6 +4752,9 @@ the documentation of `org-diary'."
                       (> (org-days-to-time (match-string 1)) 0))
                      ((eq org-agenda-todo-ignore-timestamp 'past)
                       (<= (org-days-to-time (match-string 1)) 0))
                       (> (org-days-to-time (match-string 1)) 0))
                      ((eq org-agenda-todo-ignore-timestamp 'past)
                       (<= (org-days-to-time (match-string 1)) 0))
+                     ((numberp org-agenda-todo-ignore-timestamp)
+                      (org-agenda-todo-custom-ignore-p
+                       (match-string 1) org-agenda-todo-ignore-timestamp))
                      (t))))))))))
 
 (defconst org-agenda-no-heading-message
                      (t))))))))))
 
 (defconst org-agenda-no-heading-message
@@ -4554,7 +4762,7 @@ the documentation of `org-diary'."
 
 (defun org-agenda-get-timestamps ()
   "Return the date stamp information for agenda display."
 
 (defun org-agenda-get-timestamps ()
   "Return the date stamp information for agenda display."
-  (let* ((props (list 'face nil
+  (let* ((props (list 'face 'org-agenda-calendar-event
                      'org-not-done-regexp org-not-done-regexp
                      'org-todo-regexp org-todo-regexp
                      'org-complex-heading-regexp org-complex-heading-regexp
                      'org-not-done-regexp org-not-done-regexp
                      'org-todo-regexp org-todo-regexp
                      'org-complex-heading-regexp org-complex-heading-regexp
@@ -4583,19 +4791,23 @@ the documentation of `org-diary'."
           "\\|\\(<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[dwmy]>\\)"
           "\\|\\(<%%\\(([^>\n]+)\\)>\\)"))
         marker hdmarker deadlinep scheduledp clockp closedp inactivep
           "\\|\\(<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[dwmy]>\\)"
           "\\|\\(<%%\\(([^>\n]+)\\)>\\)"))
         marker hdmarker deadlinep scheduledp clockp closedp inactivep
-        donep tmp priority category ee txt timestr tags b0 b3 e3 head
-        todo-state end-of-match)
+        donep tmp priority category org-category-pos ee txt timestr tags
+        b0 b3 e3 head todo-state end-of-match show-all)
     (goto-char (point-min))
     (while (setq end-of-match (re-search-forward regexp nil t))
       (setq b0 (match-beginning 0)
     (goto-char (point-min))
     (while (setq end-of-match (re-search-forward regexp nil t))
       (setq b0 (match-beginning 0)
-           b3 (match-beginning 3) e3 (match-end 3))
+           b3 (match-beginning 3) e3 (match-end 3)
+           todo-state (save-match-data (ignore-errors (org-get-todo-state)))
+           show-all (or (eq org-agenda-repeating-timestamp-show-all t)
+                        (member todo-state
+                                org-agenda-repeating-timestamp-show-all)))
       (catch :skip
        (and (org-at-date-range-p) (throw :skip nil))
        (org-agenda-skip)
        (if (and (match-end 1)
                 (not (= d1 (org-time-string-to-absolute
       (catch :skip
        (and (org-at-date-range-p) (throw :skip nil))
        (org-agenda-skip)
        (if (and (match-end 1)
                 (not (= d1 (org-time-string-to-absolute
-                            (match-string 1) d1 nil
-                            org-agenda-repeating-timestamp-show-all))))
+                            (match-string 1) d1 nil show-all
+                            (current-buffer) b0))))
            (throw :skip nil))
        (if (and e3
                 (not (org-diary-sexp-entry (buffer-substring b3 e3) "" date)))
            (throw :skip nil))
        (if (and e3
                 (not (org-diary-sexp-entry (buffer-substring b3 e3) "" date)))
@@ -4612,7 +4824,6 @@ the documentation of `org-diary'."
              clockp (and org-agenda-include-inactive-timestamps
                          (or (string-match org-clock-string tmp)
                              (string-match "]-+\\'" tmp)))
              clockp (and org-agenda-include-inactive-timestamps
                          (or (string-match org-clock-string tmp)
                              (string-match "]-+\\'" tmp)))
-             todo-state (ignore-errors (org-get-todo-state))
              donep (member todo-state org-done-keywords))
        (if (or scheduledp deadlinep closedp clockp
                (and donep org-agenda-skip-timestamp-if-done))
              donep (member todo-state org-done-keywords))
        (if (or scheduledp deadlinep closedp clockp
                (and donep org-agenda-skip-timestamp-if-done))
@@ -4621,24 +4832,26 @@ the documentation of `org-diary'."
            ;; substring should only run to end of time stamp
            (setq timestr (substring timestr 0 (match-end 0))))
        (setq marker (org-agenda-new-marker b0)
            ;; substring should only run to end of time stamp
            (setq timestr (substring timestr 0 (match-end 0))))
        (setq marker (org-agenda-new-marker b0)
-             category (org-get-category b0))
+             category (org-get-category b0)
+             org-category-pos (get-text-property b0 'org-category-position))
        (save-excursion
        (save-excursion
-         (if (not (re-search-backward "^\\*+ " nil t))
+         (if (not (re-search-backward org-outline-regexp-bol nil t))
              (setq txt org-agenda-no-heading-message)
            (goto-char (match-beginning 0))
            (setq hdmarker (org-agenda-new-marker)
                  tags (org-get-tags-at))
            (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
              (setq txt org-agenda-no-heading-message)
            (goto-char (match-beginning 0))
            (setq hdmarker (org-agenda-new-marker)
                  tags (org-get-tags-at))
            (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
-           (setq head (match-string 1))
-           (setq txt (org-format-agenda-item
+           (setq head (or (match-string 1) ""))
+           (setq txt (org-agenda-format-item
                       (if inactivep org-agenda-inactive-leader nil)
                       (if inactivep org-agenda-inactive-leader nil)
-                      head category tags timestr nil
+                      head category tags timestr
                       remove-re)))
          (setq priority (org-get-priority txt))
          (org-add-props txt props
            'org-marker marker 'org-hd-marker hdmarker)
          (org-add-props txt nil 'priority priority
                         'org-category category 'date date
                       remove-re)))
          (setq priority (org-get-priority txt))
          (org-add-props txt props
            'org-marker marker 'org-hd-marker hdmarker)
          (org-add-props txt nil 'priority priority
                         'org-category category 'date date
+                        'org-category-position org-category-pos
                         'todo-state todo-state
                         'type "timestamp")
          (push txt ee))
                         'todo-state todo-state
                         'type "timestamp")
          (push txt ee))
@@ -4650,14 +4863,14 @@ the documentation of `org-diary'."
 (defun org-agenda-get-sexps ()
   "Return the sexp information for agenda display."
   (require 'diary-lib)
 (defun org-agenda-get-sexps ()
   "Return the sexp information for agenda display."
   (require 'diary-lib)
-  (let* ((props (list 'face nil
+  (let* ((props (list 'face 'org-agenda-calendar-sexp
                      'mouse-face 'highlight
                      'help-echo
                      (format "mouse-2 or RET jump to org file %s"
                              (abbreviate-file-name buffer-file-name))))
         (regexp "^&?%%(")
                      'mouse-face 'highlight
                      'help-echo
                      (format "mouse-2 or RET jump to org file %s"
                              (abbreviate-file-name buffer-file-name))))
         (regexp "^&?%%(")
-        marker category ee txt tags entry result beg b sexp sexp-entry
-        todo-state)
+        marker category org-category-pos ee txt tags entry
+        result beg b sexp sexp-entry todo-state)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
@@ -4674,6 +4887,7 @@ the documentation of `org-diary'."
        (when result
          (setq marker (org-agenda-new-marker beg)
                category (org-get-category beg)
        (when result
          (setq marker (org-agenda-new-marker beg)
                category (org-get-category beg)
+               org-category-pos (get-text-property beg 'org-category-position)
                todo-state (org-get-todo-state))
 
          (dolist (r (if (stringp result)
                todo-state (org-get-todo-state))
 
          (dolist (r (if (stringp result)
@@ -4683,28 +4897,53 @@ the documentation of `org-diary'."
                (setq txt r)
              (setq txt "SEXP entry returned empty string"))
 
                (setq txt r)
              (setq txt "SEXP entry returned empty string"))
 
-           (setq txt (org-format-agenda-item
+           (setq txt (org-agenda-format-item
                       "" txt category tags 'time))
            (org-add-props txt props 'org-marker marker)
            (org-add-props txt nil
              'org-category category 'date date 'todo-state todo-state
                       "" txt category tags 'time))
            (org-add-props txt props 'org-marker marker)
            (org-add-props txt nil
              'org-category category 'date date 'todo-state todo-state
+             'org-category-position org-category-pos
              'type "sexp")
            (push txt ee)))))
     (nreverse ee)))
 
              'type "sexp")
            (push txt ee)))))
     (nreverse ee)))
 
-(defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks)
+;; Calendar sanity: define some functions that are independent of
+;; `calendar-date-style'.
+;; Normally I would like to use ISO format when calling the diary functions,
+;; but to make sure we still have Emacs 22 compatibility we bind
+;; also `european-calendar-style' and use european format
+(defun org-anniversary (year month day &optional mark)
+  "Like `diary-anniversary', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european) (european-calendar-style t))
+     (diary-anniversary day month year mark))))
+(defun org-cyclic (N year month day &optional mark)
+  "Like `diary-cyclic', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)       (european-calendar-style t))
+     (diary-cyclic N day month year mark))))
+(defun org-block (Y1 M1 D1 Y2 M2 D2 &optional mark)
+  "Like `diary-block', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)       (european-calendar-style t))
+     (diary-block D1 M1 Y1 D2 M2 Y2 mark))))
+(defun org-date (year month day &optional mark)
+  "Like `diary-date', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)       (european-calendar-style t))
+     (diary-date day month year mark))))
+(defalias 'org-float 'diary-float)
+
+;; Define the` org-class' function
+(defun org-class (y1 m1 d1 y2 m2 d2 dayname &rest skip-weeks)
   "Entry applies if date is between dates on DAYNAME, but skips SKIP-WEEKS.
   "Entry applies if date is between dates on DAYNAME, but skips SKIP-WEEKS.
-The order of the first 2 times 3 arguments depends on the variable
-`calendar-date-style' or, if that is not defined, on `european-calendar-style'.
-So for American calendars, give this as MONTH DAY YEAR, for European as
-DAY MONTH YEAR, and for ISO as YEAR MONTH DAY.
-DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
-is any number of ISO weeks in the block period for which the item should
-be skipped."
-  (let* ((date1 (calendar-absolute-from-gregorian
-                (org-order-calendar-date-args m1 d1 y1)))
-        (date2 (calendar-absolute-from-gregorian
-                (org-order-calendar-date-args m2 d2 y2)))
+DAYNAME is a number between 0 (Sunday) and 6 (Saturday).
+SKIP-WEEKS is any number of ISO weeks in the block period for which the
+item should be skipped.  If any of the SKIP-WEEKS arguments is the symbol
+`holidays', then any date that is known by the Emacs calendar to be a
+holiday will also be skipped."
+  (let* ((date1 (calendar-absolute-from-gregorian (list m1 d1 y1)))
+        (date2 (calendar-absolute-from-gregorian (list m2 d2 y2)))
         (d (calendar-absolute-from-gregorian date)))
     (and
      (<= date1 d)
         (d (calendar-absolute-from-gregorian date)))
     (and
      (<= date1 d)
@@ -4714,8 +4953,30 @@ be skipped."
         (progn
           (require 'cal-iso)
           (not (member (car (calendar-iso-from-absolute d)) skip-weeks))))
         (progn
           (require 'cal-iso)
           (not (member (car (calendar-iso-from-absolute d)) skip-weeks))))
+     (not (and (memq 'holidays skip-weeks)
+              (calendar-check-holidays date)))
      entry)))
 
      entry)))
 
+(defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks)
+  "Like `org-class', but honor `calendar-date-style'.
+The order of the first 2 times 3 arguments depends on the variable
+`calendar-date-style' or, if that is not defined, on `european-calendar-style'.
+So for American calendars, give this as MONTH DAY YEAR, for European as
+DAY MONTH YEAR, and for ISO as YEAR MONTH DAY.
+DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
+is any number of ISO weeks in the block period for which the item should
+be skipped.
+
+This function is here only for backward compatibility and it is deprecated,
+please use `org-class' instead."
+  (let* ((date1 (org-order-calendar-date-args m1 d1 y1))
+        (date2 (org-order-calendar-date-args m2 d2 y2)))
+    (org-class
+     (nth 2 date1) (car date1) (nth 1 date1)
+     (nth 2 date2) (car date2) (nth 1 date2)
+     dayname skip-weeks)))
+(make-obsolete 'org-diary-class 'org-class "")
+
 (defalias 'org-get-closed 'org-agenda-get-progress)
 (defun org-agenda-get-progress ()
   "Return the logged TODO entries for agenda display."
 (defalias 'org-get-closed 'org-agenda-get-progress)
 (defun org-agenda-get-progress ()
   "Return the logged TODO entries for agenda display."
@@ -4728,7 +4989,9 @@ be skipped."
                              (abbreviate-file-name buffer-file-name))))
         (items (if (consp org-agenda-show-log)
                    org-agenda-show-log
                              (abbreviate-file-name buffer-file-name))))
         (items (if (consp org-agenda-show-log)
                    org-agenda-show-log
-                 org-agenda-log-mode-items))
+                 (if (eq org-agenda-show-log 'clockcheck)
+                     '(clock)
+                   org-agenda-log-mode-items)))
         (parts
          (delq nil
                (list
         (parts
          (delq nil
                (list
@@ -4748,8 +5011,8 @@ be skipped."
                            (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
                    1 11))))
         (org-agenda-search-headline-for-time nil)
                            (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
                    1 11))))
         (org-agenda-search-headline-for-time nil)
-        marker hdmarker priority category tags closedp statep clockp state
-        ee txt extra timestr rest clocked)
+        marker hdmarker priority category org-category-pos tags closedp
+        statep clockp state ee txt extra timestr rest clocked)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
@@ -4760,29 +5023,30 @@ be skipped."
              clockp (not (or closedp statep))
              state (and statep (match-string 2))
              category (org-get-category (match-beginning 0))
              clockp (not (or closedp statep))
              state (and statep (match-string 2))
              category (org-get-category (match-beginning 0))
-             timestr (buffer-substring (match-beginning 0) (point-at-eol))
-             )
+             org-category-pos (get-text-property (match-beginning 0) 'org-category-position)
+             timestr (buffer-substring (match-beginning 0) (point-at-eol)))
        (when (string-match "\\]" timestr)
          ;; substring should only run to end of time stamp
          (setq rest (substring timestr (match-end 0))
                timestr (substring timestr 0 (match-end 0)))
          (if (and (not closedp) (not statep)
        (when (string-match "\\]" timestr)
          ;; substring should only run to end of time stamp
          (setq rest (substring timestr (match-end 0))
                timestr (substring timestr 0 (match-end 0)))
          (if (and (not closedp) (not statep)
-                  (string-match "\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)\\].*?\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)" rest))
+                  (string-match "\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)\\].*?\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)"
+                                rest))
              (progn (setq timestr (concat (substring timestr 0 -1)
                                           "-" (match-string 1 rest) "]"))
                     (setq clocked (match-string 2 rest)))
            (setq clocked "-")))
        (save-excursion
              (progn (setq timestr (concat (substring timestr 0 -1)
                                           "-" (match-string 1 rest) "]"))
                     (setq clocked (match-string 2 rest)))
            (setq clocked "-")))
        (save-excursion
-         (setq extra nil)
-         (cond
-          ((not org-agenda-log-mode-add-notes))
-          (statep
-           (and (looking-at ".*\n[ \t]*\\([^-\n \t].*?\\)[ \t]*$")
-                (setq extra (match-string 1))))
-          (clockp
-           (and (looking-at ".*\n[ \t]*-[ \t]+\\([^-\n \t].*?\\)[ \t]*$")
-                (setq extra (match-string 1)))))
-         (if (not (re-search-backward "^\\*+ " nil t))
+         (setq extra
+               (cond
+                ((not org-agenda-log-mode-add-notes) nil)
+                (statep
+                 (and (looking-at ".*\\\\\n[ \t]*\\([^-\n \t].*?\\)[ \t]*$")
+                      (match-string 1)))
+                (clockp
+                 (and (looking-at ".*\n[ \t]*-[ \t]+\\([^-\n \t].*?\\)[ \t]*$")
+                      (match-string 1)))))
+         (if (not (re-search-backward org-outline-regexp-bol nil t))
              (setq txt org-agenda-no-heading-message)
            (goto-char (match-beginning 0))
            (setq hdmarker (org-agenda-new-marker)
              (setq txt org-agenda-no-heading-message)
            (goto-char (match-beginning 0))
            (setq hdmarker (org-agenda-new-marker)
@@ -4794,7 +5058,7 @@ be skipped."
                  (setq txt (concat (substring txt 0 (match-beginning 1))
                                    " - " extra " " (match-string 2 txt)))
                (setq txt (concat txt " - " extra))))
                  (setq txt (concat (substring txt 0 (match-beginning 1))
                                    " - " extra " " (match-string 2 txt)))
                (setq txt (concat txt " - " extra))))
-           (setq txt (org-format-agenda-item
+           (setq txt (org-agenda-format-item
                       (cond
                        (closedp "Closed:    ")
                            (statep (concat "State:     (" state ")"))
                       (cond
                        (closedp "Closed:    ")
                            (statep (concat "State:     (" state ")"))
@@ -4804,12 +5068,132 @@ be skipped."
          (org-add-props txt props
            'org-marker marker 'org-hd-marker hdmarker 'face 'org-agenda-done
            'priority priority 'org-category category
          (org-add-props txt props
            'org-marker marker 'org-hd-marker hdmarker 'face 'org-agenda-done
            'priority priority 'org-category category
+           'org-category-position org-category-pos
            'type "closed" 'date date
            'undone-face 'org-warning 'done-face 'org-agenda-done)
          (push txt ee))
        (goto-char (point-at-eol))))
     (nreverse ee)))
 
            'type "closed" 'date date
            'undone-face 'org-warning 'done-face 'org-agenda-done)
          (push txt ee))
        (goto-char (point-at-eol))))
     (nreverse ee)))
 
+(defun org-agenda-show-clocking-issues ()
+  "Add overlays, showing issues with clocking.
+See also the user option `org-agenda-clock-consistency-checks'."
+  (interactive)
+  (let* ((pl org-agenda-clock-consistency-checks)
+        (re (concat "^[ \t]*"
+                    org-clock-string
+                    "[ \t]+"
+                    "\\(\\[.*?\\]\\)" ; group 1 is first stamp
+                    "\\(-\\{1,3\\}\\(\\[.*?\\]\\)\\)?")) ; group 3 is second
+        (tlstart 0.)
+        (tlend 0.)
+        (maxtime (org-hh:mm-string-to-minutes
+                  (or (plist-get pl :max-duration) "24:00")))
+        (mintime (org-hh:mm-string-to-minutes
+                  (or (plist-get pl :min-duration) 0)))
+        (maxgap  (org-hh:mm-string-to-minutes
+                  ;; default 30:00 means never complain
+                  (or (plist-get pl :max-gap) "30:00")))
+        (gapok (mapcar 'org-hh:mm-string-to-minutes
+                       (plist-get pl :gap-ok-around)))
+        (def-face (or (plist-get pl :default-face)
+                      '((:background "DarkRed") (:foreground "white"))))
+        issue face m te ts dt ov)
+    (goto-char (point-min))
+    (while (re-search-forward " Clocked: +(-\\|\\([0-9]+:[0-9]+\\))" nil t)
+      (setq issue nil face def-face)
+      (catch 'next
+       (setq m (org-get-at-bol 'org-marker)
+             te nil ts nil)
+       (unless (and m (markerp m))
+         (setq issue "No valid clock line") (throw 'next t))
+       (org-with-point-at m
+         (save-excursion
+           (goto-char (point-at-bol))
+           (unless (looking-at re)
+             (error "No valid Clock line")
+             (throw 'next t))
+           (unless (match-end 3)
+             (setq issue "No end time"
+                   face (or (plist-get pl :no-end-time-face) face))
+             (throw 'next t))
+           (setq ts (match-string 1)
+                 te (match-string 3)
+                 ts (org-float-time
+                     (apply 'encode-time (org-parse-time-string ts)))
+                 te (org-float-time
+                     (apply 'encode-time (org-parse-time-string te)))
+                 dt (- te ts))))
+       (cond
+        ((> dt (* 60 maxtime))
+         ;; a very long clocking chunk
+         (setq issue (format "Clocking interval is very long: %s"
+                             (org-minutes-to-hh:mm-string
+                              (floor (/ (float dt) 60.))))
+               face (or (plist-get pl :long-face) face)))
+        ((< dt (* 60 mintime))
+         ;; a very short clocking chunk
+         (setq issue (format "Clocking interval is very short: %s"
+                             (org-minutes-to-hh:mm-string
+                              (floor (/ (float dt) 60.))))
+               face (or (plist-get pl :short-face) face)))
+        ((and (> tlend 0) (< ts tlend))
+         ;; Two clock entries are overlapping
+         (setq issue (format "Clocking overlap: %d minutes"
+                             (/ (- tlend ts) 60))
+               face (or (plist-get pl :overlap-face) face)))
+        ((and (> tlend 0) (> ts (+ tlend (* 60 maxgap))))
+         ;; There is a gap, lets see if we need to report it
+         (unless (org-agenda-check-clock-gap tlend ts gapok)
+           (setq issue (format "Clocking gap: %d minutes"
+                                 (/ (- ts tlend) 60))
+                 face (or (plist-get pl :gap-face) face))))
+        (t nil)))
+      (setq tlend (or te tlend) tlstart (or ts tlstart))
+      (when issue
+       ;; OK, there was some issue, add an overlay to show the issue
+       (setq ov (make-overlay (point-at-bol) (point-at-eol)))
+       (overlay-put ov 'before-string
+                    (concat
+                     (org-add-props
+                         (format "%-43s" (concat " " issue))
+                         nil
+                       'face face)
+                     "\n"))
+       (overlay-put ov 'evaporate t)))))
+
+(defun org-agenda-check-clock-gap (t1 t2 ok-list)
+  "Check if gap T1 -> T2 contains one of the OK-LIST time-of-day values."
+  (catch 'exit
+    (unless ok-list
+      ;; there are no OK times for gaps...
+      (throw 'exit nil))
+    (if (> (- (/ t2 36000) (/ t1 36000)) 24)
+       ;; This is more than 24 hours, so it is OK.
+       ;; because we have at least one OK time, that must be in the
+       ;; 24 hour interval.
+       (throw 'exit t))
+    ;; We have a shorter gap.
+    ;; Now we have to get the minute of the day when these times are
+    (let* ((t1dec (decode-time (seconds-to-time t1)))
+          (t2dec (decode-time (seconds-to-time t2)))
+          ;; compute the minute on the day
+          (min1 (+ (nth 1 t1dec) (* 60 (nth 2 t1dec))))
+          (min2 (+ (nth 1 t2dec) (* 60 (nth 2 t2dec)))))
+      (when (< min2 min1)
+       ;; if min2 is smaller than min1, this means it is on the next day.
+       ;; Wrap it to after midnight.
+       (setq min2 (+ min2 1440)))
+      ;; Now check if any of the OK times is in the gap
+      (mapc (lambda (x)
+             ;; Wrap the time to after midnight if necessary
+             (if (< x min1) (setq x (+ x 1440)))
+             ;; Check if in interval
+             (and (<= min1 x) (>= min2 x) (throw 'exit t)))
+           ok-list)
+      ;; Nope, this gap is not OK
+      nil)))
+
 (defun org-agenda-get-deadlines ()
   "Return the deadline information for agenda display."
   (let* ((props (list 'mouse-face 'highlight
 (defun org-agenda-get-deadlines ()
   "Return the deadline information for agenda display."
   (let* ((props (list 'mouse-face 'highlight
@@ -4822,9 +5206,9 @@ be skipped."
         (regexp org-deadline-time-regexp)
         (todayp (org-agenda-todayp date)) ; DATE bound by calendar
         (d1 (calendar-absolute-from-gregorian date))  ; DATE bound by calendar
         (regexp org-deadline-time-regexp)
         (todayp (org-agenda-todayp date)) ; DATE bound by calendar
         (d1 (calendar-absolute-from-gregorian date))  ; DATE bound by calendar
-        d2 diff dfrac wdays pos pos1 category tags
-        suppress-prewarning
-        ee txt head face s todo-state upcomingp donep timestr)
+        d2 diff dfrac wdays pos pos1 category org-category-pos
+        tags suppress-prewarning ee txt head face s todo-state
+        show-all upcomingp donep timestr)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (setq suppress-prewarning nil)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (setq suppress-prewarning nil)
@@ -4842,15 +5226,19 @@ be skipped."
        (setq s (match-string 1)
              txt nil
              pos (1- (match-beginning 1))
        (setq s (match-string 1)
              txt nil
              pos (1- (match-beginning 1))
+             todo-state (save-match-data (org-get-todo-state))
+             show-all (or (eq org-agenda-repeating-timestamp-show-all t)
+                          (member todo-state
+                                   org-agenda-repeating-timestamp-show-all))
              d2 (org-time-string-to-absolute
              d2 (org-time-string-to-absolute
-                 (match-string 1) d1 'past
-                 org-agenda-repeating-timestamp-show-all)
+                 (match-string 1) d1 'past show-all
+                 (current-buffer) pos)
              diff (- d2 d1)
              wdays (if suppress-prewarning
                        (let ((org-deadline-warning-days suppress-prewarning))
                          (org-get-wdays s))
                      (org-get-wdays s))
              diff (- d2 d1)
              wdays (if suppress-prewarning
                        (let ((org-deadline-warning-days suppress-prewarning))
                          (org-get-wdays s))
                      (org-get-wdays s))
-             dfrac (/ (* 1.0 (- wdays diff)) (max wdays 1))
+             dfrac (- 1 (/ (* 1.0 diff) (max wdays 1)))
              upcomingp (and todayp (> diff 0)))
        ;; When to show a deadline in the calendar:
        ;; If the expiration is within wdays warning time.
              upcomingp (and todayp (> diff 0)))
        ;; When to show a deadline in the calendar:
        ;; If the expiration is within wdays warning time.
@@ -4859,13 +5247,14 @@ be skipped."
                          (and todayp (not org-agenda-only-exact-dates)))
                     (= diff 0)))
            (save-excursion
                          (and todayp (not org-agenda-only-exact-dates)))
                     (= diff 0)))
            (save-excursion
-             (setq todo-state (org-get-todo-state))
+             ;; (setq todo-state (org-get-todo-state))
              (setq donep (member todo-state org-done-keywords))
              (if (and donep
                       (or org-agenda-skip-deadline-if-done
                           (not (= diff 0))))
                  (setq txt nil)
              (setq donep (member todo-state org-done-keywords))
              (if (and donep
                       (or org-agenda-skip-deadline-if-done
                           (not (= diff 0))))
                  (setq txt nil)
-               (setq category (org-get-category))
+               (setq category (org-get-category)
+                     org-category-pos (get-text-property (point) 'org-category-position))
                (if (not (re-search-backward "^\\*+[ \t]+" nil t))
                    (setq txt org-agenda-no-heading-message)
                  (goto-char (match-end 0))
                (if (not (re-search-backward "^\\*+[ \t]+" nil t))
                    (setq txt org-agenda-no-heading-message)
                  (goto-char (match-end 0))
@@ -4879,7 +5268,7 @@ be skipped."
                      (setq timestr
                            (concat (substring s (match-beginning 1)) " "))
                    (setq timestr 'time))
                      (setq timestr
                            (concat (substring s (match-beginning 1)) " "))
                    (setq timestr 'time))
-                 (setq txt (org-format-agenda-item
+                 (setq txt (org-agenda-format-item
                             (if (= diff 0)
                                 (car org-agenda-deadline-leaders)
                               (if (functionp
                             (if (= diff 0)
                                 (car org-agenda-deadline-leaders)
                               (if (functionp
@@ -4892,13 +5281,14 @@ be skipped."
                             head category tags
                             (if (not (= diff 0)) nil timestr)))))
              (when txt
                             head category tags
                             (if (not (= diff 0)) nil timestr)))))
              (when txt
-               (setq face (org-agenda-deadline-face dfrac wdays))
+               (setq face (org-agenda-deadline-face dfrac))
                (org-add-props txt props
                  'org-marker (org-agenda-new-marker pos)
                  'org-hd-marker (org-agenda-new-marker pos1)
                  'priority (+ (- diff)
                               (org-get-priority txt))
                  'org-category category
                (org-add-props txt props
                  'org-marker (org-agenda-new-marker pos)
                  'org-hd-marker (org-agenda-new-marker pos1)
                  'priority (+ (- diff)
                               (org-get-priority txt))
                  'org-category category
+                 'org-category-position org-category-pos
                  'todo-state todo-state
                  'type (if upcomingp "upcoming-deadline" "deadline")
                  'date (if upcomingp date d2)
                  'todo-state todo-state
                  'type (if upcomingp "upcoming-deadline" "deadline")
                  'date (if upcomingp date d2)
@@ -4907,10 +5297,9 @@ be skipped."
                (push txt ee))))))
     (nreverse ee)))
 
                (push txt ee))))))
     (nreverse ee)))
 
-(defun org-agenda-deadline-face (fraction &optional wdays)
+(defun org-agenda-deadline-face (fraction)
   "Return the face to displaying a deadline item.
 FRACTION is what fraction of the head-warning time has passed."
   "Return the face to displaying a deadline item.
 FRACTION is what fraction of the head-warning time has passed."
-  (if (equal wdays 0) (setq fraction 1.))
   (let ((faces org-agenda-deadline-faces) f)
     (catch 'exit
       (while (setq f (pop faces))
   (let ((faces org-agenda-deadline-faces) f)
     (catch 'exit
       (while (setq f (pop faces))
@@ -4935,8 +5324,8 @@ FRACTION is what fraction of the head-warning time has passed."
                                        0 'org-hd-marker a))
                              (cons (marker-position mm) a)))
                  deadline-results))
                                        0 'org-hd-marker a))
                              (cons (marker-position mm) a)))
                  deadline-results))
-        d2 diff pos pos1 category tags donep
-        ee txt head pastschedp todo-state face timestr s habitp)
+        d2 diff pos pos1 category org-category-pos tags donep
+        ee txt head pastschedp todo-state face timestr s habitp show-all)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
@@ -4944,9 +5333,13 @@ FRACTION is what fraction of the head-warning time has passed."
        (setq s (match-string 1)
              txt nil
              pos (1- (match-beginning 1))
        (setq s (match-string 1)
              txt nil
              pos (1- (match-beginning 1))
+             todo-state (save-match-data (org-get-todo-state))
+             show-all (or (eq org-agenda-repeating-timestamp-show-all t)
+                          (member todo-state
+                                  org-agenda-repeating-timestamp-show-all))
              d2 (org-time-string-to-absolute
              d2 (org-time-string-to-absolute
-                 (match-string 1) d1 'past
-                 org-agenda-repeating-timestamp-show-all)
+                 (match-string 1) d1 'past show-all
+                 (current-buffer) pos)
              diff (- d2 d1))
        (setq pastschedp (and todayp (< diff 0)))
        ;; When to show a scheduled item in the calendar:
              diff (- d2 d1))
        (setq pastschedp (and todayp (< diff 0)))
        ;; When to show a scheduled item in the calendar:
@@ -4956,15 +5349,17 @@ FRACTION is what fraction of the head-warning time has passed."
                       (and todayp (not org-agenda-only-exact-dates)))
                  (= diff 0))
          (save-excursion
                       (and todayp (not org-agenda-only-exact-dates)))
                  (= diff 0))
          (save-excursion
-           (setq todo-state (org-get-todo-state))
            (setq donep (member todo-state org-done-keywords))
            (setq donep (member todo-state org-done-keywords))
-           (setq habitp (and (functionp 'org-is-habit-p)
-                             (org-is-habit-p)))
            (if (and donep
            (if (and donep
-                    (or habitp org-agenda-skip-scheduled-if-done
-                        (not (= diff 0))))
+                    (or org-agenda-skip-scheduled-if-done
+                        (not (= diff 0))
+                        (and (functionp 'org-is-habit-p)
+                             (org-is-habit-p))))
                (setq txt nil)
                (setq txt nil)
-             (setq category (org-get-category))
+             (setq habitp (and (functionp 'org-is-habit-p)
+                               (org-is-habit-p)))
+             (setq category (org-get-category)
+                   org-category-pos (get-text-property (point) 'org-category-position))
              (if (not (re-search-backward "^\\*+[ \t]+" nil t))
                  (setq txt org-agenda-no-heading-message)
                (goto-char (match-end 0))
              (if (not (re-search-backward "^\\*+[ \t]+" nil t))
                  (setq txt org-agenda-no-heading-message)
                (goto-char (match-end 0))
@@ -4988,14 +5383,14 @@ FRACTION is what fraction of the head-warning time has passed."
                    (setq timestr
                          (concat (substring s (match-beginning 1)) " "))
                  (setq timestr 'time))
                    (setq timestr
                          (concat (substring s (match-beginning 1)) " "))
                  (setq timestr 'time))
-               (setq txt (org-format-agenda-item
+               (setq txt (org-agenda-format-item
                           (if (= diff 0)
                               (car org-agenda-scheduled-leaders)
                             (format (nth 1 org-agenda-scheduled-leaders)
                                     (- 1 diff)))
                           head category tags
                           (if (not (= diff 0)) nil timestr)
                           (if (= diff 0)
                               (car org-agenda-scheduled-leaders)
                             (format (nth 1 org-agenda-scheduled-leaders)
                                     (- 1 diff)))
                           head category tags
                           (if (not (= diff 0)) nil timestr)
-                          nil nil habitp))))
+                          nil habitp))))
            (when txt
              (setq face
                    (cond
            (when txt
              (setq face
                    (cond
@@ -5015,6 +5410,7 @@ FRACTION is what fraction of the head-warning time has passed."
                              (org-habit-get-priority habitp)
                            (+ 94 (- 5 diff) (org-get-priority txt)))
                'org-category category
                              (org-habit-get-priority habitp)
                            (+ 94 (- 5 diff) (org-get-priority txt)))
                'org-category category
+               'org-category-position org-category-pos
                'org-habit-p habitp
                'todo-state todo-state)
              (push txt ee))))))
                'org-habit-p habitp
                'todo-state todo-state)
              (push txt ee))))))
@@ -5032,55 +5428,65 @@ FRACTION is what fraction of the head-warning time has passed."
                              (abbreviate-file-name buffer-file-name))))
         (regexp org-tr-regexp)
         (d0 (calendar-absolute-from-gregorian date))
                              (abbreviate-file-name buffer-file-name))))
         (regexp org-tr-regexp)
         (d0 (calendar-absolute-from-gregorian date))
-        marker hdmarker ee txt d1 d2 s1 s2 timestr category todo-state tags pos
-        head donep)
+        marker hdmarker ee txt d1 d2 s1 s2 category org-category-pos
+        todo-state tags pos head donep)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
        (org-agenda-skip)
        (setq pos (point))
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
        (org-agenda-skip)
        (setq pos (point))
-       (setq timestr (match-string 0)
-             s1 (match-string 1)
-             s2 (match-string 2)
-             d1 (time-to-days (org-time-string-to-time s1))
-             d2 (time-to-days (org-time-string-to-time s2)))
-       (if (and (> (- d0 d1) -1) (> (- d2 d0) -1))
-           ;; Only allow days between the limits, because the normal
-           ;; date stamps will catch the limits.
-           (save-excursion
-             (setq todo-state (org-get-todo-state))
-             (setq donep (member todo-state org-done-keywords))
-             (if (and donep org-agenda-skip-timestamp-if-done)
-                 (throw :skip t))
-             (setq marker (org-agenda-new-marker (point)))
-             (setq category (org-get-category))
-             (if (not (re-search-backward "^\\*+ " nil t))
-                 (setq txt org-agenda-no-heading-message)
-               (goto-char (match-beginning 0))
-               (setq hdmarker (org-agenda-new-marker (point)))
-               (setq tags (org-get-tags-at))
-               (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
-               (setq head (match-string 1))
-               (let ((remove-re
-                      (if org-agenda-remove-timeranges-from-blocks
-                          (concat
-                           "<" (regexp-quote s1) ".*?>"
-                           "--"
-                           "<" (regexp-quote s2) ".*?>")
-                        nil)))
-                 (setq txt (org-format-agenda-item
-                            (format
-                             (nth (if (= d1 d2) 0 1)
-                                  org-agenda-timerange-leaders)
-                             (1+ (- d0 d1)) (1+ (- d2 d1)))
-                            head category tags
-                            timestr nil remove-re))))
-             (org-add-props txt props
-               'org-marker marker 'org-hd-marker hdmarker
-               'type "block" 'date date
-               'todo-state todo-state
-               'priority (org-get-priority txt) 'org-category category)
-             (push txt ee)))
+       (let ((start-time (match-string 1))
+             (end-time (match-string 2)))
+         (setq s1 (match-string 1)
+               s2 (match-string 2)
+               d1 (time-to-days (org-time-string-to-time s1 (current-buffer) pos))
+               d2 (time-to-days (org-time-string-to-time s2 (current-buffer) pos)))
+         (if (and (> (- d0 d1) -1) (> (- d2 d0) -1))
+             ;; Only allow days between the limits, because the normal
+             ;; date stamps will catch the limits.
+             (save-excursion
+               (setq todo-state (org-get-todo-state))
+               (setq donep (member todo-state org-done-keywords))
+               (if (and donep org-agenda-skip-timestamp-if-done)
+                   (throw :skip t))
+               (setq marker (org-agenda-new-marker (point)))
+               (setq category (org-get-category)
+                     org-category-pos (get-text-property (point) 'org-category-position))
+               (if (not (re-search-backward org-outline-regexp-bol nil t))
+                   (setq txt org-agenda-no-heading-message)
+                 (goto-char (match-beginning 0))
+                 (setq hdmarker (org-agenda-new-marker (point)))
+                 (setq tags (org-get-tags-at))
+                 (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
+                 (setq head (match-string 1))
+                 (let ((remove-re
+                        (if org-agenda-remove-timeranges-from-blocks
+                            (concat
+                             "<" (regexp-quote s1) ".*?>"
+                             "--"
+                             "<" (regexp-quote s2) ".*?>")
+                          nil)))
+                   (setq txt (org-agenda-format-item
+                              (format
+                               (nth (if (= d1 d2) 0 1)
+                                    org-agenda-timerange-leaders)
+                               (1+ (- d0 d1)) (1+ (- d2 d1)))
+                              head category tags
+                              (cond ((and (= d1 d0) (= d2 d0))
+                                     (concat "<" start-time ">--<" end-time ">"))
+                                     ((= d1 d0)
+                                     (concat "<" start-time ">"))
+                                    ((= d2 d0)
+                                     (concat "<" end-time ">"))
+                                    (t nil))
+                              remove-re))))
+               (org-add-props txt props
+                 'org-marker marker 'org-hd-marker hdmarker
+                 'type "block" 'date date
+                 'todo-state todo-state
+                 'priority (org-get-priority txt) 'org-category category
+                 'org-category-position org-category-pos)
+               (push txt ee))))
        (goto-char pos)))
     ;; Sort the entries by expiration date.
     (nreverse ee)))
        (goto-char pos)))
     ;; Sort the entries by expiration date.
     (nreverse ee)))
@@ -5109,8 +5515,8 @@ The flag is set if the currently compiled format contains a `%e'.")
          (return (cadr entry))
       (return (apply 'create-image (cdr entry)))))))
 
          (return (cadr entry))
       (return (apply 'create-image (cdr entry)))))))
 
-(defun org-format-agenda-item (extra txt &optional category tags dotime
-                                    noprefix remove-re habitp)
+(defun org-agenda-format-item (extra txt &optional category tags dotime
+                                    remove-re habitp)
   "Format TXT to be inserted into the agenda buffer.
 In particular, it adds the prefix and corresponding text properties.  EXTRA
 must be a string and replaces the `%s' specifier in the prefix format.
   "Format TXT to be inserted into the agenda buffer.
 In particular, it adds the prefix and corresponding text properties.  EXTRA
 must be a string and replaces the `%s' specifier in the prefix format.
@@ -5119,9 +5525,7 @@ category taken from local variable or file name.  It will replace the `%c'
 specifier in the format.  DOTIME, when non-nil, indicates that a
 time-of-day should be extracted from TXT for sorting of this entry, and for
 the `%t' specifier in the format.  When DOTIME is a string, this string is
 specifier in the format.  DOTIME, when non-nil, indicates that a
 time-of-day should be extracted from TXT for sorting of this entry, and for
 the `%t' specifier in the format.  When DOTIME is a string, this string is
-searched for a time before TXT is.  NOPREFIX is a flag and indicates that
-only the correctly processes TXT should be returned - this is used by
-`org-agenda-change-all-lines'.  TAGS can be the tags of the headline.
+searched for a time before TXT is.  TAGS can be the tags of the headline.
 Any match of REMOVE-RE will be removed from TXT."
   (save-match-data
     ;; Diary entries sometimes have extra whitespace at the beginning
 Any match of REMOVE-RE will be removed from TXT."
   (save-match-data
     ;; Diary entries sometimes have extra whitespace at the beginning
@@ -5151,9 +5555,9 @@ Any match of REMOVE-RE will be removed from TXT."
                           (if (stringp dotime) dotime "")
                           (and org-agenda-search-headline-for-time txt))))
           (time-of-day (and dotime (org-get-time-of-day ts)))
                           (if (stringp dotime) dotime "")
                           (and org-agenda-search-headline-for-time txt))))
           (time-of-day (and dotime (org-get-time-of-day ts)))
-          stamp plain s0 s1 s2 t1 t2 rtn srp l
+          stamp plain s0 s1 s2 rtn srp l
           duration thecategory)
           duration thecategory)
-      (and (org-mode-p) buffer-file-name
+      (and (eq major-mode 'org-mode) buffer-file-name
           (add-to-list 'org-agenda-contributing-files buffer-file-name))
       (when (and dotime time-of-day)
        ;; Extract starting and ending time and move them to prefix
           (add-to-list 'org-agenda-contributing-files buffer-file-name))
       (when (and dotime time-of-day)
        ;; Extract starting and ending time and move them to prefix
@@ -5178,26 +5582,17 @@ Any match of REMOVE-RE will be removed from TXT."
        ;; Normalize the time(s) to 24 hour
        (if s1 (setq s1 (org-get-time-of-day s1 'string t)))
        (if s2 (setq s2 (org-get-time-of-day s2 'string t)))
        ;; Normalize the time(s) to 24 hour
        (if s1 (setq s1 (org-get-time-of-day s1 'string t)))
        (if s2 (setq s2 (org-get-time-of-day s2 'string t)))
+
+       ;; Try to set s2 if s1 and `org-agenda-default-appointment-duration' are set
+       (when (and s1 (not s2) org-agenda-default-appointment-duration)
+         (setq s2
+               (org-minutes-to-hh:mm-string
+                (+ (org-hh:mm-string-to-minutes s1) org-agenda-default-appointment-duration))))
+
        ;; Compute the duration
        ;; Compute the duration
-       (when s1
-         (setq t1 (+ (* 60 (string-to-number (substring s1 0 2)))
-                     (string-to-number (substring s1 3)))
-               t2 (cond
-                   (s2 (+ (* 60 (string-to-number (substring s2 0 2)))
-                          (string-to-number (substring s2 3))))
-                   (org-agenda-default-appointment-duration
-                    (+ t1 org-agenda-default-appointment-duration))
-                   (t nil)))
-         (setq duration (if t2 (- t2 t1)))))
-
-      (when (and s1 (not s2) org-agenda-default-appointment-duration
-                (string-match "\\([0-9]+\\):\\([0-9]+\\)" s1))
-       (let ((m (+ (string-to-number (match-string 2 s1))
-                   (* 60 (string-to-number (match-string 1 s1)))
-                   org-agenda-default-appointment-duration))
-             h)
-         (setq h (/ m 60) m (- m (* h 60)))
-         (setq s2 (format "%02d:%02d" h m))))
+       (when s2
+         (setq duration (- (org-hh:mm-string-to-minutes s2)
+                           (org-hh:mm-string-to-minutes s1)))))
 
       (when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")
                          txt)
 
       (when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")
                          txt)
@@ -5210,7 +5605,7 @@ Any match of REMOVE-RE will be removed from TXT."
                     (concat (make-string (max (- 50 (length txt)) 1) ?\ )
                             (match-string 2 txt))
                     t t txt))))
                     (concat (make-string (max (- 50 (length txt)) 1) ?\ )
                             (match-string 2 txt))
                     t t txt))))
-      (when (org-mode-p)
+      (when (eq major-mode 'org-mode)
        (setq effort
              (condition-case nil
                  (org-get-effort
        (setq effort
              (condition-case nil
                  (org-get-effort
@@ -5218,45 +5613,48 @@ Any match of REMOVE-RE will be removed from TXT."
                       (get-text-property 0 'org-marker txt)))
                (error nil)))
        (when effort
                       (get-text-property 0 'org-marker txt)))
                (error nil)))
        (when effort
-         (setq neffort (org-hh:mm-string-to-minutes effort)
-               effort (setq effort (concat "[" effort "]" )))))
+         (setq neffort (org-duration-string-to-minutes effort)
+               effort (setq effort (concat "[" effort "]")))))
+      ;; prevent erroring out with %e format when there is no effort
+      (or effort (setq effort ""))
 
       (when remove-re
        (while (string-match remove-re txt)
          (setq txt (replace-match "" t t txt))))
 
 
       (when remove-re
        (while (string-match remove-re txt)
          (setq txt (replace-match "" t t txt))))
 
-      ;; Create the final string
-      (if noprefix
-         (setq rtn txt)
-       ;; Prepare the variables needed in the eval of the compiled format
-       (setq time (cond (s2 (concat
-                             (org-agenda-time-of-day-to-ampm-maybe s1)
-                             "-" (org-agenda-time-of-day-to-ampm-maybe s2)
-                             (if org-agenda-timegrid-use-ampm " ")))
-                        (s1 (concat
-                             (org-agenda-time-of-day-to-ampm-maybe s1)
-                             (if org-agenda-timegrid-use-ampm
-                                 "........ "
-                               "......")))
-                        (t ""))
-             extra (or (and (not habitp) extra) "")
-             category (if (symbolp category) (symbol-name category) category)
-             thecategory (copy-sequence category))
-       (if (string-match org-bracket-link-regexp category)
-           (progn
-             (setq l (if (match-end 3)
-                         (- (match-end 3) (match-beginning 3))
-                       (- (match-end 1) (match-beginning 1))))
-             (when (< l (or org-prefix-category-length 0))
-               (setq category (copy-sequence category))
-               (org-add-props category nil
-                 'extra-space (make-string
-                               (- org-prefix-category-length l 1) ?\ ))))
-         (if (and org-prefix-category-max-length
-                  (>= (length category) org-prefix-category-max-length))
-             (setq category (substring category 0 (1- org-prefix-category-max-length)))))
-       ;; Evaluate the compiled format
-       (setq rtn (concat (eval org-prefix-format-compiled) txt)))
+      ;; Set org-heading property on `txt' to mark the start of the
+      ;; heading.
+      (add-text-properties 0 (length txt) '(org-heading t) txt)
+
+      ;; Prepare the variables needed in the eval of the compiled format
+      (setq time (cond (s2 (concat
+                           (org-agenda-time-of-day-to-ampm-maybe s1)
+                           "-" (org-agenda-time-of-day-to-ampm-maybe s2)
+                           (if org-agenda-timegrid-use-ampm " ")))
+                      (s1 (concat
+                           (org-agenda-time-of-day-to-ampm-maybe s1)
+                           (if org-agenda-timegrid-use-ampm
+                               "........ "
+                             "......")))
+                      (t ""))
+           extra (or (and (not habitp) extra) "")
+           category (if (symbolp category) (symbol-name category) category)
+           thecategory (copy-sequence category))
+      (if (string-match org-bracket-link-regexp category)
+         (progn
+           (setq l (if (match-end 3)
+                       (- (match-end 3) (match-beginning 3))
+                     (- (match-end 1) (match-beginning 1))))
+           (when (< l (or org-prefix-category-length 0))
+             (setq category (copy-sequence category))
+             (org-add-props category nil
+               'extra-space (make-string
+                             (- org-prefix-category-length l 1) ?\ ))))
+       (if (and org-prefix-category-max-length
+                (>= (length category) org-prefix-category-max-length))
+           (setq category (substring category 0 (1- org-prefix-category-max-length)))))
+      ;; Evaluate the compiled format
+      (setq rtn (concat (eval org-prefix-format-compiled) txt))
 
       ;; And finally add the text properties
       (remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn)
 
       ;; And finally add the text properties
       (remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn)
@@ -5265,7 +5663,6 @@ Any match of REMOVE-RE will be removed from TXT."
        'tags (mapcar 'org-downcase-keep-props tags)
        'org-highest-priority org-highest-priority
        'org-lowest-priority org-lowest-priority
        'tags (mapcar 'org-downcase-keep-props tags)
        'org-highest-priority org-highest-priority
        'org-lowest-priority org-lowest-priority
-       'prefix-length (- (length rtn) (length txt))
        'time-of-day time-of-day
        'duration duration
        'effort effort
        'time-of-day time-of-day
        'duration duration
        'effort effort
@@ -5273,6 +5670,7 @@ Any match of REMOVE-RE will be removed from TXT."
        'txt txt
        'time time
        'extra extra
        'txt txt
        'time time
        'extra extra
+       'format org-prefix-format-compiled
        'dotime dotime))))
 
 (defun org-agenda-fix-displayed-tags (txt tags add-inherited hide-re)
        'dotime dotime))))
 
 (defun org-agenda-fix-displayed-tags (txt tags add-inherited hide-re)
@@ -5337,12 +5735,22 @@ The modified list may contain inherited tags, and tags matched by
       (while (setq time (pop gridtimes))
        (unless (and remove (member time have))
          (setq time (replace-regexp-in-string " " "0" (format "%04s" time)))
       (while (setq time (pop gridtimes))
        (unless (and remove (member time have))
          (setq time (replace-regexp-in-string " " "0" (format "%04s" time)))
-         (push (org-format-agenda-item
+         (push (org-agenda-format-item
                 nil string "" nil
                 (concat (substring time 0 -2) ":" (substring time -2)))
                new)
          (put-text-property
           2 (length (car new)) 'face 'org-time-grid (car new))))
                 nil string "" nil
                 (concat (substring time 0 -2) ":" (substring time -2)))
                new)
          (put-text-property
           2 (length (car new)) 'face 'org-time-grid (car new))))
+      (when (and todayp org-agenda-show-current-time-in-grid)
+       (push (org-agenda-format-item
+              nil
+              org-agenda-current-time-string
+              "" nil
+              (format-time-string "%H:%M "))
+             new)
+       (put-text-property
+        2 (length (car new)) 'face 'org-agenda-current-time (car new)))
+
       (if (member 'time-up org-agenda-sorting-strategy-selected)
          (append new list)
        (append list new)))))
       (if (member 'time-up org-agenda-sorting-strategy-selected)
          (append new list)
        (append list new)))))
@@ -5352,7 +5760,8 @@ The modified list may contain inherited tags, and tags matched by
 The resulting form is returned and stored in the variable
 `org-prefix-format-compiled'."
   (setq org-prefix-has-time nil org-prefix-has-tag nil
 The resulting form is returned and stored in the variable
 `org-prefix-format-compiled'."
   (setq org-prefix-has-time nil org-prefix-has-tag nil
-       org-prefix-category-length nil  org-prefix-has-effort nil)
+       org-prefix-category-length nil
+       org-prefix-has-effort nil)
   (let ((s (cond
            ((stringp org-agenda-prefix-format)
             org-agenda-prefix-format)
   (let ((s (cond
            ((stringp org-agenda-prefix-format)
             org-agenda-prefix-format)
@@ -5361,11 +5770,12 @@ The resulting form is returned and stored in the variable
            (t "  %-12:c%?-12t% s")))
        (start 0)
        varform vars var e c f opt)
            (t "  %-12:c%?-12t% s")))
        (start 0)
        varform vars var e c f opt)
-    (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([ctsei]\\)"
+    (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([ctsei]\\|(.+)\\)"
                         s start)
                         s start)
-      (setq var (cdr (assoc (match-string 4 s)
-                           '(("c" . category) ("t" . time) ("s" . extra)
-                             ("i" . category-icon) ("T" . tag) ("e" . effort))))
+      (setq var (or (cdr (assoc (match-string 4 s)
+                               '(("c" . category) ("t" . time) ("s" . extra)
+                                 ("i" . category-icon) ("T" . tag) ("e" . effort))))
+                   'eval)
            c (or (match-string 3 s) "")
            opt (match-beginning 1)
            start (1+ (match-beginning 0)))
            c (or (match-string 3 s) "")
            opt (match-beginning 1)
            start (1+ (match-beginning 0)))
@@ -5381,12 +5791,14 @@ The resulting form is returned and stored in the variable
                (save-match-data
                  (if (string-match "\\.[0-9]+" x)
                      (string-to-number (substring (match-string 0 x) 1)))))))
                (save-match-data
                  (if (string-match "\\.[0-9]+" x)
                      (string-to-number (substring (match-string 0 x) 1)))))))
-      (if opt
-         (setq varform
-               `(if (equal "" ,var)
-                    ""
-                  (format ,f (if (equal "" ,var) "" (concat ,var ,c)))))
-       (setq varform `(format ,f (if (equal ,var "") "" (concat ,var ,c (get-text-property 0 'extra-space ,var))))))
+      (if (eq var 'eval)
+         (setq varform `(format ,f (org-eval ,(read (match-string 4 s)))))
+       (if opt
+           (setq varform
+                 `(if (equal "" ,var)
+                      ""
+                    (format ,f (if (equal "" ,var) "" (concat ,var ,c)))))
+         (setq varform `(format ,f (if (equal ,var "") "" (concat ,var ,c (get-text-property 0 'extra-space ,var)))))))
       (setq s (replace-match "%s" t nil s))
       (push varform vars))
     (setq vars (nreverse vars))
       (setq s (replace-match "%s" t nil s))
       (push varform vars))
     (setq vars (nreverse vars))
@@ -5461,12 +5873,12 @@ could bind the variable in the options section of a custom command.")
 (defun org-agenda-highlight-todo (x)
   (let ((org-done-keywords org-done-keywords-for-agenda)
        (case-fold-search nil)
 (defun org-agenda-highlight-todo (x)
   (let ((org-done-keywords org-done-keywords-for-agenda)
        (case-fold-search nil)
-        re pl)
+       re)
     (if (eq x 'line)
        (save-excursion
          (beginning-of-line 1)
          (setq re (org-get-at-bol 'org-todo-regexp))
     (if (eq x 'line)
        (save-excursion
          (beginning-of-line 1)
          (setq re (org-get-at-bol 'org-todo-regexp))
-         (goto-char (+ (point) (or (org-get-at-bol 'prefix-length) 0)))
+         (goto-char (or (text-property-any (point-at-bol) (point-at-eol) 'org-heading t) (point)))
          (when (looking-at (concat "[ \t]*\\.*\\(" re "\\) +"))
            (add-text-properties (match-beginning 0) (match-end 1)
                                 (list 'face (org-get-todo-face 1)))
          (when (looking-at (concat "[ \t]*\\.*\\(" re "\\) +"))
            (add-text-properties (match-beginning 0) (match-end 1)
                                 (list 'face (org-get-todo-face 1)))
@@ -5474,21 +5886,31 @@ could bind the variable in the options section of a custom command.")
              (delete-region (match-beginning 1) (1- (match-end 0)))
              (goto-char (match-beginning 1))
              (insert (format org-agenda-todo-keyword-format s)))))
              (delete-region (match-beginning 1) (1- (match-end 0)))
              (goto-char (match-beginning 1))
              (insert (format org-agenda-todo-keyword-format s)))))
-      (setq re (concat (get-text-property 0 'org-todo-regexp x))
-           pl (get-text-property 0 'prefix-length x))
-      (when (and re
-                (equal (string-match (concat "\\(\\.*\\)" re "\\( +\\)")
-                                     x (or pl 0)) pl))
-       (add-text-properties
-        (or (match-end 1) (match-end 0)) (match-end 0)
-        (list 'face (org-get-todo-face (match-string 2 x)))
-        x)
-       (when (match-end 1)
-         (setq x (concat (substring x 0 (match-end 1))
-                         (format org-agenda-todo-keyword-format
-                                 (match-string 2 x))
-                         (org-add-props " " (text-properties-at 0 x))
-                         (substring x (match-end 3))))))
+      (let ((pl (text-property-any 0 (length x) 'org-heading t x)))
+       (setq re (get-text-property 0 'org-todo-regexp x))
+       (when (and re
+                  ;; Test `pl' because if there's no heading content,
+                  ;; there's no point matching to highlight.  Note
+                  ;; that if we didn't test `pl' first, and there
+                  ;; happened to be no keyword from `org-todo-regexp'
+                  ;; on this heading line, then the `equal' comparison
+                  ;; afterwards would spuriously succeed in the case
+                  ;; where `pl' is nil -- causing an args-out-of-range
+                  ;; error when we try to add text properties to text
+                  ;; that isn't there.
+                  pl
+                  (equal (string-match (concat "\\(\\.*\\)" re "\\( +\\)")
+                                       x pl) pl))
+         (add-text-properties
+          (or (match-end 1) (match-end 0)) (match-end 0)
+          (list 'face (org-get-todo-face (match-string 2 x)))
+          x)
+         (when (match-end 1)
+           (setq x (concat (substring x 0 (match-end 1))
+                           (format org-agenda-todo-keyword-format
+                                   (match-string 2 x))
+                           (org-add-props " " (text-properties-at 0 x))
+                           (substring x (match-end 3)))))))
       x)))
 
 (defsubst org-cmp-priority (a b)
       x)))
 
 (defsubst org-cmp-priority (a b)
@@ -5500,7 +5922,7 @@ could bind the variable in the options section of a custom command.")
          (t nil))))
 
 (defsubst org-cmp-effort (a b)
          (t nil))))
 
 (defsubst org-cmp-effort (a b)
-  "Compare the priorities of string A and B."
+  "Compare the effort values of string A and B."
   (let* ((def (if org-sort-agenda-noeffort-is-high 32767 -1))
         (ea (or (get-text-property 1 'effort-minutes a) def))
         (eb (or (get-text-property 1 'effort-minutes b) def)))
   (let* ((def (if org-sort-agenda-noeffort-is-high 32767 -1))
         (ea (or (get-text-property 1 'effort-minutes a) def))
         (eb (or (get-text-property 1 'effort-minutes b) def)))
@@ -5541,8 +5963,8 @@ could bind the variable in the options section of a custom command.")
 
 (defsubst org-cmp-alpha (a b)
   "Compare the headlines, alphabetically."
 
 (defsubst org-cmp-alpha (a b)
   "Compare the headlines, alphabetically."
-  (let* ((pla (get-text-property 0 'prefix-length a))
-        (plb (get-text-property 0 'prefix-length b))
+  (let* ((pla (text-property-any 0 (length a) 'org-heading t a))
+        (plb (text-property-any 0 (length b) 'org-heading t b))
         (ta (and pla (substring a pla)))
         (tb (and plb (substring b plb))))
     (when pla
         (ta (and pla (substring a pla)))
         (tb (and plb (substring b plb))))
     (when pla
@@ -5763,29 +6185,46 @@ in the agenda."
 When this is the global TODO list, a prefix argument will be interpreted."
   (interactive)
   (let* ((org-agenda-keep-modes t)
 When this is the global TODO list, a prefix argument will be interpreted."
   (interactive)
   (let* ((org-agenda-keep-modes t)
-        (filter org-agenda-filter)
-        (preset (get 'org-agenda-filter :preset-filter))
-        (org-agenda-filter-while-redo (or filter preset))
+        (tag-filter org-agenda-tag-filter)
+        (tag-preset (get 'org-agenda-tag-filter :preset-filter))
+        (cat-filter org-agenda-category-filter)
+        (cat-preset (get 'org-agenda-category-filter :preset-filter))
+        (org-agenda-tag-filter-while-redo (or tag-filter tag-preset))
         (cols org-agenda-columns-active)
         (line (org-current-line))
         (window-line (- line (org-current-line (window-start))))
         (lprops (get 'org-agenda-redo-command 'org-lprops)))
         (cols org-agenda-columns-active)
         (line (org-current-line))
         (window-line (- line (org-current-line (window-start))))
         (lprops (get 'org-agenda-redo-command 'org-lprops)))
-    (put 'org-agenda-filter :preset-filter nil)
+    (put 'org-agenda-tag-filter :preset-filter nil)
+    (put 'org-agenda-category-filter :preset-filter nil)
     (and cols (org-columns-quit))
     (message "Rebuilding agenda buffer...")
     (org-let lprops '(eval org-agenda-redo-command))
     (setq org-agenda-undo-list nil
          org-agenda-pending-undo-list nil)
     (message "Rebuilding agenda buffer...done")
     (and cols (org-columns-quit))
     (message "Rebuilding agenda buffer...")
     (org-let lprops '(eval org-agenda-redo-command))
     (setq org-agenda-undo-list nil
          org-agenda-pending-undo-list nil)
     (message "Rebuilding agenda buffer...done")
-    (put 'org-agenda-filter :preset-filter preset)
-    (and (or filter preset) (org-agenda-filter-apply filter))
-    (and cols (interactive-p) (org-agenda-columns))
+    (put 'org-agenda-tag-filter :preset-filter tag-preset)
+    (put 'org-agenda-category-filter :preset-filter cat-preset)
+    (and (or tag-filter tag-preset) (org-agenda-filter-apply tag-filter 'tag))
+    (and (or cat-filter cat-preset) (org-agenda-filter-apply cat-filter 'category))
+    (and cols (org-called-interactively-p 'any) (org-agenda-columns))
     (org-goto-line line)
     (recenter window-line)))
 
     (org-goto-line line)
     (recenter window-line)))
 
-
 (defvar org-global-tags-completion-table nil)
 (defvar org-agenda-filter-form nil)
 (defvar org-global-tags-completion-table nil)
 (defvar org-agenda-filter-form nil)
+(defvar org-agenda-filtered-by-category nil)
+
+(defun org-agenda-filter-by-category (strip)
+  "Keep only those lines in the agenda buffer that have a specific category.
+The category is that of the current line."
+  (interactive "P")
+  (if org-agenda-filtered-by-category
+      (org-agenda-filter-show-all-cat)
+    (let ((cat (org-no-properties (get-text-property (point) 'org-category))))
+      (if cat (org-agenda-filter-apply
+              (list (concat (if strip "-" "+") cat)) 'category)
+       (error "No category at point")))))
+
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
   "Keep only those lines in the agenda buffer that have a specific tag.
 The tag is selected with its fast selection letter, as configured.
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
   "Keep only those lines in the agenda buffer that have a specific tag.
 The tag is selected with its fast selection letter, as configured.
@@ -5804,25 +6243,26 @@ to switch to narrowing."
         (efforts (org-split-string
                   (or (cdr (assoc (concat org-effort-property "_ALL")
                                   org-global-properties))
         (efforts (org-split-string
                   (or (cdr (assoc (concat org-effort-property "_ALL")
                                   org-global-properties))
-                      "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00"                  "")))
+                      "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00"
+                      "")))
         (effort-op org-agenda-filter-effort-default-operator)
         (effort-prompt "")
         (inhibit-read-only t)
         (effort-op org-agenda-filter-effort-default-operator)
         (effort-prompt "")
         (inhibit-read-only t)
-        (current org-agenda-filter)
-        a n tag)
+        (current org-agenda-tag-filter)
+        maybe-refresh a n tag)
     (unless char
       (message
        "%s by tag [%s ], [TAB], %s[/]:off, [+-]:narrow, [>=<?]:effort: "
        (if narrow "Narrow" "Filter") tag-chars
        (if org-agenda-auto-exclude-function "[RET], " ""))
     (unless char
       (message
        "%s by tag [%s ], [TAB], %s[/]:off, [+-]:narrow, [>=<?]:effort: "
        (if narrow "Narrow" "Filter") tag-chars
        (if org-agenda-auto-exclude-function "[RET], " ""))
-      (setq char (read-char)))
+      (setq char (read-char-exclusive)))
     (when (member char '(?+ ?-))
       ;; Narrowing down
       (cond ((equal char ?-) (setq strip t narrow t))
            ((equal char ?+) (setq strip nil narrow t)))
       (message
        "Narrow by tag [%s ], [TAB], [/]:off, [>=<]:effort: " tag-chars)
     (when (member char '(?+ ?-))
       ;; Narrowing down
       (cond ((equal char ?-) (setq strip t narrow t))
            ((equal char ?+) (setq strip nil narrow t)))
       (message
        "Narrow by tag [%s ], [TAB], [/]:off, [>=<]:effort: " tag-chars)
-      (setq char (read-char)))
+      (setq char (read-char-exclusive)))
     (when (member char '(?< ?> ?= ??))
       ;; An effort operator
       (setq effort-op (char-to-string char))
     (when (member char '(?< ?> ?= ??))
       ;; An effort operator
       (setq effort-op (char-to-string char))
@@ -5835,7 +6275,7 @@ to switch to narrowing."
                     (if (= i 9) "0" (int-to-string (1+ i)))
                     "]" (nth i efforts))))
        (message "Effort%s: %s " effort-op effort-prompt)
                     (if (= i 9) "0" (int-to-string (1+ i)))
                     "]" (nth i efforts))))
        (message "Effort%s: %s " effort-op effort-prompt)
-       (setq char (read-char))
+       (setq char (read-char-exclusive))
        (when (or (< char ?0) (> char ?9))
          (error "Need 1-9,0 to select effort" ))))
     (when (equal char ?\t)
        (when (or (< char ?0) (> char ?9))
          (error "Need 1-9,0 to select effort" ))))
     (when (equal char ?\t)
@@ -5847,19 +6287,27 @@ to switch to narrowing."
                   "Tag: " org-global-tags-completion-table))))
     (cond
      ((equal char ?\r)
                   "Tag: " org-global-tags-completion-table))))
     (cond
      ((equal char ?\r)
-      (org-agenda-filter-by-tag-show-all)
+      (org-agenda-filter-show-all-tag)
       (when org-agenda-auto-exclude-function
       (when org-agenda-auto-exclude-function
-       (setq org-agenda-filter '())
+       (setq org-agenda-tag-filter '())
        (dolist (tag (org-agenda-get-represented-tags))
          (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
            (if modifier
        (dolist (tag (org-agenda-get-represented-tags))
          (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
            (if modifier
-               (push modifier org-agenda-filter))))
-       (if (not (null org-agenda-filter))
-           (org-agenda-filter-apply org-agenda-filter))))
+               (push modifier org-agenda-tag-filter))))
+       (if (not (null org-agenda-tag-filter))
+           (org-agenda-filter-apply org-agenda-tag-filter 'tag)))
+      (setq maybe-refresh t))
      ((equal char ?/)
      ((equal char ?/)
-      (org-agenda-filter-by-tag-show-all)
-      (when (get 'org-agenda-filter :preset-filter)
-       (org-agenda-filter-apply org-agenda-filter)))
+      (org-agenda-filter-show-all-tag)
+      (when (get 'org-agenda-tag-filter :preset-filter)
+       (org-agenda-filter-apply org-agenda-tag-filter 'tag))
+      (setq maybe-refresh t))
+     ((equal char ?. )
+      (setq org-agenda-tag-filter
+           (mapcar (lambda(tag) (concat "+" tag))
+                   (org-get-at-bol 'tags)))
+      (org-agenda-filter-apply org-agenda-tag-filter 'tag)
+      (setq maybe-refresh t))
      ((or (equal char ?\ )
          (setq a (rassoc char alist))
          (and (>= char ?0) (<= char ?9)
      ((or (equal char ?\ )
          (setq a (rassoc char alist))
          (and (>= char ?0) (<= char ?9)
@@ -5870,13 +6318,17 @@ to switch to narrowing."
               (setq tag "?eff")
               a (cons tag nil))
          (and tag (setq a (cons tag nil))))
               (setq tag "?eff")
               a (cons tag nil))
          (and tag (setq a (cons tag nil))))
-      (org-agenda-filter-by-tag-show-all)
+      (org-agenda-filter-show-all-tag)
       (setq tag (car a))
       (setq tag (car a))
-      (setq org-agenda-filter
+      (setq org-agenda-tag-filter
            (cons (concat (if strip "-" "+") tag)
                  (if narrow current nil)))
            (cons (concat (if strip "-" "+") tag)
                  (if narrow current nil)))
-      (org-agenda-filter-apply org-agenda-filter))
-     (t (error "Invalid tag selection character %c" char)))))
+      (org-agenda-filter-apply org-agenda-tag-filter 'tag)
+      (setq maybe-refresh t))
+     (t (error "Invalid tag selection character %c" char)))
+    (when (and maybe-refresh
+              (eq org-agenda-clockreport-mode 'with-filter))
+      (org-agenda-redo))))
 
 (defun org-agenda-get-represented-tags ()
   "Get a list of all tags currently represented in the agenda."
 
 (defun org-agenda-get-represented-tags ()
   "Get a list of all tags currently represented in the agenda."
@@ -5890,15 +6342,17 @@ to switch to narrowing."
     tags))
 
 (defun org-agenda-filter-by-tag-refine (strip &optional char)
     tags))
 
 (defun org-agenda-filter-by-tag-refine (strip &optional char)
-  "Refine the current filter.  See `org-agenda-filter-by-tag."
+  "Refine the current filter.  See `org-agenda-filter-by-tag'."
   (interactive "P")
   (org-agenda-filter-by-tag strip char 'refine))
 
 (defun org-agenda-filter-make-matcher ()
   (interactive "P")
   (org-agenda-filter-by-tag strip char 'refine))
 
 (defun org-agenda-filter-make-matcher ()
-  "Create the form that tests a line for the agenda filter."
+  "Create the form that tests a line for agenda filter."
   (let (f f1)
   (let (f f1)
-    (dolist (x (append (get 'org-agenda-filter :preset-filter)
-                      org-agenda-filter))
+    ;; first compute the tag-filter matcher
+    (dolist (x (delete-dups
+               (append (get 'org-agenda-tag-filter
+                            :preset-filter) org-agenda-tag-filter)))
       (if (member x '("-" "+"))
          (setq f1 (if (equal x "-") 'tags '(not tags)))
        (if (string-match "[<=>?]" x)
       (if (member x '("-" "+"))
          (setq f1 (if (equal x "-") 'tags '(not tags)))
        (if (string-match "[<=>?]" x)
@@ -5907,6 +6361,14 @@ to switch to narrowing."
        (if (equal (string-to-char x) ?-)
            (setq f1 (list 'not f1))))
       (push f1 f))
        (if (equal (string-to-char x) ?-)
            (setq f1 (list 'not f1))))
       (push f1 f))
+    ;; then compute the category-filter matcher
+    (dolist (x (delete-dups
+               (append (get 'org-agenda-category-filter
+                            :preset-filter) org-agenda-category-filter)))
+      (if (equal "-" (substring x 0 1))
+         (setq f1 (list 'not (list 'equal (substring x 1) 'cat)))
+       (setq f1 (list 'equal (substring x 1) 'cat)))
+      (push f1 f))
     (cons 'and (nreverse f))))
 
 (defun org-agenda-filter-effort-form (e)
     (cons 'and (nreverse f))))
 
 (defun org-agenda-filter-effort-form (e)
@@ -5920,7 +6382,7 @@ E looks like \"+<2:25\"."
                   ((equal op ??) op)
                   (t '=)))
     (list 'org-agenda-compare-effort (list 'quote op)
                   ((equal op ??) op)
                   (t '=)))
     (list 'org-agenda-compare-effort (list 'quote op)
-         (org-hh:mm-string-to-minutes e))))
+         (org-duration-string-to-minutes e))))
 
 (defun org-agenda-compare-effort (op value)
   "Compare the effort of the current line with VALUE, using OP.
 
 (defun org-agenda-compare-effort (op value)
   "Compare the effort of the current line with VALUE, using OP.
@@ -5931,49 +6393,67 @@ If the line does not have an effort defined, return nil."
       (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0))
               value))))
 
       (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0))
               value))))
 
-(defun org-agenda-filter-apply (filter)
+(defun org-agenda-filter-apply (filter type)
   "Set FILTER as the new agenda filter and apply it."
   "Set FILTER as the new agenda filter and apply it."
-  (let (tags)
-    (setq org-agenda-filter filter
-         org-agenda-filter-form (org-agenda-filter-make-matcher))
+  (let (tags cat)
+    (if (eq type 'tag)
+       (setq org-agenda-tag-filter filter)
+      (setq org-agenda-category-filter filter))
+    (setq org-agenda-filter-form (org-agenda-filter-make-matcher))
+    (if (and (eq type 'category)
+            (not (equal (substring (car filter) 0 1) "-")))
+       ;; Only set `org-agenda-filtered-by-category' to t
+       ;; when a unique category is used as the filter
+       (setq org-agenda-filtered-by-category t))
     (org-agenda-set-mode-name)
     (save-excursion
       (goto-char (point-min))
       (while (not (eobp))
        (if (org-get-at-bol 'org-marker)
            (progn
     (org-agenda-set-mode-name)
     (save-excursion
       (goto-char (point-min))
       (while (not (eobp))
        (if (org-get-at-bol 'org-marker)
            (progn
-             (setq tags (org-get-at-bol 'tags)) ; used in eval
+             (setq tags (org-get-at-bol 'tags) ; used in eval
+                   cat (get-text-property (point) 'org-category))
              (if (not (eval org-agenda-filter-form))
              (if (not (eval org-agenda-filter-form))
-                 (org-agenda-filter-by-tag-hide-line))
+                 (org-agenda-filter-hide-line type))
              (beginning-of-line 2))
          (beginning-of-line 2))))
     (if (get-char-property (point) 'invisible)
              (beginning-of-line 2))
          (beginning-of-line 2))))
     (if (get-char-property (point) 'invisible)
-       (org-agenda-previous-line))))
+       (ignore-errors (org-agenda-previous-line)))))
 
 
-(defun org-agenda-filter-by-tag-hide-line ()
+(defun org-agenda-filter-hide-line (type)
   (let (ov)
     (setq ov (make-overlay (max (point-min) (1- (point-at-bol)))
                               (point-at-eol)))
     (overlay-put ov 'invisible t)
   (let (ov)
     (setq ov (make-overlay (max (point-min) (1- (point-at-bol)))
                               (point-at-eol)))
     (overlay-put ov 'invisible t)
-    (overlay-put ov 'type 'tags-filter)
-    (push ov org-agenda-filter-overlays)))
+    (overlay-put ov 'type type)
+    (if (eq type 'tag)
+       (push ov org-agenda-tag-filter-overlays)
+      (push ov org-agenda-cat-filter-overlays))))
 
 (defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
   (setq pos (or pos (point)))
   (save-excursion
     (dolist (ov (overlays-at pos))
       (when (and (overlay-get ov 'invisible)
 
 (defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
   (setq pos (or pos (point)))
   (save-excursion
     (dolist (ov (overlays-at pos))
       (when (and (overlay-get ov 'invisible)
-                (eq (overlay-get ov 'type) 'tags-filter))
+                (eq (overlay-get ov 'type) 'tag))
        (goto-char pos)
        (if (< (overlay-start ov) (point-at-eol))
            (move-overlay ov (point-at-eol)
                              (overlay-end ov)))))))
 
        (goto-char pos)
        (if (< (overlay-start ov) (point-at-eol))
            (move-overlay ov (point-at-eol)
                              (overlay-end ov)))))))
 
-(defun org-agenda-filter-by-tag-show-all ()
-  (mapc 'delete-overlay org-agenda-filter-overlays)
-  (setq org-agenda-filter-overlays nil)
-  (setq org-agenda-filter nil)
-  (setq org-agenda-filter-form nil)
+(defun org-agenda-filter-show-all-tag nil
+  (mapc 'delete-overlay org-agenda-tag-filter-overlays)
+  (setq org-agenda-tag-filter-overlays nil
+       org-agenda-tag-filter nil
+       org-agenda-filter-form nil)
+  (org-agenda-set-mode-name))
+
+(defun org-agenda-filter-show-all-cat nil
+  (mapc 'delete-overlay org-agenda-cat-filter-overlays)
+  (setq org-agenda-cat-filter-overlays nil
+       org-agenda-filtered-by-category nil
+       org-agenda-category-filter nil
+       org-agenda-filter-form nil)
   (org-agenda-set-mode-name))
 
 (defun org-agenda-manipulate-query-add ()
   (org-agenda-set-mode-name))
 
 (defun org-agenda-manipulate-query-add ()
@@ -6039,7 +6519,7 @@ Negative selection means regexp must not match for selection of an entry."
      (tdpos (goto-char tdpos))
      ((eq org-agenda-type 'agenda)
       (let* ((sd (org-agenda-compute-starting-span
      (tdpos (goto-char tdpos))
      ((eq org-agenda-type 'agenda)
       (let* ((sd (org-agenda-compute-starting-span
-                 (org-today) (or org-agenda-ndays org-agenda-span)))
+                 (org-today) (or org-agenda-current-span org-agenda-ndays org-agenda-span)))
             (org-agenda-overriding-arguments org-agenda-last-arguments))
        (setf (nth 1 org-agenda-overriding-arguments) sd)
        (org-agenda-redo)
             (org-agenda-overriding-arguments org-agenda-last-arguments))
        (setf (nth 1 org-agenda-overriding-arguments) sd)
        (org-agenda-redo)
@@ -6092,17 +6572,20 @@ With prefix ARG, go backward that many times the current span."
 (defun org-agenda-view-mode-dispatch ()
   "Call one of the view mode commands."
   (interactive)
 (defun org-agenda-view-mode-dispatch ()
   "Call one of the view mode commands."
   (interactive)
-  (message "View: [d]ay [w]eek [m]onth [y]ear                         [q]uit/abort
-      time[G]rid     [[]inactive [f]ollow [l]og [L]og-all   [E]ntryText
-      [a]rch-trees   [A]rch-files    clock[R]eport   include[D]iary")
+  (message "View: [d]ay [w]eek [m]onth [y]ear [SPC]reset    [q]uit/abort
+      time[G]rid     [[]inactive [f]ollow [l]og [L]og-all   [c]lockcheck
+      [a]rch-trees   [A]rch-files    clock[R]eport   include[D]iary
+      [E]ntryText")
   (let ((a (read-char-exclusive)))
     (case a
   (let ((a (read-char-exclusive)))
     (case a
+      (?\  (call-interactively 'org-agenda-reset-view))
       (?d (call-interactively 'org-agenda-day-view))
       (?w (call-interactively 'org-agenda-week-view))
       (?m (call-interactively 'org-agenda-month-view))
       (?y (call-interactively 'org-agenda-year-view))
       (?l (call-interactively 'org-agenda-log-mode))
       (?L (org-agenda-log-mode '(4)))
       (?d (call-interactively 'org-agenda-day-view))
       (?w (call-interactively 'org-agenda-week-view))
       (?m (call-interactively 'org-agenda-month-view))
       (?y (call-interactively 'org-agenda-year-view))
       (?l (call-interactively 'org-agenda-log-mode))
       (?L (org-agenda-log-mode '(4)))
+      (?c (org-agenda-log-mode 'clockcheck))
       ((?F ?f) (call-interactively 'org-agenda-follow-mode))
       (?a (call-interactively 'org-agenda-archives-mode))
       (?A (org-agenda-archives-mode 'files))
       ((?F ?f) (call-interactively 'org-agenda-follow-mode))
       (?a (call-interactively 'org-agenda-archives-mode))
       (?A (org-agenda-archives-mode 'files))
@@ -6118,6 +6601,10 @@ With prefix ARG, go backward that many times the current span."
       (?q (message "Abort"))
       (otherwise (error "Invalid key" )))))
 
       (?q (message "Abort"))
       (otherwise (error "Invalid key" )))))
 
+(defun org-agenda-reset-view ()
+  "Switch to default view for agenda."
+  (interactive)
+  (org-agenda-change-time-span (or org-agenda-ndays org-agenda-span)))
 (defun org-agenda-day-view (&optional day-of-year)
   "Switch to daily view for agenda.
 With argument DAY-OF-YEAR, switch to that day of the year."
 (defun org-agenda-day-view (&optional day-of-year)
   "Switch to daily view for agenda.
 With argument DAY-OF-YEAR, switch to that day of the year."
@@ -6161,7 +6648,8 @@ SPAN may be `day', `week', `month', `year'."
                org-starting-day))
         (sd (org-agenda-compute-starting-span sd span n))
         (org-agenda-overriding-arguments
                org-starting-day))
         (sd (org-agenda-compute-starting-span sd span n))
         (org-agenda-overriding-arguments
-         (list (car org-agenda-last-arguments) sd span t)))
+         (or org-agenda-overriding-arguments
+             (list (car org-agenda-last-arguments) sd span t))))
     (org-agenda-redo)
     (org-agenda-find-same-or-today-or-agenda))
   (org-agenda-set-mode-name)
     (org-agenda-redo)
     (org-agenda-find-same-or-today-or-agenda))
   (org-agenda-set-mode-name)
@@ -6259,8 +6747,7 @@ so that the date SD will be in that range."
   (interactive)
   (setq org-agenda-follow-mode (not org-agenda-follow-mode))
   (org-agenda-set-mode-name)
   (interactive)
   (setq org-agenda-follow-mode (not org-agenda-follow-mode))
   (org-agenda-set-mode-name)
-  (if (and org-agenda-follow-mode (org-get-at-bol 'org-marker))
-      (org-agenda-show))
+  (org-agenda-do-context-action)
   (message "Follow mode is %s"
           (if org-agenda-follow-mode "on" "off")))
 
   (message "Follow mode is %s"
           (if org-agenda-follow-mode "on" "off")))
 
@@ -6301,10 +6788,13 @@ With a double `C-u' prefix arg, show *only* log items, nothing else."
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline)
   (setq org-agenda-show-log
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline)
   (setq org-agenda-show-log
-       (if (equal special '(16))
-           'only
-         (if special '(closed clock state)
-           (not org-agenda-show-log))))
+       (cond
+        ((equal special '(16)) 'only)
+        ((eq special 'clockcheck)
+         (if (eq org-agenda-show-log 'clockcheck)
+             nil 'clockcheck))
+        (special '(closed clock state))
+        (t (not org-agenda-show-log))))
   (org-agenda-set-mode-name)
   (org-agenda-redo)
   (message "Log mode is %s"
   (org-agenda-set-mode-name)
   (org-agenda-redo)
   (message "Log mode is %s"
@@ -6373,15 +6863,38 @@ When called with a prefix argument, include all archive files as well."
              (if org-agenda-use-time-grid   " Grid"   "")
              (if (and (boundp 'org-habit-show-habits)
                       org-habit-show-habits) " Habit"   "")
              (if org-agenda-use-time-grid   " Grid"   "")
              (if (and (boundp 'org-habit-show-habits)
                       org-habit-show-habits) " Habit"   "")
-             (if (consp org-agenda-show-log) " LogAll"
-               (if org-agenda-show-log " Log" ""))
-             (if (or org-agenda-filter (get 'org-agenda-filter
+             (cond
+              ((consp org-agenda-show-log) " LogAll")
+              ((eq org-agenda-show-log 'clockcheck) " ClkCk")
+              (org-agenda-show-log " Log")
+              (t ""))
+             (if (or org-agenda-category-filter (get 'org-agenda-category-filter
+                                                     :preset-filter))
+                 '(:eval (org-propertize
+                          (concat " <"
+                                  (mapconcat
+                                   'identity
+                                   (append
+                                    (get 'org-agenda-category-filter :preset-filter)
+                                    org-agenda-category-filter)
+                                   "")
+                                  ">")
+                          'face 'org-agenda-filter-category
+                          'help-echo "Category used in filtering"))
+               "")
+             (if (or org-agenda-tag-filter (get 'org-agenda-tag-filter
                                             :preset-filter))
                                             :preset-filter))
-                 (concat " {" (mapconcat
-                               'identity
-                               (append (get 'org-agenda-filter
-                                            :preset-filter)
-                                       org-agenda-filter) "") "}")
+                 '(:eval (org-propertize
+                          (concat " {"
+                                  (mapconcat
+                                   'identity
+                                   (append
+                                    (get 'org-agenda-tag-filter :preset-filter)
+                                    org-agenda-tag-filter)
+                                   "")
+                                  "}")
+                          'face 'org-agenda-filter-tags
+                          'help-echo "Tags used in filtering"))
                "")
              (if org-agenda-archives-mode
                  (if (eq org-agenda-archives-mode t)
                "")
              (if org-agenda-archives-mode
                  (if (eq org-agenda-archives-mode t)
@@ -6415,11 +6928,13 @@ When called with a prefix argument, include all archive files as well."
 (defun org-agenda-do-context-action ()
   "Show outline path and, maybe, follow mode window."
   (let ((m (org-get-at-bol 'org-marker)))
 (defun org-agenda-do-context-action ()
   "Show outline path and, maybe, follow mode window."
   (let ((m (org-get-at-bol 'org-marker)))
-    (if (and org-agenda-follow-mode m)
-       (org-agenda-show))
-    (if (and m org-agenda-show-outline-path)
-       (org-with-point-at m
-         (org-display-outline-path t)))))
+    (when (and (markerp m) (marker-buffer m))
+      (and org-agenda-follow-mode
+          (if org-agenda-follow-indirect
+              (org-agenda-tree-to-indirect-buffer)
+            (org-agenda-show)))
+      (and org-agenda-show-outline-path
+          (org-with-point-at m (org-display-outline-path t))))))
 
 (defun org-agenda-show-priority ()
   "Show the priority of the current item.
 
 (defun org-agenda-show-priority ()
   "Show the priority of the current item.
@@ -6449,11 +6964,13 @@ and by additional input from the age of a schedules or deadline entry."
     (widen)
     (push-mark)
     (goto-char pos)
     (widen)
     (push-mark)
     (goto-char pos)
-    (when (org-mode-p)
+    (when (eq major-mode 'org-mode)
       (org-show-context 'agenda)
       (save-excursion
        (and (outline-next-heading)
       (org-show-context 'agenda)
       (save-excursion
        (and (outline-next-heading)
-            (org-flag-heading nil)))) ; show the next heading
+            (org-flag-heading nil))))  ; show the next heading
+    (when (outline-invisible-p)
+      (show-entry))                    ; display invisible text
     (recenter (/ (window-height) 2))
     (run-hooks 'org-agenda-after-show-hook)
     (and highlight (org-highlight (point-at-bol) (point-at-eol)))))
     (recenter (/ (window-height) 2))
     (run-hooks 'org-agenda-after-show-hook)
     (and highlight (org-highlight (point-at-bol) (point-at-eol)))))
@@ -6476,7 +6993,7 @@ Point is in the buffer where the item originated.")
      (with-current-buffer buffer
        (save-excursion
         (goto-char pos)
      (with-current-buffer buffer
        (save-excursion
         (goto-char pos)
-        (if (and (org-mode-p) (not (member type '("sexp"))))
+        (if (and (eq major-mode 'org-mode) (not (member type '("sexp"))))
             (setq dbeg (progn (org-back-to-heading t) (point))
                   dend (org-end-of-subtree t t))
           (setq dbeg (point-at-bol)
             (setq dbeg (progn (org-back-to-heading t) (point))
                   dend (org-end-of-subtree t t))
           (setq dbeg (point-at-bol)
@@ -6528,7 +7045,7 @@ Point is in the buffer where the item originated.")
         (pos (marker-position marker)))
     (org-with-remote-undo buffer
       (with-current-buffer buffer
         (pos (marker-position marker)))
     (org-with-remote-undo buffer
       (with-current-buffer buffer
-       (if (org-mode-p)
+       (if (eq major-mode 'org-mode)
            (if (and confirm
                     (not (y-or-n-p "Archive this subtree or entry? ")))
                (error "Abort")
            (if (and confirm
                     (not (y-or-n-p "Archive this subtree or entry? ")))
                (error "Abort")
@@ -6575,7 +7092,7 @@ If this information is not given, the function uses the tree at point."
           (pos (marker-position marker))
           (rfloc (or rfloc
                      (org-refile-get-location
           (pos (marker-position marker))
           (rfloc (or rfloc
                      (org-refile-get-location
-                      (if goto "Goto: " "Refile to: ") buffer
+                      (if goto "Goto" "Refile to") buffer
                       org-refile-allow-creating-parent-nodes))))
       (with-current-buffer buffer
        (save-excursion
                       org-refile-allow-creating-parent-nodes))))
       (with-current-buffer buffer
        (save-excursion
@@ -6595,9 +7112,7 @@ at the text of the entry itself."
                     (org-get-at-bol 'org-marker)))
         (buffer (and marker (marker-buffer marker)))
         (prefix (buffer-substring
                     (org-get-at-bol 'org-marker)))
         (buffer (and marker (marker-buffer marker)))
         (prefix (buffer-substring
-                 (point-at-bol)
-                 (+ (point-at-bol)
-                    (or (org-get-at-bol 'prefix-length) 0)))))
+                 (point-at-bol) (point-at-eol))))
     (cond
      (buffer
       (with-current-buffer buffer
     (cond
      (buffer
       (with-current-buffer buffer
@@ -6631,15 +7146,17 @@ at the text of the entry itself."
                       (org-agenda-error)))
           (buffer (marker-buffer marker))
           (pos (marker-position marker)))
                       (org-agenda-error)))
           (buffer (marker-buffer marker))
           (pos (marker-position marker)))
-      (switch-to-buffer buffer)
+      (org-pop-to-buffer-same-window buffer)
       (and delete-other-windows (delete-other-windows))
       (widen)
       (goto-char pos)
       (and delete-other-windows (delete-other-windows))
       (widen)
       (goto-char pos)
-      (when (org-mode-p)
+      (when (eq major-mode 'org-mode)
        (org-show-context 'agenda)
        (save-excursion
          (and (outline-next-heading)
        (org-show-context 'agenda)
        (save-excursion
          (and (outline-next-heading)
-              (org-flag-heading nil)))))))  ; show the next heading
+              (org-flag-heading nil))) ; show the next heading
+       (when (outline-invisible-p)
+         (show-entry))))))             ; display invisible text
 
 (defun org-agenda-goto-mouse (ev)
   "Go to the Org-mode file which contains the item at the mouse click."
 
 (defun org-agenda-goto-mouse (ev)
   "Go to the Org-mode file which contains the item at the mouse click."
@@ -6707,7 +7224,7 @@ if it was hidden in the outline."
        (org-back-to-heading)
        (run-hook-with-args 'org-cycle-hook 'folded))
       (message "Remote: FOLDED"))
        (org-back-to-heading)
        (run-hook-with-args 'org-cycle-hook 'folded))
       (message "Remote: FOLDED"))
-     ((and (interactive-p) (= more 1))
+     ((and (org-called-interactively-p 'any) (= more 1))
       (message "Remote: show with default settings"))
      ((= more 2)
       (show-entry)
       (message "Remote: show with default settings"))
      ((= more 2)
       (show-entry)
@@ -6797,6 +7314,24 @@ With numerical prefix arg ARG, go up to this level and then take that tree.
 With a \\[universal-argument] prefix, make a separate frame for this tree (i.e. don't
 use the dedicated frame)."
   (interactive)
 With a \\[universal-argument] prefix, make a separate frame for this tree (i.e. don't
 use the dedicated frame)."
   (interactive)
+  (if (and current-prefix-arg (listp current-prefix-arg))
+      (org-agenda-do-tree-to-indirect-buffer)
+    (let ((agenda-window (selected-window))
+          (indirect-window
+          (and org-last-indirect-buffer
+               (get-buffer-window org-last-indirect-buffer))))
+      (save-window-excursion (org-agenda-do-tree-to-indirect-buffer))
+      (unwind-protect
+          (progn
+            (unless (and indirect-window (window-live-p indirect-window))
+              (setq indirect-window (split-window agenda-window)))
+            (select-window indirect-window)
+            (switch-to-buffer org-last-indirect-buffer :norecord)
+            (fit-window-to-buffer indirect-window))
+        (select-window (get-buffer-window org-agenda-buffer-name))))))
+
+(defun org-agenda-do-tree-to-indirect-buffer ()
+  "Same as `org-agenda-tree-to-indirect-buffer' without saving window."
   (org-agenda-check-no-diary)
   (let* ((marker (or (org-get-at-bol 'org-marker)
                     (org-agenda-error)))
   (org-agenda-check-no-diary)
   (let* ((marker (or (org-get-at-bol 'org-marker)
                     (org-agenda-error)))
@@ -6886,7 +7421,7 @@ the same tree node, and the headline of the tree node in the Org-mode file."
                                            &optional fixface just-this)
   "Change all lines in the agenda buffer which match HDMARKER.
 The new content of the line will be NEWHEAD (as modified by
                                            &optional fixface just-this)
   "Change all lines in the agenda buffer which match HDMARKER.
 The new content of the line will be NEWHEAD (as modified by
-`org-format-agenda-item').  HDMARKER is checked with
+`org-agenda-format-item').  HDMARKER is checked with
 `equal' against all `org-hd-marker' text properties in the file.
 If FIXFACE is non-nil, the face of each item is modified according to
 the new TODO state.
 `equal' against all `org-hd-marker' text properties in the file.
 If FIXFACE is non-nil, the face of each item is modified according to
 the new TODO state.
@@ -6911,15 +7446,22 @@ If FORCE-TAGS is non nil, the car of it returns the new tags."
                dotime (org-get-at-bol 'dotime)
                cat (org-get-at-bol 'org-category)
                tags thetags
                dotime (org-get-at-bol 'dotime)
                cat (org-get-at-bol 'org-category)
                tags thetags
-               new (org-format-agenda-item "x" newhead cat tags dotime 'noprefix)
-               pl (org-get-at-bol 'prefix-length)
+               new
+               (let ((org-prefix-format-compiled
+                      (or (get-text-property (point) 'format)
+                          org-prefix-format-compiled)))
+                 (with-current-buffer (marker-buffer hdmarker)
+                   (save-excursion
+                     (save-restriction
+                       (widen)
+                       (org-agenda-format-item (org-get-at-bol 'extra)
+                                               newhead cat tags dotime)))))
+               pl (text-property-any (point-at-bol) (point-at-eol) 'org-heading t)
                undone-face (org-get-at-bol 'undone-face)
                done-face (org-get-at-bol 'done-face))
                undone-face (org-get-at-bol 'undone-face)
                done-face (org-get-at-bol 'done-face))
-         (goto-char (+ (point) pl))
-         ;; (org-move-to-column pl)  FIXME: does the above line work correctly?
+         (beginning-of-line 1)
          (cond
           ((equal new "")
          (cond
           ((equal new "")
-           (beginning-of-line 1)
            (and (looking-at ".*\n?") (replace-match "")))
           ((looking-at ".*")
            (replace-match new t t)
            (and (looking-at ".*\n?") (replace-match "")))
           ((looking-at ".*")
            (replace-match new t t)
@@ -7009,9 +7551,8 @@ the same tree node, and the headline of the tree node in the Org-mode file."
   "Set tags for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
   "Set tags for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
-  (if (and (org-region-active-p) (interactive-p))
+  (if (and (org-region-active-p) (org-called-interactively-p 'any))
       (call-interactively 'org-change-tag-in-region)
       (call-interactively 'org-change-tag-in-region)
-    (org-agenda-show)   ;;; FIXME This is a stupid hack and should not be needed
     (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                         (org-agenda-error)))
           (buffer (marker-buffer hdmarker))
     (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                         (org-agenda-error)))
           (buffer (marker-buffer hdmarker))
@@ -7040,7 +7581,6 @@ the same tree node, and the headline of the tree node in the Org-mode file."
   "Set a property for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
   "Set a property for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
-  (org-agenda-show)   ;;; FIXME This is a stupid hack and should not be needed
   (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                       (org-agenda-error)))
         (buffer (marker-buffer hdmarker))
   (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                       (org-agenda-error)))
         (buffer (marker-buffer hdmarker))
@@ -7063,7 +7603,6 @@ the same tree node, and the headline of the tree node in the Org-mode file."
   "Set the effort property for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
   "Set the effort property for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
-  (org-agenda-show)   ;;; FIXME This is a stupid hack and should not be needed
   (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                       (org-agenda-error)))
         (buffer (marker-buffer hdmarker))
   (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                       (org-agenda-error)))
         (buffer (marker-buffer hdmarker))
@@ -7078,16 +7617,17 @@ the same tree node, and the headline of the tree node in the Org-mode file."
          (org-show-context 'agenda))
        (save-excursion
          (and (outline-next-heading)
          (org-show-context 'agenda))
        (save-excursion
          (and (outline-next-heading)
-              (org-flag-heading nil)))   ; show the next heading
+              (org-flag-heading nil))) ; show the next heading
        (goto-char pos)
        (call-interactively 'org-set-effort)
        (goto-char pos)
        (call-interactively 'org-set-effort)
-       (end-of-line 1)))))
+       (end-of-line 1)
+       (setq newhead (org-get-heading)))
+      (org-agenda-change-all-lines newhead hdmarker))))
 
 (defun org-agenda-toggle-archive-tag ()
   "Toggle the archive tag for the current entry."
   (interactive)
   (org-agenda-check-no-diary)
 
 (defun org-agenda-toggle-archive-tag ()
   "Toggle the archive tag for the current entry."
   (interactive)
   (org-agenda-check-no-diary)
-  (org-agenda-show)   ;;; FIXME This is a stupid hack and should not be needed
   (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                        (org-agenda-error)))
         (buffer (marker-buffer hdmarker))
   (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                        (org-agenda-error)))
         (buffer (marker-buffer hdmarker))
@@ -7141,26 +7681,44 @@ the same tree node, and the headline of the tree node in the Org-mode file."
     (org-agenda-date-earlier (prefix-numeric-value arg)))))
 
 (defun org-agenda-date-later (arg &optional what)
     (org-agenda-date-earlier (prefix-numeric-value arg)))))
 
 (defun org-agenda-date-later (arg &optional what)
-  "Change the date of this item to one day later."
+  "Change the date of this item to ARG day(s) later."
   (interactive "p")
   (org-agenda-check-type t 'agenda 'timeline)
   (org-agenda-check-no-diary)
   (let* ((marker (or (org-get-at-bol 'org-marker)
                     (org-agenda-error)))
         (buffer (marker-buffer marker))
   (interactive "p")
   (org-agenda-check-type t 'agenda 'timeline)
   (org-agenda-check-no-diary)
   (let* ((marker (or (org-get-at-bol 'org-marker)
                     (org-agenda-error)))
         (buffer (marker-buffer marker))
-        (pos (marker-position marker)))
+        (pos (marker-position marker))
+        cdate today)
     (org-with-remote-undo buffer
     (org-with-remote-undo buffer
-     (with-current-buffer buffer
-       (widen)
-       (goto-char pos)
-       (if (not (org-at-timestamp-p))
-          (error "Cannot find time stamp"))
-       (org-timestamp-change arg (or what 'day)))
-     (org-agenda-show-new-time marker org-last-changed-timestamp))
+      (with-current-buffer buffer
+       (widen)
+       (goto-char pos)
+       (if (not (org-at-timestamp-p))
+           (error "Cannot find time stamp"))
+       (when (and org-agenda-move-date-from-past-immediately-to-today
+                  (equal arg 1)
+                  (or (not what) (eq what 'day))
+                  (not (save-match-data (org-at-date-range-p))))
+         (setq cdate (org-parse-time-string (match-string 0) 'nodefault)
+               cdate (calendar-absolute-from-gregorian
+                      (list (nth 4 cdate) (nth 3 cdate) (nth 5 cdate)))
+               today (org-today))
+         (if (> today cdate)
+             ;; immediately shift to today
+             (setq arg (- today cdate))))
+       (org-timestamp-change arg (or what 'day))
+       (when (and (org-at-date-range-p)
+                  (re-search-backward org-tr-regexp-both (point-at-bol)))
+         (let ((end org-last-changed-timestamp))
+           (org-timestamp-change arg (or what 'day))
+           (setq org-last-changed-timestamp
+                 (concat org-last-changed-timestamp "--" end)))))
+      (org-agenda-show-new-time marker org-last-changed-timestamp))
     (message "Time stamp changed to %s" org-last-changed-timestamp)))
 
 (defun org-agenda-date-earlier (arg &optional what)
     (message "Time stamp changed to %s" org-last-changed-timestamp)))
 
 (defun org-agenda-date-earlier (arg &optional what)
-  "Change the date of this item to one day earlier."
+  "Change the date of this item to ARG day(s) earlier."
   (interactive "p")
   (org-agenda-date-later (- arg) what))
 
   (interactive "p")
   (org-agenda-date-later (- arg) what))
 
@@ -7234,9 +7792,9 @@ be used to request time specification in the time stamp."
       (org-agenda-show-new-time marker org-last-changed-timestamp))
     (message "Time stamp changed to %s" org-last-changed-timestamp)))
 
       (org-agenda-show-new-time marker org-last-changed-timestamp))
     (message "Time stamp changed to %s" org-last-changed-timestamp)))
 
-(defun org-agenda-schedule (arg)
+(defun org-agenda-schedule (arg &optional time)
   "Schedule the item at point.
   "Schedule the item at point.
-Arg is passed through to `org-schedule'."
+ARG is passed through to `org-schedule'."
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline 'todo 'tags 'search)
   (org-agenda-check-no-diary)
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline 'todo 'tags 'search)
   (org-agenda-check-no-diary)
@@ -7252,13 +7810,13 @@ Arg is passed through to `org-schedule'."
       (with-current-buffer buffer
        (widen)
        (goto-char pos)
       (with-current-buffer buffer
        (widen)
        (goto-char pos)
-       (setq ts (org-schedule arg)))
+       (setq ts (org-schedule arg time)))
       (org-agenda-show-new-time marker ts "S"))
     (message "Item scheduled for %s" ts)))
 
       (org-agenda-show-new-time marker ts "S"))
     (message "Item scheduled for %s" ts)))
 
-(defun org-agenda-deadline (arg)
+(defun org-agenda-deadline (arg &optional time)
   "Schedule the item at point.
   "Schedule the item at point.
-Arg is passed through to `org-deadline'."
+ARG is passed through to `org-deadline'."
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline 'todo 'tags 'search)
   (org-agenda-check-no-diary)
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline 'todo 'tags 'search)
   (org-agenda-check-no-diary)
@@ -7272,7 +7830,7 @@ Arg is passed through to `org-deadline'."
       (with-current-buffer buffer
        (widen)
        (goto-char pos)
       (with-current-buffer buffer
        (widen)
        (goto-char pos)
-       (setq ts (org-deadline arg)))
+       (setq ts (org-deadline arg time)))
       (org-agenda-show-new-time marker ts "D"))
        (message "Deadline for this item set to %s" ts)))
 
       (org-agenda-show-new-time marker ts "D"))
        (message "Deadline for this item set to %s" ts)))
 
@@ -7465,6 +8023,7 @@ top-level    as top-level entries at the end of the file."
 (defcustom org-agenda-insert-diary-extract-time nil
   "Non-nil means extract any time specification from the diary entry."
   :group 'org-agenda
 (defcustom org-agenda-insert-diary-extract-time nil
   "Non-nil means extract any time specification from the diary entry."
   :group 'org-agenda
+  :version "24.1"
   :type 'boolean)
 
 (defun org-agenda-add-entry-to-org-agenda-diary-file (type text &optional d1 d2)
   :type 'boolean)
 
 (defun org-agenda-add-entry-to-org-agenda-diary-file (type text &optional d1 d2)
@@ -7481,7 +8040,7 @@ the resulting entry will not be shown.  When TEXT is empty, switch to
      ((eq type 'anniversary)
       (or (re-search-forward "^*[ \t]+Anniversaries" nil t)
        (progn
      ((eq type 'anniversary)
       (or (re-search-forward "^*[ \t]+Anniversaries" nil t)
        (progn
-         (or (org-on-heading-p t)
+         (or (org-at-heading-p t)
              (progn
                (outline-next-heading)
                (insert "* Anniversaries\n\n")
              (progn
                (outline-next-heading)
                (insert "* Anniversaries\n\n")
@@ -7490,26 +8049,17 @@ the resulting entry will not be shown.  When TEXT is empty, switch to
       (org-back-over-empty-lines)
       (backward-char 1)
       (insert "\n")
       (org-back-over-empty-lines)
       (backward-char 1)
       (insert "\n")
-      (require 'diary-lib)
-      (let ((calendar-date-display-form
-            (if (if (boundp 'calendar-date-style)
-                    (eq calendar-date-style 'european)
-                  (with-no-warnings ;; european-calendar-style is obsolete as of version 23.1
-                    (org-bound-and-true-p european-calendar-style))) ; Emacs 22
-                '(day " " month " " year)
-              '(month " " day " " year))))
-
-       (insert (format "%%%%(diary-anniversary %s) %s"
-                       (calendar-date-string d1 nil t) text))))
+      (insert (format "%%%%(org-anniversary %d %2d %2d) %s"
+                     (nth 2 d1) (car d1) (nth 1 d1) text)))
      ((eq type 'day)
       (let ((org-prefix-has-time t)
            (org-agenda-time-leading-zero t)
            fmt time time2)
        (if org-agenda-insert-diary-extract-time
      ((eq type 'day)
       (let ((org-prefix-has-time t)
            (org-agenda-time-leading-zero t)
            fmt time time2)
        (if org-agenda-insert-diary-extract-time
-           ;; Use org-format-agenda-item to parse text for a time-range and
+           ;; Use org-agenda-format-item to parse text for a time-range and
            ;; remove it.  FIXME: This is a hack, we should refactor
            ;; that function to make time extraction available separately
            ;; remove it.  FIXME: This is a hack, we should refactor
            ;; that function to make time extraction available separately
-           (setq fmt (org-format-agenda-item nil text nil nil t)
+           (setq fmt (org-agenda-format-item nil text nil nil t)
                  time (get-text-property 0 'time fmt)
                  time2 (if (> (length time) 0)
                            ;; split-string removes trailing ...... if
                  time (get-text-property 0 'time fmt)
                  time2 (if (> (length time) 0)
                            ;; split-string removes trailing ...... if
@@ -7744,7 +8294,7 @@ This is a command that has to be installed in `calendar-mode-map'."
 (defun org-agenda-bulk-mark (&optional arg)
   "Mark the entry at point for future bulk action."
   (interactive "p")
 (defun org-agenda-bulk-mark (&optional arg)
   "Mark the entry at point for future bulk action."
   (interactive "p")
-  (dotimes (i (max arg 1))
+  (dotimes (i (or arg 1))
     (unless (org-get-at-bol 'org-agenda-diary-link)
       (let* ((m (org-get-at-bol 'org-hd-marker))
             ov)
     (unless (org-get-at-bol 'org-agenda-diary-link)
       (let* ((m (org-get-at-bol 'org-hd-marker))
             ov)
@@ -7762,6 +8312,20 @@ This is a command that has to be installed in `calendar-mode-map'."
        (message "%d entries marked for bulk action"
                 (length org-agenda-bulk-marked-entries))))))
 
        (message "%d entries marked for bulk action"
                 (length org-agenda-bulk-marked-entries))))))
 
+(defun org-agenda-bulk-mark-regexp (regexp)
+  "Mark entries match REGEXP."
+  (interactive "sMark entries matching regexp: ")
+  (let (entries-marked)
+    (save-excursion
+      (goto-char (point-min))
+      (goto-char (next-single-property-change (point) 'txt))
+      (while (re-search-forward regexp nil t)
+       (when (string-match regexp (get-text-property (point) 'txt))
+         (setq entries-marked (+ entries-marked 1))
+         (call-interactively 'org-agenda-bulk-mark))))
+    (if (not entries-marked)
+       (message "No entry matching this regexp."))))
+
 (defun org-agenda-bulk-unmark ()
   "Unmark the entry at point for future bulk action."
   (interactive)
 (defun org-agenda-bulk-unmark ()
   "Unmark the entry at point for future bulk action."
   (interactive)
@@ -7808,9 +8372,25 @@ This will remove the markers, and the overlays."
   "Execute an remote-editing action on all marked entries.
 The prefix arg is passed through to the command if possible."
   (interactive "P")
   "Execute an remote-editing action on all marked entries.
 The prefix arg is passed through to the command if possible."
   (interactive "P")
-  (unless org-agenda-bulk-marked-entries
-    (error "No entries are marked"))
-  (message "Bulk: [r]efile [$]arch [A]rch->sib [t]odo [+/-]tag [s]chd [S]catter [d]eadline")
+  ;; Make sure we have markers, and only valid ones
+  (unless org-agenda-bulk-marked-entries (error "No entries are marked"))
+  (mapc
+   (lambda (m)
+     (unless (and (markerp m)
+                 (marker-buffer m)
+                 (buffer-live-p (marker-buffer m))
+                 (marker-position m))
+       (error "Marker %s for bulk command is invalid" m)))
+   org-agenda-bulk-marked-entries)
+
+  ;; Prompt for the bulk command
+  (message (concat "Bulk: [r]efile [$]arch [A]rch->sib [t]odo"
+                  " [+/-]tag [s]chd [S]catter [d]eadline [f]unction"
+                  (when org-agenda-bulk-custom-functions
+                    (concat " Custom: ["
+                            (mapconcat (lambda(f) (char-to-string (car f)))
+                                       org-agenda-bulk-custom-functions "")
+                            "]"))))
   (let* ((action (read-char-exclusive))
         (org-log-refile (if org-log-refile 'time nil))
         (entries (reverse org-agenda-bulk-marked-entries))
   (let* ((action (read-char-exclusive))
         (org-log-refile (if org-log-refile 'time nil))
         (entries (reverse org-agenda-bulk-marked-entries))
@@ -7825,7 +8405,7 @@ The prefix arg is passed through to the command if possible."
 
      ((member action '(?r ?w))
       (setq rfloc (org-refile-get-location
 
      ((member action '(?r ?w))
       (setq rfloc (org-refile-get-location
-                  "Refile to"
+                  "Refile to"
                   (marker-buffer (car org-agenda-bulk-marked-entries))
                   org-refile-allow-creating-parent-nodes))
       (if (nth 3 rfloc)
                   (marker-buffer (car org-agenda-bulk-marked-entries))
                   org-refile-allow-creating-parent-nodes))
       (if (nth 3 rfloc)
@@ -7873,27 +8453,45 @@ The prefix arg is passed through to the command if possible."
                           (fset 'read-string old)
                         (fmakunbound 'read-string)))))))
 
                           (fset 'read-string old)
                         (fmakunbound 'read-string)))))))
 
-     ((eq action '?S)
-      (let ((days (read-number
-                  (format "Scatter tasks across how many %sdays: "
-                          (if arg "week" "")) 7)))
-       (setq cmd
-             `(let ((distance (random ,(1+ days))))
-                (if arg
-                    (let ((dist distance)
-                          (day-of-week
-                           (calendar-day-of-week
-                            (calendar-gregorian-from-absolute (org-today)))))
-                      (dotimes (i (1+ dist))
-                        (while (member day-of-week org-agenda-weekend-days)
-                          (incf distance)
+     ((equal action ?S)
+      (if (not (org-agenda-check-type nil 'agenda 'timeline 'todo))
+         (error "Can't scatter tasks in \"%s\" agenda view" org-agenda-type)
+       (let ((days (read-number
+                    (format "Scatter tasks across how many %sdays: "
+                            (if arg "week" "")) 7)))
+         (setq cmd
+               `(let ((distance (1+ (random ,days))))
+                  (if arg
+                      (let ((dist distance)
+                            (day-of-week
+                             (calendar-day-of-week
+                              (calendar-gregorian-from-absolute (org-today)))))
+                        (dotimes (i (1+ dist))
+                          (while (member day-of-week org-agenda-weekend-days)
+                            (incf distance)
+                            (incf day-of-week)
+                            (if (= day-of-week 7)
+                                (setq day-of-week 0)))
                           (incf day-of-week)
                           (if (= day-of-week 7)
                           (incf day-of-week)
                           (if (= day-of-week 7)
-                              (setq day-of-week 0)))
-                        (incf day-of-week)
-                        (if (= day-of-week 7)
-                            (setq day-of-week 0)))))
-                (org-agenda-date-later distance)))))
+                              (setq day-of-week 0)))))
+                  ;; silently fail when try to replan a sexp entry
+                  (condition-case nil
+                      (let* ((date (calendar-gregorian-from-absolute
+                                    (+ (org-today) distance)))
+                             (time (encode-time 0 0 0 (nth 1 date) (nth 0 date)
+                                                (nth 2 date))))
+                        (org-agenda-schedule nil time))
+                    (error nil)))))))
+
+     ((assoc action org-agenda-bulk-custom-functions)
+      (setq cmd (list (cadr (assoc action org-agenda-bulk-custom-functions)))
+           redo-at-end t))
+
+     ((equal action ?f)
+      (setq cmd (list (intern
+                      (org-icompleting-read "Function: "
+                                            obarray 'fboundp t nil nil)))))
 
      (t (error "Invalid bulk action")))
 
 
      (t (error "Invalid bulk action")))
 
@@ -7914,7 +8512,8 @@ The prefix arg is passed through to the command if possible."
          (progn (message "Skipping removed entry at %s" e)
                 (setq cntskip (1+ cntskip)))
        (goto-char pos)
          (progn (message "Skipping removed entry at %s" e)
                 (setq cntskip (1+ cntskip)))
        (goto-char pos)
-       (eval cmd)
+       (let (org-loop-over-headlines-in-active-region)
+         (eval cmd))
        (setq org-agenda-bulk-marked-entries
              (delete e org-agenda-bulk-marked-entries))
        (setq cnt (1+ cnt))))
        (setq org-agenda-bulk-marked-entries
              (delete e org-agenda-bulk-marked-entries))
        (setq cnt (1+ cnt))))
@@ -7946,7 +8545,7 @@ tag and (if present) the flagging note."
          (org-agenda-remove-flag hdmarker)
          (let ((win (get-buffer-window "*Flagging Note*")))
            (and win (delete-window win)))
          (org-agenda-remove-flag hdmarker)
          (let ((win (get-buffer-window "*Flagging Note*")))
            (and win (delete-window win)))
-         (message "Entry unflaged"))
+         (message "Entry unflagged"))
       (setq note (org-entry-get hdmarker "THEFLAGGINGNOTE"))
       (unless note
        (error "No flagging note"))
       (setq note (org-entry-get hdmarker "THEFLAGGINGNOTE"))
       (unless note
        (error "No flagging note"))
@@ -7969,7 +8568,7 @@ tag and (if present) the flagging note."
       (org-entry-delete nil "THEFLAGGINGNOTE")
       (setq newhead (org-get-heading)))
     (org-agenda-change-all-lines newhead marker)
       (org-entry-delete nil "THEFLAGGINGNOTE")
       (setq newhead (org-get-heading)))
     (org-agenda-change-all-lines newhead marker)
-    (message "Entry unflaged")))
+    (message "Entry unflagged")))
 
 (defun org-agenda-get-any-marker (&optional pos)
   (or (get-text-property (or pos (point-at-bol)) 'org-hd-marker)
 
 (defun org-agenda-get-any-marker (&optional pos)
   (or (get-text-property (or pos (point-at-bol)) 'org-hd-marker)
@@ -7980,7 +8579,7 @@ tag and (if present) the flagging note."
 (defvar appt-time-msg-list)
 
 ;;;###autoload
 (defvar appt-time-msg-list)
 
 ;;;###autoload
-(defun org-agenda-to-appt (&optional refresh filter)
+(defun org-agenda-to-appt (&optional refresh filter &rest args)
   "Activate appointments found in `org-agenda-files'.
 With a \\[universal-argument] prefix, refresh the list of
 appointments.
   "Activate appointments found in `org-agenda-files'.
 With a \\[universal-argument] prefix, refresh the list of
 appointments.
@@ -7991,6 +8590,10 @@ expression, and filter out entries that don't match it.
 If FILTER is a string, use this string as a regular expression
 for filtering entries out.
 
 If FILTER is a string, use this string as a regular expression
 for filtering entries out.
 
+If FILTER is a function, filter out entries against which
+calling the function returns nil.  This function takes one
+argument: an entry from `org-agenda-get-day-entries'.
+
 FILTER can also be an alist with the car of each cell being
 either 'headline or 'category.  For example:
 
 FILTER can also be an alist with the car of each cell being
 either 'headline or 'category.  For example:
 
@@ -7998,12 +8601,18 @@ either 'headline or 'category.  For example:
     (category \"Work\"))
 
 will only add headlines containing IMPORTANT or headlines
     (category \"Work\"))
 
 will only add headlines containing IMPORTANT or headlines
-belonging to the \"Work\" category."
+belonging to the \"Work\" category.
+
+ARGS are symbols indicating what kind of entries to consider.
+By default `org-agenda-to-appt' will use :deadline, :scheduled
+and :timestamp entries.  See the docstring of `org-diary' for
+details and examples."
   (interactive "P")
   (if refresh (setq appt-time-msg-list nil))
   (if (eq filter t)
       (setq filter (read-from-minibuffer "Regexp filter: ")))
   (let* ((cnt 0) ; count added events
   (interactive "P")
   (if refresh (setq appt-time-msg-list nil))
   (if (eq filter t)
       (setq filter (read-from-minibuffer "Regexp filter: ")))
   (let* ((cnt 0) ; count added events
+        (scope (or args '(:deadline :scheduled :timestamp)))
         (org-agenda-new-buffers nil)
         (org-deadline-warning-days 0)
         ;; Do not use `org-today' here because appt only takes
         (org-agenda-new-buffers nil)
         (org-deadline-warning-days 0)
         ;; Do not use `org-today' here because appt only takes
@@ -8017,10 +8626,10 @@ belonging to the \"Work\" category."
     (org-prepare-agenda-buffers files)
     (while (setq file (pop files))
       (setq entries
     (org-prepare-agenda-buffers files)
     (while (setq file (pop files))
       (setq entries
-           (append entries
-                   (org-agenda-get-day-entries
-                    file today :timestamp :scheduled :deadline))))
-    (setq entries (delq nil entries))
+           (delq nil
+                 (append entries
+                         (apply 'org-agenda-get-day-entries
+                                file today scope)))))
     ;; Map thru entries and find if we should filter them out
     (mapc
      (lambda(x)
     ;; Map thru entries and find if we should filter them out
     (mapc
      (lambda(x)
@@ -8029,11 +8638,14 @@ belonging to the \"Work\" category."
              (tod (get-text-property 1 'time-of-day x))
              (ok (or (null filter)
                      (and (stringp filter) (string-match filter evt))
              (tod (get-text-property 1 'time-of-day x))
              (ok (or (null filter)
                      (and (stringp filter) (string-match filter evt))
+                     (and (functionp filter) (funcall filter x))
                      (and (listp filter)
                      (and (listp filter)
-                          (or (string-match
-                               (cadr (assoc 'category filter)) cat)
-                              (string-match
-                               (cadr (assoc 'headline filter)) evt))))))
+                          (let ((cat-filter (cadr (assoc 'category filter)))
+                                (evt-filter (cadr (assoc 'headline filter))))
+                            (or (and (stringp cat-filter)
+                                     (string-match cat-filter cat))
+                                (and (stringp evt-filter)
+                                     (string-match evt-filter evt))))))))
         ;; FIXME: Shall we remove text-properties for the appt text?
         ;; (setq evt (set-text-properties 0 (length evt) nil evt))
         (when (and ok tod)
         ;; FIXME: Shall we remove text-properties for the appt text?
         ;; (setq evt (set-text-properties 0 (length evt) nil evt))
         (when (and ok tod)
@@ -8056,8 +8668,14 @@ belonging to the \"Work\" category."
                date)))
     (eq date today)))
 
                date)))
     (eq date today)))
 
-(provide 'org-agenda)
+(defun org-agenda-todo-yesterday (&optional arg)
+  "Like `org-agenda-todo' but the time of change will be 23:59 of yesterday"
+  (interactive "P")
+  (let* ((hour (third (decode-time
+                       (org-current-time))))
+         (org-extend-today-until (1+ hour)))
+    (org-agenda-todo arg)))
 
 
-;; arch-tag: 77f7565d-7c4b-44af-a2df-9f6f7070cff1
+(provide 'org-agenda)
 
 ;;; org-agenda.el ends here
 
 ;;; org-agenda.el ends here