
diff --git a/src/report/standard-reports/budget.scm b/src/report/standard-reports/budget.scm
index 33e3323..35948a6 100644
@@ -26,11 +26,14 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define-module (gnucash report standard-reports budget))
+
 (use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
 (use-modules (gnucash gnc-module))
 
 (use-modules (gnucash printf))
 
+(use-modules (srfi srfi-1))
+
 (gnc:module-load "gnucash/report/report-system" 0)
 (gnc:module-load "gnucash/gnome-utils" 0) ;for gnc-build-url
 
@@ -61,20 +64,81 @@
 (define opthelp-rollup-budget (N_ "If parent account does not have its own budget value, use the sum of the child account budget values."))
 (define optname-show-zb-accounts (N_ "Include accounts with zero total balances and budget values"))
 (define opthelp-show-zb-accounts (N_ "Include accounts with zero total (recursive) balances and budget values in this report."))
-(define optname-compress-periods (N_ "Compress prior/later periods"))
-(define opthelp-compress-periods (N_ "Accumulate columns for periods before and after the current period to allow focus on the current period."))
+
+
+(define optname-use-budget-period-range
+  (N_ "Report for range of budget periods"))
+(define opthelp-use-budget-period-range
+  (N_ "Create report for a budget period range instead of the entire budget."))
+
+(define optname-budget-period-start (N_ "Range start"))
+(define opthelp-budget-period-start
+  (N_ "Select a budget period type that starts the reporting range."))
+(define optname-budget-period-start-exact (N_ "Exact start period"))
+(define opthelp-budget-period-start-exact
+  (N_ "Select exact period that starts the reporting range."))
+
+(define optname-budget-period-end (N_ "Range end"))
+(define opthelp-budget-period-end
+  (N_ "Select a budget period type that ends the reporting range."))
+(define optname-budget-period-end-exact (N_ "Exact end period"))
+(define opthelp-budget-period-end-exact
+  (N_ "Select exact period that ends the reporting range."))
+
+(define optname-period-collapse-before (N_ "Include collapsed periods before selected."))
+(define opthelp-period-collapse-before (N_ "Include in report previous periods as single collapsed column (one for all periods before starting)"))
+(define optname-period-collapse-after (N_ "Include collapsed periods after selected."))
+(define opthelp-period-collapse-after (N_ "Include in report further periods as single collapsed column (one for all periods after ending and to the end of budget range)"))
+
 (define optname-bottom-behavior (N_ "Flatten list to depth limit"))
 (define opthelp-bottom-behavior
   (N_ "Displays accounts which exceed the depth limit at the depth limit."))
 
 (define optname-budget (N_ "Budget"))
 
+;;List of common helper functions, that is not bound only to options generation or report evaluation
+(define (get-option-val options pagename optname)
+    (gnc:option-value
+       (gnc:lookup-option options pagename optname)))
+
+(define (set-option-enabled options page opt-name enabled)
+        (gnc-option-db-set-option-selectable-by-name
+          options page opt-name enabled))
+
 ;; options generator
 (define (budget-report-options-generator)
-  (let* ((options (gnc:new-options)) 
-    (add-option 
-     (lambda (new-option)
-       (gnc:register-option options new-option))))
+  (let* ( (options (gnc:new-options))
+          (add-option
+           (lambda (new-option)
+             (gnc:register-option options new-option)))
+          (period-options (list (list->vector
+                                 (list 'first
+                                       (N_ "First")
+                                       (N_ "The first period of the budget")))
+                                (list->vector
+                                 (list 'previous
+                                       (N_ "Previous")
+                                       (N_ "Budget period was before current period, according to report evaluation date")))
+                                (list->vector
+                                 (list 'current
+                                       (N_ "Current")
+                                       (N_ "Current period, according to report evaluation date")))
+                                (list->vector
+                                 (list 'next
+                                       (N_ "Next")
+                                       (N_ "Next period, according to report evaluation date")))
+                                (list->vector
+                                 (list 'last
+                                       (N_ "Last")
+                                       (N_ "Last budget period")))
+                                (list->vector
+                                 (list 'manual
+                                       (N_ "Manual period selection")
+                                       (N_ "Explicitly select period valud with spinner below")))))
+          (ui-use-periods #f)
+          (ui-start-period-type 'current)
+          (ui-end-period-type 'next)
+        )
 
     (gnc:register-option
      options
@@ -102,7 +166,93 @@
       gnc:pagename-general optname-show-full-names
       "e" (N_ "Show full account names (including parent accounts).") #t))
 
+    (add-option
+     (gnc:make-complex-boolean-option
+      gnc:pagename-general
+      optname-use-budget-period-range
+      "f"
+      opthelp-use-budget-period-range
+      #f
+      #f
+      ;; Make period only option widgets
+      ;; selectable only when we are running the report for a budget period
+      ;; range.
+      (lambda (value)
+          (let (
+                (enabler (lambda (target-opt enabled)
+                      (set-option-enabled options gnc:pagename-general target-opt enabled)))
+               )
+            (for-each (lambda (target-opt)
+                      (enabler target-opt value))
+                (list optname-budget-period-start optname-budget-period-end
+                        optname-period-collapse-before optname-period-collapse-after)
+            )
+            (enabler optname-budget-period-start-exact
+                     (and value
+                          (eq? 'manual ui-start-period-type)))
+            (enabler optname-budget-period-end-exact
+                     (and value
+                          (eq? 'manual ui-end-period-type)))
+            (set! ui-use-periods value)
+        ))))
+
+    (add-option
+     (gnc:make-multichoice-callback-option
+      gnc:pagename-general optname-budget-period-start
+      "g1.1" opthelp-budget-period-start 'current
+      period-options
+      #f
+      (lambda (new-val)
+              (set-option-enabled options gnc:pagename-general
+                                  optname-budget-period-start-exact
+                                  (and ui-use-periods (eq? 'manual new-val)))
+              (set! ui-start-period-type new-val)
+              )
+      ))
+
+    (add-option
+     (gnc:make-number-range-option
+      gnc:pagename-general optname-budget-period-start-exact
+      "g1.2" opthelp-budget-period-start-exact
+      ;; FIXME: It would be nice if the max number of budget periods (60) was
+      ;; defined globally somewhere so we could reference it here.  However, it
+      ;; only appears to be defined currently in src/gnome/glade/budget.glade.
+      1 1 60 0 1))
+
+    (add-option
+     (gnc:make-multichoice-callback-option
+      gnc:pagename-general optname-budget-period-end
+      "g2.1" opthelp-budget-period-end 'next
+      period-options
+      #f
+      (lambda (new-val)
+              (set-option-enabled options gnc:pagename-general
+                                  optname-budget-period-end-exact
+                                  (and ui-use-periods (eq? 'manual new-val)))
+              (set! ui-end-period-type new-val)
+              )
+      ))
+
+    (add-option
+     (gnc:make-number-range-option
+      gnc:pagename-general optname-budget-period-end-exact
+      "g2.2" opthelp-budget-period-end-exact
+      ;; FIXME: It would be nice if the max number of budget periods (60) was
+      ;; defined globally somewhere so we could reference it here.  However, it
+      ;; only appears to be defined currently in src/gnome/glade/budget.glade.
+      1 1 60 0 1))
     ;; accounts to work on
+
+    (add-option
+     (gnc:make-simple-boolean-option
+      gnc:pagename-general optname-period-collapse-before
+      "g3" opthelp-period-collapse-before #t))
+
+    (add-option
+     (gnc:make-simple-boolean-option
+      gnc:pagename-general optname-period-collapse-after
+      "g4" opthelp-period-collapse-after #t))
+
     (gnc:options-add-account-selection!
      options gnc:pagename-accounts
      optname-display-depth optname-show-subaccounts
@@ -170,7 +320,6 @@
          (num-rows (gnc:html-acct-table-num-rows acct-table))
          (rownum 0)
          (numcolumns (gnc:html-table-num-columns html-table))
-         (num-periods (gnc-budget-get-num-periods budget))
      ;;(html-table (or html-table (gnc:make-html-table)))
          ;; WARNING: we implicitly depend here on the details of
          ;; gnc:html-table-add-account-balances.  Specifically, we
@@ -179,14 +328,14 @@
          ;; assumption.
          (colnum (quotient numcolumns 2))
 
-     )
+         )
 
-  (define (negative-numeric-p x)
-    (if (gnc-numeric-p x) (gnc-numeric-negative-p x) #f))
-  (define (number-cell-tag x)
-    (if (negative-numeric-p x) "number-cell-neg" "number-cell"))
-  (define (total-number-cell-tag x)
-    (if (negative-numeric-p x) "total-number-cell-neg" "total-number-cell"))
+        (define (negative-numeric-p x)
+                (if (gnc-numeric-p x) (gnc-numeric-negative-p x) #f))
+        (define (number-cell-tag x)
+                (if (negative-numeric-p x) "number-cell-neg" "number-cell"))
+        (define (total-number-cell-tag x)
+                (if (negative-numeric-p x) "total-number-cell-neg" "total-number-cell"))
 
   ;; Calculate the value to use for the budget of an account for a specific set of periods.
   ;; If there is 1 period, use that period's budget value.  Otherwise, sum the budgets for
@@ -199,14 +348,14 @@
   ;;
   ;; Return value:
   ;;   Budget sum
-  (define (gnc:get-account-periodlist-budget-value budget acct periodlist)
-    (cond
-      ((= (length periodlist) 1)(gnc:get-account-period-rolledup-budget-value budget acct (car periodlist)))
-      (else (gnc-numeric-add (gnc:get-account-period-rolledup-budget-value budget acct (car periodlist))
-                             (gnc:get-account-periodlist-budget-value budget acct (cdr periodlist))
-                             GNC-DENOM-AUTO GNC-RND-ROUND))
-    )
-  )
+        (define (gnc:get-account-periodlist-budget-value budget acct periodlist)
+          (cond
+           ((= (length periodlist) 1) (gnc:get-account-period-rolledup-budget-value budget acct (car periodlist)))
+           (else (gnc-numeric-add (gnc:get-account-period-rolledup-budget-value budget acct (car periodlist))
+                                  (gnc:get-account-periodlist-budget-value budget acct (cdr periodlist))
+                                  GNC-DENOM-AUTO GNC-RND-ROUND))
+           )
+          )
 
   ;; Calculate the value to use for the actual of an account for a specific set of periods.
   ;; This is the sum of the actuals for each of the periods.
@@ -218,17 +367,17 @@
   ;;
   ;; Return value:
   ;;   Budget sum
-  (define (gnc:get-account-periodlist-actual-value budget acct periodlist)
-    (cond
-      ((= (length periodlist) 1)
-        (gnc-budget-get-account-period-actual-value budget acct (car periodlist)))
-      (else
-        (gnc-numeric-add
-          (gnc-budget-get-account-period-actual-value budget acct (car periodlist))
-          (gnc:get-account-periodlist-actual-value budget acct (cdr periodlist))
-          GNC-DENOM-AUTO GNC-RND-ROUND))
-    )
-  )
+        (define (gnc:get-account-periodlist-actual-value budget acct periodlist)
+          (cond
+           ((= (length periodlist) 1)
+            (gnc-budget-get-account-period-actual-value budget acct (car periodlist)))
+           (else
+            (gnc-numeric-add
+             (gnc-budget-get-account-period-actual-value budget acct (car periodlist))
+             (gnc:get-account-periodlist-actual-value budget acct (cdr periodlist))
+             GNC-DENOM-AUTO GNC-RND-ROUND))
+           )
+          )
 
   ;; Adds a line to tbe budget report.
   ;;
@@ -240,19 +389,17 @@
   ;;   acct - account being displayed
   ;;   rollup-budget? - rollup budget values for account children if account budget not set
   ;;   exchange-fn - exchange function (not used)
-  (define (gnc:html-table-add-budget-line!
-           html-table rownum colnum
-           budget acct rollup-budget? column-list exchange-fn)
-    (let* (
-           (period 0)
-           (current-col (+ colnum 1))
-           (bgt-total (gnc-numeric-zero))
-           (bgt-total-unset? #t)
-           (act-total (gnc-numeric-zero))
-           (comm (xaccAccountGetCommodity acct))
-           (reverse-balance? (gnc-reverse-balance acct))
-		   (income-acct? (eq? (xaccAccountGetType acct) ACCT-TYPE-INCOME))
-           )
+        (define (gnc:html-table-add-budget-line!
+                 html-table rownum colnum budget acct rollup-budget? column-list exchange-fn)
+          (let* (
+                 (current-col (+ colnum 1))
+                 (bgt-total (gnc-numeric-zero))
+                 (bgt-total-unset? #t)
+                 (act-total (gnc-numeric-zero))
+                 (comm (xaccAccountGetCommodity acct))
+                 (reverse-balance? (gnc-reverse-balance acct))
+                 (income-acct? (eq? (xaccAccountGetType acct) ACCT-TYPE-INCOME))
+                 )
 
       ;; Displays a set of budget column values
       ;;
@@ -263,47 +410,46 @@
       ;;   bgt-numeric-val - budget value, or #f if column not to be shown
       ;;   act-numeric-val - actual value, or #f if column not to be shown
       ;;   dif-numeric val - difference value, or #f if column not to be shown
-      (define (gnc:html-table-display-budget-columns!
-               html-table rownum total?
-               bgt-numeric-val act-numeric-val dif-numeric-val)
-           (let* ((bgt-val #f)(act-val #f)(dif-val #f)
-		          (style-tag (if total? "total-number-cell" "number-cell"))
-				  (style-tag-neg (string-append style-tag "-neg"))
-		         )
-             (if show-budget?
-               (begin
-                 (set! bgt-val (if (gnc-numeric-zero-p bgt-numeric-val) "."
-                           (gnc:make-gnc-monetary comm bgt-numeric-val)))
-                 (gnc:html-table-set-cell/tag!
-                  html-table rownum current-col style-tag bgt-val)
-                 (set! current-col (+ current-col 1))
-               )
-             )
-             (if show-actual?
-               (begin
-                 (set! act-val (gnc:make-gnc-monetary comm act-numeric-val))
-                 (gnc:html-table-set-cell/tag!
-                  html-table rownum current-col
-                  (if (gnc-numeric-negative-p act-numeric-val) style-tag-neg style-tag)
-                  act-val)
-                 (set! current-col (+ current-col 1))
-               )
-             )
-             (if show-diff?
-               (begin
-                 (set! dif-val
-                   (if (and (gnc-numeric-zero-p bgt-numeric-val) (gnc-numeric-zero-p act-numeric-val))
-                     "."
-                     (gnc:make-gnc-monetary comm dif-numeric-val)))
-                 (gnc:html-table-set-cell/tag!
-                  html-table rownum current-col
-                  (if (gnc-numeric-negative-p dif-numeric-val) style-tag-neg style-tag)
-                  dif-val)
-                 (set! current-col (+ current-col 1))
-               )
-             )
-           )
-        )
+                (define (gnc:html-table-display-budget-columns!
+                         html-table rownum total? bgt-numeric-val act-numeric-val dif-numeric-val)
+                  (let* ((bgt-val #f)(act-val #f)(dif-val #f)
+                         (style-tag (if total? "total-number-cell" "number-cell"))
+                         (style-tag-neg (string-append style-tag "-neg"))
+                         )
+                     (if show-budget?
+                       (begin
+                         (set! bgt-val (if (gnc-numeric-zero-p bgt-numeric-val) "."
+                                   (gnc:make-gnc-monetary comm bgt-numeric-val)))
+                         (gnc:html-table-set-cell/tag!
+                          html-table rownum current-col style-tag bgt-val)
+                         (set! current-col (+ current-col 1))
+                       )
+                     )
+                     (if show-actual?
+                       (begin
+                         (set! act-val (gnc:make-gnc-monetary comm act-numeric-val))
+                         (gnc:html-table-set-cell/tag!
+                          html-table rownum current-col
+                          (if (gnc-numeric-negative-p act-numeric-val) style-tag-neg style-tag)
+                          act-val)
+                         (set! current-col (+ current-col 1))
+                       )
+                     )
+                     (if show-diff?
+                       (begin
+                         (set! dif-val
+                           (if (and (gnc-numeric-zero-p bgt-numeric-val) (gnc-numeric-zero-p act-numeric-val))
+                             "."
+                             (gnc:make-gnc-monetary comm dif-numeric-val)))
+                         (gnc:html-table-set-cell/tag!
+                          html-table rownum current-col
+                          (if (gnc-numeric-negative-p dif-numeric-val) style-tag-neg style-tag)
+                          dif-val)
+                         (set! current-col (+ current-col 1))
+                       )
+                     )
+                  )
+                );;end of define gnc:html-table-display-budget-columns
 
       ;; Adds a set of column values to the budget report for a specific list
       ;; of periods.
@@ -314,70 +460,67 @@
       ;;   budget - budget to use
       ;;   acct - account being displayed
       ;;   period-list - list of periods to use
-      (define (gnc:html-table-add-budget-line-columns!
-                html-table rownum budget acct period-list)
-        (let* (
-          ;; budgeted amount
-          (bgt-numeric-val (gnc:get-account-periodlist-budget-value budget acct period-list))
-
-          ;; actual amount
-          (act-numeric-abs (gnc:get-account-periodlist-actual-value budget acct period-list))
-          (act-numeric-val
-            (if reverse-balance?
-              (gnc-numeric-neg act-numeric-abs)
-              act-numeric-abs))
-
-          ;; difference (budget to actual)
-          (dif-numeric-val
-            (gnc-numeric-sub
-              bgt-numeric-val act-numeric-val
-              GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER)))
-          )
-
-          (if (not (gnc-numeric-zero-p bgt-numeric-val))
-            (begin
-              (set! bgt-total (gnc-numeric-add bgt-total bgt-numeric-val GNC-DENOM-AUTO GNC-RND-ROUND))
-              (set! bgt-total-unset? #f))
+                (define (gnc:html-table-add-budget-line-columns!
+                         html-table rownum budget acct period-list)
+                  (let* (
+                      ;; budgeted amount
+                      (bgt-numeric-val (gnc:get-account-periodlist-budget-value budget acct period-list))
+
+                      ;; actual amount
+                      (act-numeric-abs (gnc:get-account-periodlist-actual-value budget acct period-list))
+                      (act-numeric-val
+                        (if reverse-balance?
+                          (gnc-numeric-neg act-numeric-abs)
+                          act-numeric-abs))
+
+                      ;; difference (budget to actual)
+                      (dif-numeric-val
+                        (gnc-numeric-sub
+                          bgt-numeric-val act-numeric-val
+                          GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER)))
+                    )
+
+                    (if (not (gnc-numeric-zero-p bgt-numeric-val))
+                      (begin
+                        (set! bgt-total (gnc-numeric-add bgt-total bgt-numeric-val GNC-DENOM-AUTO GNC-RND-ROUND))
+                        (set! bgt-total-unset? #f))
+                    )
+                    (set! act-total (gnc-numeric-add act-total act-numeric-val GNC-DENOM-AUTO GNC-RND-ROUND))
+                    (if income-acct?
+                      (set! dif-numeric-val
+                        (gnc-numeric-sub
+                          act-numeric-val bgt-numeric-val
+                          GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER))))
+                    (gnc:html-table-display-budget-columns!
+                             html-table rownum #f
+                             bgt-numeric-val act-numeric-val dif-numeric-val)
+                  )
+                );;end of define gnc:html-table-add-budget-line-columns
+
+                (while (not (null? column-list))
+                 (let* ((col-info (car column-list)))
+                       (cond
+                        ((equal? col-info 'total)
+                         (gnc:html-table-display-budget-columns!
+                              html-table rownum #t bgt-total act-total
+                              (if income-acct?
+                                 (gnc-numeric-sub
+                                    act-total bgt-total
+                                    GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER))
+                                 (gnc-numeric-sub
+                                    bgt-total act-total
+                                    GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER)))
+                          ))
+                        ((list? col-info)
+                         (gnc:html-table-add-budget-line-columns! html-table rownum budget acct col-info))
+                        (else
+                         (gnc:html-table-add-budget-line-columns! html-table rownum budget acct (list col-info)))
+                        )
+                       (set! column-list (cdr column-list))
+                 )
+                )
           )
-          (set! act-total (gnc-numeric-add act-total act-numeric-val GNC-DENOM-AUTO GNC-RND-ROUND))
-		  (if income-acct?
-            (set! dif-numeric-val
-              (gnc-numeric-sub
-                act-numeric-val bgt-numeric-val
-                GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER))))
-          (gnc:html-table-display-budget-columns!
-                   html-table rownum #f
-                   bgt-numeric-val act-numeric-val dif-numeric-val)
-        )
-      )
-
-      (while (not (null? column-list))
-        (let* ((col-info (car column-list)))
-          (cond
-            ((equal? col-info 'total)
-               (gnc:html-table-display-budget-columns!
-                   html-table rownum #t
-                   bgt-total act-total
-				   (if income-acct?
-                     (gnc-numeric-sub
-                        act-total bgt-total
-                        GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER))
-                     (gnc-numeric-sub
-                        bgt-total act-total
-                        GNC-DENOM-AUTO (+ GNC-DENOM-LCD GNC-RND-NEVER)))
-                ))
-            ((list? col-info)
-                (gnc:html-table-add-budget-line-columns!
-                   html-table rownum budget acct col-info))
-            (else
-                (gnc:html-table-add-budget-line-columns!
-                   html-table rownum budget acct (list col-info)))
-            )
-          (set! column-list (cdr column-list))
-        )
-     )
-    )
-  )
+        );; end of define gnc:html-table-add-budget-line
 
   ;; Adds header rows to the budget report.  The columns are specified by the
   ;; column-list parameter.
@@ -387,135 +530,239 @@
   ;;   colnum - starting column number
   ;;   budget - budget to use
   ;;   column-list - column info list
-  (define (gnc:html-table-add-budget-headers!
-           html-table colnum budget column-list)
-    (let* (
-           (period 0)
-           (current-col (+ colnum 1))
-           (col-list column-list)
-	   (col-span 0)
-           )
-
-	(if show-budget? (set! col-span (+ col-span 1)))
-	(if show-actual? (set! col-span (+ col-span 1)))
-	(if show-diff? (set! col-span (+ col-span 1)))
-	(if (eqv? col-span 0) (set! col-span 1))
-
-      ;; prepend 2 empty rows
-      (gnc:html-table-prepend-row! html-table '())
-      (gnc:html-table-prepend-row! html-table '())
-
-      (while (not (= (length col-list) 0))
-        (let* (
-                (col-info (car col-list))
-                (tc #f)
-              )
-          (cond
-            ((equal? col-info 'total)
-               (gnc:html-table-set-cell!
-                html-table 0 current-col "Total")
-            )
-            ((list? col-info)
-               (gnc:html-table-set-cell!
-                html-table 0 current-col "Multiple periods")
-            )
-            (else
-             (let* ((date (gnc-budget-get-period-start-date budget col-info)))
-               (gnc:html-table-set-cell!
-                html-table 0 current-col (gnc-print-date date))
-               )
-            )
-          )
-          (set! tc (gnc:html-table-get-cell html-table 0 current-col))
-          (gnc:html-table-cell-set-colspan! tc col-span)
-          (gnc:html-table-cell-set-tag! tc "centered-label-cell")
-          (set! current-col (+ current-col 1))
-          (set! col-list (cdr col-list))
-        )
-      )
-
-      ;; make the column headers
-      (set! col-list column-list)
-      (set! current-col (+ colnum 1))
-      (while (not (= (length column-list) 0))
-        (let* ((col-info (car column-list)))
-          (if show-budget?
-            (begin
-              (gnc:html-table-set-cell/tag!
-               html-table 1 current-col "centered-label-cell"
-               (_ "Bgt")) ;; Translators: Abbreviation for "Budget"
-              (set! current-col (+ current-col 1))
-            )
-          )
-          (if show-actual?
-            (begin 
-              (gnc:html-table-set-cell/tag!
-               html-table 1 current-col "centered-label-cell"
-               (_ "Act")) ;; Translators: Abbreviation for "Actual"
-              (set! current-col (+ current-col 1))
-            )
-          )
-          (if show-diff?
-            (begin 
-              (gnc:html-table-set-cell/tag!
-               html-table 1 current-col "centered-label-cell"
-               (_ "Diff")) ;; Translators: Abbrevation for "Difference"
-              (set! current-col (+ current-col 1))
+        (define (gnc:html-table-add-budget-headers!
+                 html-table colnum budget column-list)
+                (let* (
+                       (current-col (+ colnum 1))
+                       (col-list column-list)
+                       (col-span 0)
+                      )
+
+                      (if show-budget? (set! col-span (+ col-span 1)))
+                      (if show-actual? (set! col-span (+ col-span 1)))
+                      (if show-diff? (set! col-span (+ col-span 1)))
+                      (if (eqv? col-span 0) (set! col-span 1))
+
+                      ;; prepend 2 empty rows
+                      (gnc:html-table-prepend-row! html-table '())
+                      (gnc:html-table-prepend-row! html-table '())
+
+                      (while (not (= (length col-list) 0))
+                             (let* (
+                                    (col-info (car col-list))
+                                    (tc #f)
+                                    (period-to-date-string (lambda (p) (gnc-print-date (gnc-budget-get-period-start-date budget p))))
+                                   )
+                                   (cond
+                                    ((equal? col-info 'total)
+                                     (gnc:html-table-set-cell! html-table 0 current-col (_ "Total"))
+                                    )
+                                    ((list? col-info)
+                                     (gnc:html-table-set-cell!
+                                      html-table 0 current-col (string-append
+                                                                    (period-to-date-string (car col-info))
+                                                                    " &ndash; "
+                                                                    (period-to-date-string (car (reverse col-info)))
+                                                               )
+                                     )
+                                    )
+                                    (else
+                                     (gnc:html-table-set-cell!
+                                      html-table 0 current-col (period-to-date-string col-info)
+                                     )
+                                    )
+                                   )
+                                   (set! tc (gnc:html-table-get-cell html-table 0 current-col))
+                                   (gnc:html-table-cell-set-colspan! tc col-span)
+                                   (gnc:html-table-cell-set-tag! tc "centered-label-cell")
+                                   (set! current-col (+ current-col 1))
+                                   (set! col-list (cdr col-list))
+                              )
+                      )
+
+                      ;; make the column headers
+                      (set! col-list column-list)
+                      (set! current-col (+ colnum 1))
+                      (while (not (= (length column-list) 0))
+                          (let* ((col-info (car column-list)))
+                                (if show-budget?
+                                  (begin
+                                    (gnc:html-table-set-cell/tag!
+                                     html-table 1 current-col "centered-label-cell"
+                                     (_ "Bgt")) ;; Translators: Abbreviation for "Budget"
+                                    (set! current-col (+ current-col 1))
+                                  )
+                                )
+                                (if show-actual?
+                                  (begin
+                                    (gnc:html-table-set-cell/tag!
+                                     html-table 1 current-col "centered-label-cell"
+                                     (_ "Act")) ;; Translators: Abbreviation for "Actual"
+                                    (set! current-col (+ current-col 1))
+                                  )
+                                )
+                                (if show-diff?
+                                  (begin
+                                    (gnc:html-table-set-cell/tag!
+                                     html-table 1 current-col "centered-label-cell"
+                                     (_ "Diff")) ;; Translators: Abbrevation for "Difference"
+                                    (set! current-col (+ current-col 1))
+                                  )
+                                )
+                                (set! column-list (cdr column-list))
+                        )
+                      )
+                )
+        );;end of define gnc:html-table-add-budget-headers
+
+        ;; Determines the budget period relative to current period. Budget period is current if
+        ;; it start time <= current time and end time >= current time
+        ;; When period is found it's passed to adjuster that is responsible for final calculation of period.
+        ;;
+        ;; If budget in future then first period of bundget is returned, if it in past, then the last period is returned
+        ;; if adjuster produced period number that is less then first period or greater then last period, the same rules apply.
+        ;;
+        ;; Parameters:
+        ;;   budget - budget to use
+        ;;   adjuster - function that is used for calculation of period relative to current
+        (define (find-period-relative-to-current budget adjuster)
+            (let* ((now (current-time))
+                  (total-periods (gnc-budget-get-num-periods budget) )
+                  (last-period (- total-periods 1))
+                  (period-start (lambda (x) (car (gnc-budget-get-period-start-date budget x))))
+                  (period-end (lambda (x) (car (gnc-budget-get-period-end-date budget x))))
+                 )
+                (cond ((< now (period-start 0)) 1)
+                      ((> now (period-end last-period)) total-periods)
+                      ( else (let ((found-period
+                                        (find (lambda (period)
+                                                      (and (>= now (period-start period))
+                                                           (<= now (period-end period))))
+                                              (iota total-periods))
+                                  ))
+                                  (gnc:debug "current period =" found-period)
+                                  (if found-period
+                                      (let ((adjusted (adjuster found-period)))
+                                            (cond ((< adjusted 0) 0) ((> adjusted last-period) last-period) (else adjusted))
+                                      )
+                                      #f)
+                     ))
+                )
             )
-          )
-          (set! column-list (cdr column-list))
+        );;end of find-period-relative-to-current
+        ;; Maps type of user selected period to concrete period number, if user not selected to use range false is returned
+        (define (calc-user-period budget
+                  use-ranges? period-type period-exact-val )
+                (if (not use-ranges?)
+                    #f
+                    (cond
+                        ((eq? 'first period-type) 0)
+                        ((eq? 'last period-type) (- (gnc-budget-get-num-periods budget) 1))
+                        ((eq? 'manual period-type) (- period-exact-val 1))
+                        ((eq? 'previous period-type)
+                            (find-period-relative-to-current budget (lambda (period) (- period 1))))
+                        ((eq? 'current period-type)
+                            (find-period-relative-to-current budget (lambda (period) period )))
+                        ((eq? 'next period-type)
+                            (find-period-relative-to-current budget (lambda (period) ( + period 1))))
+                    )
+                )
+        );;end of calc-user-period budget
+        ;; Performs calculation of periods list. If list element is a list itself, it means that
+        ;; elements of this sublist should be presented as summed value.
+        ;; If user required a total column calculation a quoted total val appended to the end
+        ;; For example if function produced list ( (0 1 2 3 4) 5 6 7 (8 9) 'total) then budget report will
+        ;; have 6 columns:
+        ;; -- first column is a sum of values for periods 0..4
+        ;; -- second .. forth columns is a values for periods 5,6,7
+        ;; -- fifth is a sum of value for periods 8, 9
+        ;; -- sixth a column with total of all columns
+        ;;
+        ;; Total is calculated only for selected periods. So if the list resulted in (3 4 'total), total column
+        ;; will contain the sum of values for periods 3,4
+        (define (calc-periods
+                 budget user-start user-end collapse-before? collapse-after? show-total?)
+
+
+                (define (range start end)
+                  (define (int-range current end step lst)
+                        (if (>=  current end)
+                            lst
+                            (int-range (+ current step) end step (cons current lst))))
+                  (reverse (int-range (if (number? start) start 0) end 1 '()))
+                )
+
+                (let* ((num-periods (gnc-budget-get-num-periods budget))
+                       (range-start (if user-start user-start 0))
+                       (range-end (if user-end (+ 1 user-end) num-periods))
+                       (fold-before-start 0)
+                       (fold-before-end (if collapse-before? range-start 0))
+                       (fold-after-start (if collapse-after? range-end num-periods))
+                       (fold-after-end num-periods)
+                       )
+                      (map (lambda (x) (if (and (list? x) (= 1 (length x))) (car x) x))
+                           (filter (lambda (x) (not (null? x)))
+                                    (append (list (range fold-before-start fold-before-end))
+                                            (range range-start range-end)
+                                            (list (range fold-after-start fold-after-end))
+                                            (if show-total? (list 'total) '())
+                        )))
+                )
+        );;end of define calc-periods
+
+       ;; end of defines
+
+
+        (let* ((rownum 0)
+               (use-ranges? (get-val params 'use-ranges))
+               (column-info-list (calc-periods budget
+                                               (calc-user-period budget
+                                                                  use-ranges?
+                                                                  (get-val params 'user-start-period)
+                                                                  (get-val params 'user-start-period-exact)
+                                               )
+                                               (calc-user-period budget
+                                                                  use-ranges?
+                                                                  (get-val params 'user-end-period)
+                                                                  (get-val params 'user-end-period-exact)
+                                               )
+                                               (get-val params 'collapse-before)
+                                               (get-val params 'collapse-after)
+                                               show-totalcol?
+                                 ))
+               ;;(html-table (or html-table (gnc:make-html-table)))
+               ;; WARNING: we implicitly depend here on the details of
+               ;; gnc:html-table-add-account-balances.  Specifically, we
+               ;; assume that it makes twice as many columns as it uses for
+               ;; account labels.  For now, that seems to be a valid
+               ;; assumption.
+              )
+              ;;debug output for control of period list calculation
+              (gnc:debug "use-ranges? =" use-ranges?)
+              (gnc:debug "user-start-period =" (get-val params 'user-start-period))
+              (gnc:debug "user-start-period-exact =" (get-val params 'user-start-period-exact))
+              (gnc:debug "user-end-period =" (get-val params 'user-end-period))
+              (gnc:debug "user-end-period-exact =" (get-val params 'user-end-period-exact))
+              (gnc:debug "column-info-list=" column-info-list)
+
+              ;; call gnc:html-table-add-budget-line! for each account
+              (while (< rownum num-rows)
+                     (let* (
+                            (env (append (gnc:html-acct-table-get-row-env acct-table rownum) params))
+                            (acct (get-val env 'account))
+                            (exchange-fn (get-val env 'exchange-fn))
+                           )
+                           (gnc:html-table-add-budget-line!
+                            html-table rownum colnum budget acct rollup-budget? column-info-list exchange-fn)
+                           (set! rownum (+ rownum 1)) ;; increment rownum
+                     )
+              ) ;; end of while
+
+              ;; column headers
+              (gnc:html-table-add-budget-headers! html-table colnum budget column-info-list)
         )
-      )
-    )
-  )
-
-  (let* ((num-rows (gnc:html-acct-table-num-rows acct-table))
-         (rownum 0)
-;;		 (column-info-list '((0 1 2 3 4 5) 6 7 8 (9 10 11)))
-		 (column-info-list '())
-         (numcolumns (gnc:html-table-num-columns html-table))
-	 ;;(html-table (or html-table (gnc:make-html-table)))
-         ;; WARNING: we implicitly depend here on the details of
-         ;; gnc:html-table-add-account-balances.  Specifically, we
-         ;; assume that it makes twice as many columns as it uses for
-          ;; account labels.  For now, that seems to be a valid
-         ;; assumption.
-         (colnum (quotient numcolumns 2))
-		 (period 0)
-
-	 )
-
-	(while (< period num-periods)
-	  (set! column-info-list (append column-info-list (list period)))
-	  (set! period (+ 1 period)))
-
-	(if show-totalcol?
-	  (set! column-info-list (append column-info-list (list 'total))))
-
-(gnc:debug "column-info-list=" column-info-list)
-
-    ;; call gnc:html-table-add-budget-line! for each account
-    (while (< rownum num-rows)
-       (let*
-         (
-           (env
-             (append (gnc:html-acct-table-get-row-env acct-table rownum) params))
-           (acct (get-val env 'account))
-           (exchange-fn (get-val env 'exchange-fn))
-         )
-         (gnc:html-table-add-budget-line!
-            html-table rownum colnum
-            budget acct rollup-budget? column-info-list exchange-fn)
-         (set! rownum (+ rownum 1)) ;; increment rownum
-       )
-    ) ;; end of while
-
-    ;; column headers
-    (gnc:html-table-add-budget-headers! html-table colnum budget column-info-list)
-    )
-
   )
-) ;; end of define
+) ;; end of define gnc:html-table-add-budget-values
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; budget-renderer
@@ -524,9 +771,9 @@
 
 (define (budget-renderer report-obj)
   (define (get-option pagename optname)
-    (gnc:option-value
-     (gnc:lookup-option
-      (gnc:report-options report-obj) pagename optname)))
+    (get-option-val (gnc:report-options report-obj) pagename optname))
+;;     (gnc:lookup-option
+;;      (gnc:report-options report-obj) pagename optname)))
 
   (gnc:report-starting reportname)
 
@@ -542,8 +789,13 @@
          (bottom-behavior (get-option gnc:pagename-accounts optname-bottom-behavior))
          (rollup-budget? (get-option gnc:pagename-display
                                      optname-rollup-budget))
-	 (show-zb-accts? (get-option gnc:pagename-display
+         (show-zb-accts? (get-option gnc:pagename-display
                                      optname-show-zb-accounts))
+         (use-ranges? (get-option gnc:pagename-general optname-use-budget-period-range))
+         (include-collapse-before? (if use-ranges?
+                                       (get-option gnc:pagename-general optname-period-collapse-before) #f))
+         (include-collapse-after? (if use-ranges?
+                                       (get-option gnc:pagename-general optname-period-collapse-after) #f))
          (row-num 0) ;; ???
          (work-done 0)
          (work-to-do 0)
@@ -613,8 +865,7 @@
         ;; No accounts selected.
         (gnc:html-document-add-object! 
          doc 
-         (gnc:html-make-no-account-warning 
-      reportname (gnc:report-id report-obj))))
+         (gnc:html-make-no-account-warning reportname (gnc:report-id report-obj))))
       ((not budget-valid?)
         ;; No budget selected.
         (gnc:html-document-add-object!
@@ -623,35 +874,41 @@
         (let* ((tree-depth (if (equal? display-depth 'all)
                                (accounts-get-children-depth accounts)
                                display-depth))
+               (to-period-val (lambda (v) (inexact->exact (truncate (get-option gnc:pagename-general v)))))
                ;;(account-disp-list '())
 
-               (env (list  
-			   (list 'start-date (gnc:budget-get-start-date budget))
-			   (list 'end-date (gnc:budget-get-end-date budget))
-                           (list 'display-tree-depth tree-depth)
-                           (list 'depth-limit-behavior
-                                (if bottom-behavior 'flatten 'summarize))
-			   (list 'zero-balance-mode 
-				(if show-zb-accts? 'show-leaf-acct 'omit-leaf-acct))
-			   (list 'report-budget budget)
+               (env (list
+                     (list 'start-date (gnc:budget-get-start-date budget))
+                     (list 'end-date (gnc:budget-get-end-date budget))
+                     (list 'display-tree-depth tree-depth)
+                     (list 'depth-limit-behavior
+                           (if bottom-behavior 'flatten 'summarize))
+                     (list 'zero-balance-mode
+                           (if show-zb-accts? 'show-leaf-acct 'omit-leaf-acct))
+                     (list 'report-budget budget)
                           ))
                (acct-table #f)
                (html-table (gnc:make-html-table))
                (params '())
-               (paramsBudget
-                (list
-                 (list 'show-actual
-                       (get-option gnc:pagename-display optname-show-actual))
-                 (list 'show-budget
-                       (get-option gnc:pagename-display optname-show-budget))
-                 (list 'show-difference
-                       (get-option gnc:pagename-display optname-show-difference))
-                 (list 'show-totalcol
-                       (get-option gnc:pagename-display optname-show-totalcol))
-                 (list 'rollup-budget
-                       (get-option gnc:pagename-display optname-rollup-budget))
-                )
-               )
+               (paramsBudget (list
+                              (list 'show-actual
+                                    (get-option gnc:pagename-display optname-show-actual))
+                              (list 'show-budget
+                                    (get-option gnc:pagename-display optname-show-budget))
+                              (list 'show-difference
+                                    (get-option gnc:pagename-display optname-show-difference))
+                              (list 'show-totalcol
+                                    (get-option gnc:pagename-display optname-show-totalcol))
+                              (list 'rollup-budget
+                                    (get-option gnc:pagename-display optname-rollup-budget))
+                              (list 'use-ranges use-ranges?)
+                              (list 'collapse-before include-collapse-before?)
+                              (list 'collapse-after include-collapse-after?)
+                              (list 'user-start-period (get-option gnc:pagename-general optname-budget-period-start))
+                              (list 'user-end-period (get-option gnc:pagename-general optname-budget-period-end))
+                              (list 'user-start-period-exact (to-period-val optname-budget-period-start-exact))
+                              (list 'user-end-period-exact (to-period-val optname-budget-period-end-exact))
+                              ))
                (report-name (get-option gnc:pagename-general
                                         gnc:optname-reportname))
                )
@@ -688,10 +945,9 @@
     doc))
 
 (gnc:define-report
- 'version 1
+ 'version 1.1
  'name reportname
  'report-guid "810ed4b25ef0486ea43bbd3dddb32b11"
  'menu-path (list gnc:menuname-budget)
  'options-generator budget-report-options-generator
  'renderer budget-renderer)
-

