        (modify-syntax-entry ?_ ,old-syntax js2-mode-syntax-table)))))
 
 (put 'js2-with-underscore-as-word-syntax 'lisp-indent-function 0)
+(def-edebug-spec js2-with-underscore-as-word-syntax t)
+
+(defmacro with-buffer (buf form)
+  "Executes FORM in buffer BUF.
+BUF can be a buffer name or a buffer object.
+If the buffer doesn't exist, it's created."
+  `(let ((buffer (gentemp)))
+    (setq buffer
+	  (if (stringp ,buf)
+	      (get-buffer-create ,buf)
+	    ,buf))
+    (save-excursion
+      (set-buffer buffer)
+      ,form)))
+
+(defsubst char-is-uppercase (c)
+  "Return t if C is an uppercase character.
+Handles unicode and latin chars properly."
+  (/= c (downcase c)))
+
+(defsubst char-is-lowercase (c)
+  "Return t if C is an uppercase character.
+Handles unicode and latin chars properly."
+  (/= c (upcase c)))
+
+(put 'with-buffer 'lisp-indent-function 1)
+(def-edebug-spec with-buffer t)
 
 (provide 'js2-util)
 

                expr (js2-make-unary tt 'js2-parse-member-expr t))
        (js2-check-bad-inc-dec tt beg end expr)))

     ((= tt js2-DELPROP)
      (js2-consume-token)
      (js2-make-unary js2-DELPROP 'js2-parse-unary-expr))

     ((= tt js2-ERROR)
      (js2-consume-token)
      (make-js2-error-node))  ; try to continue

     ((and (= tt js2-LT)
           js2-compiler-xml-available)
      ;; XML stream encountered in expression.
      (js2-consume-token)

      ;; Parse the following statement, then remove label from label set.
      (unwind-protect
          (setf stmt (js2-statement-helper))
        (setq js2-label-set (js2-delete-if (lambda (entry)
                                             (string= (car entry) name))
                                           js2-label-set)))
      ;; At this point we've got at least one label in `js2-statement-label'
      ;; and we've parsed stmt, a statement.  stmt may be a labeled statement
      ;; node, in which case we just pass it up tail-recursively.  Otherwise
